Arduino Powered 3-zone termostat (7 / 10 steg)
Steg 7: Lägg till i LCD
Så med vår klocka och våra temperaturgivare arbeta, låt oss få några produktionen flyttar till LCD-controller.
Den första delen av detta är att bestämma vad jag vill säga. Utrymmet är något begränsat eftersom jag har bara totalt 32 tecken över 2 rader, så den första frågan jag fick besvara var hur visar jag allt jag behöver för att Visa inom de 32 tecken.
Här är min sista LCD-avläsning:
Zone1: ()
Läge:
Zon†2: ()
Ugnen:
3: ()
Öppet: < 1,2,3 / ingen >
Om T1 är temperaturen för zon 1, TT mål temperatur, läget är nuvarande läge den körs (AWAKE, AWAY, hem, sova, omställning eller håll.
Öppna avser som zoner är nu öppen och mottagande värme (om ugnen är igång).
Detta var faktiskt ganska enkelt. Jag har några räkna att göra så mycket som en anpassad symbol är berörda, men det är ganska långt ner på min prioriteringslista.
< tt >< tt >< tt >
/*
Detta är det program som jag kommer att använda till kontroll den
ugnen. Konceptet är detta: Jag har 3 zoner jag kommer att följa.
Varje zon kommer att ha minst en zon spjäll som kommer att
kontrolleras av arduino ansökan.
Varje zon har en enda termometer som kommer att rapportera
tillbaka till registeransvarige. Beroende på den termometer behandlingen och
termostatinställningen, dämparna kommer att öppna eller stänga och den
centrala ugnen kommer att vara påslagen. En gång en godtagbar temperatur
har uppnåtts i alla zoner, ugnen stängs av.
Utöver de allmänna uppvärmning cykler, kommer systemet att
programmerbar. Vid denna tid, dock kommer programcykeln att hanteras här, inte via termostaten.
VIKTIGT TESTFALL: (som ska läggas till som jag tänker på dem / kommit över dem.
* Måste se till att ugnen är alltid off om alla 3 spjäll är stängda.
* stötdämpare ska vara öppen om de inte uttryckligen behöver stängas.
*/
#include < LiquidCrystal.h > //This är ett bibliotek som behövs för LCD-skärmen
#include < OneWire.h > //This är ett bibliotek som behövs för avläsningarna som termometer
#include < DallasTemperature.h > //This är en temperatur bibliotek
#include < Wire.h >
#include "RTClib.h"
Anslutningar:
rs (LCD stift 4) till Arduino stift 12
RW (LCD pin 5) till Arduino stift 11
Aktivera (LCD stift 6) till Arduino stift 10
LCD stift 15 till Arduino stift 13
LCD stift d4, d5, d6 och d7 till Arduino stift 5, 4, 3, 2
LiquidCrystal lcd (12, 11, 10, 5, 4, 3, 2);
byte deg [8] = {
B01000,
B10100,
B01000,
B00111,
B00100,
B00110,
B00100,
B00100
};
CONST int bakgrundsbelysning = 13. kontroller bakgrundsbelysning
#define THERM_BUS 6 / / alla temperaturavläsningar kommer via detta enda stift.
OneWire oneWire(THERM_BUS);
DallasTemperature sensorer (& oneWire);
DeviceAddress zone1Therm = {
0x28, 0x48, 0x39, 0x11, 0x04, 0x00, 0x00, 0x94};
DeviceAddress zone2Therm = {
0x28, 0xF2, 0x1F, 0x11, 0x04, 0x00, 0x00, 0x38};
DeviceAddress zone3Therm = {
0x28, 0xBA, 0xF3, 0x10, 0x04, 0x00, 0x00, 0x98};
RTC_DS1307 RTC;
BÖRJA PROGRAMMERA
Tiderna är 6 AM, 8 AM, 3: 00 och 21: 00
int * PROGRAMMED_VALUES [7].
int SUNDAY_VALUES [4] = {
67 67, 67, 60};
int MONDAY_VALUES [4] = {
67 67, 67, 60};
int TUESDAY_VALUES [4] = {
67 67, 67, 60};
int WEDNESDAY_VALUES [4] = {
67 67, 67, 60};
int THURSDAY_VALUES [4] = {
67 67, 67, 60};
int FRIDAY_VALUES [4] = {
67 67, 90, 75};
int SATURDAY_VALUES [4] = {
67 67, 67, 60};
SLUTET PROGRAMMERING
flyta zone1Temp = 0;
flyta zone2Temp = 0;
flyta zone3Temp = 0;
booleska z1Check = 0;
booleska z2Check = 0;
booleska z3Check = 0;
booleska isOverrideHeld = false;
booleska isOverridden = false;
booleska furnaceState = false; med furnaceState, true false betyder att det är för närvarande avstängd, innebär dess närvarande.
int overrideValue = 0;
CONST int furnacePin = 1;
int zoneCounter = 0;
void setup() {
Serial.BEGIN(57600); Detta ansluter arduino till datorn
TEMPERATUR SENSOR SETUP
sensors.BEGIN();
sensors.setResolution (zone1Therm, 10);
lcd.createChar (0, deg);
RTC SETUP.
Wire.BEGIN();
RTC.begin();
IF (!. RTC.isrunning()) {
log ("Fel", "RTC körs inte!");
RTC.adjust (DateTime (__DATE__, __TIME__)); DETTA MÅSTE BARA VARA OKOMMENTERADE OM DU STÄLLER IN DIN RTC FÖR FÖRSTA GÅNGEN! NÄR DEN ÄR INSTÄLLD, MÅSTE DETTA INAKTIVERAS!
}
SETUP UTGÅNGAR
pinMode (furnacePin, produktionen);
pinMode (bakgrundsbelysning, OUTPUT);
digitalWrite (bakgrundsbelysning, hög);
STÄLLA IN VECKOPROGRAMMET
PROGRAMMED_VALUES [0] = SUNDAY_VALUES;
PROGRAMMED_VALUES [1] = MONDAY_VALUES;
PROGRAMMED_VALUES [2] = TUESDAY_VALUES;
PROGRAMMED_VALUES [3] = WEDNESDAY_VALUES;
PROGRAMMED_VALUES [4] = THURSDAY_VALUES;
PROGRAMMED_VALUES [5] = FRIDAY_VALUES;
PROGRAMMED_VALUES [6] = SATURDAY_VALUES;
}
Detta går en kontinuerlig slinga
void loop() {
Delay(3000); FÖRDRÖJNING FÖR NÄRVARANDE INSTÄLLT PÅ 10 SEKUNDER. KOMMER ATT JUSTERA EFTER BEHOV
DATUM/TID LOGIK
log ("TIME", "Loop initieras på" + getDateAndTime());
TEMPERATUREN LOGIK
sensors.requestTemperatures();
zone1Temp = getTemperature(zone1Therm);
zone2Temp = getTemperature(zone2Therm);
zone3Temp = getTemperature(zone3Therm);
logTemperatureData();
getScreenOutput();
z1Check = checkZoneTemp(zone1Temp);
z2Check = checkZoneTemp(zone2Temp);
z3Check = checkZoneTemp(zone3Temp);
om (z1Check || z2Check || z3Check) {
startFurnace();
} annat {
stopFurnace();
}
om (z1Check & & furnaceState) {
closeDamper(1);
} annat {
openDamper(1);
}
om (z2Check & & furnaceState) {
closeDamper(2);
} annat {
openDamper(2);
}
om (z3Check & & furnaceState) {
closeDamper(3);
} annat {
openDamper(3);
}
}
booleska checkZoneTemp (int temperatur) {
int temp = getTargetTemperature();
IF(temperature > Temp) {
returnera false;
}
return true;
}
void logTemperatureData() {
log ("Zone1Temp", (String)(int)zone1Temp);
log ("Zone2Temp", (String)(int)zone2Temp);
log ("Zone3Temp", (String)(int)zone3Temp);
}
void getScreenOutput() {
zoneCounter ++;
IF(zoneCounter == 1) {
Sträng val = "Zone1:" + (sträng) (int) zone1Temp;
val += "(" + (String)getTargetTemperature();
val += (sträng) ")";
toScreen (val, "läge:" + getModeString());
}
annat if (zoneCounter == 2) {
Sträng val = "zon†2:" + (sträng) (int) zone2Temp;
val += "(" + (String)getTargetTemperature();
val += (sträng) ")";
toScreen (val, "ugnen:" + getFurnaceState());
}
annat {
zoneCounter = 0;
Sträng val = "3:" + (sträng) (int) zone3Temp;
val += "(" + (String)getTargetTemperature();
val += (sträng) ")";
toScreen (val, "Open:" + getActiveZonesForScreen());
}
}
int getTargetTemperature() {
int läge = getMode();
DateTime nu = RTC.now();
int datum = now.dayOfWeek();
int-värden = {
0}.
log ("info", (sträng) datum);
värden = PROGRAMMED_VALUES [datum];
log ("info", "att få målet temp:" + (String)values[mode]);
returnera värden [mode];
}
Sträng getActiveZonesForScreen() {
Sträng retVal = "";
om (z1Check & &! furnaceState) {
retVal += "1";
}
om (z2Check & &! furnaceState) {
retVal += "2";
}
om (z3Check & &! furnaceState) {
retVal += "3".
}
IF(retVal.length() == 0) {
retVal += "Ingen";
}
returnera retVal;
}
Sträng getFurnaceState() {
IF(furnaceState) {
returnera "På";
}
annat {
returnera "Off";
}
}
Sträng getModeString() {
int läge = getMode();
Växla (läge) {
fall 0:
returnera "Vakna";
fall 1:
returnera "Away";
fall 2:
återvända "Hem";
fall 3:
returnera "Sova";
standard:
returnera "N/A";
}
}
int getMode() {
DateTime nu = RTC.now();
int timme = now.hour();
om (timme < 6 || timme > = 21) {
returnera 3.
}
om (timme > = 6 & & timme < 8) {
Return 0;
}
om (timme > = 8 & & timme < 15) {
tillbaka 1.
}
om (timme > = 15 & & timme < 21) {
returnera 2.
}
}
flyta getTemperature(DeviceAddress deviceAddress) {
flyta tempC = sensors.getTempC(deviceAddress);
Serial.println(tempC);
om (tempC ==-127) {
Serial.println ("fel få temperatur.");
}
återvända DallasTemperature::toFahrenheit(tempC);
}
bekvämlighet funktion. Hanterar alla standardtext för att skriva till LCDScreen
void toScreen (sträng line1Value, sträng line2Value) {
LCD.BEGIN(16,2);
LCD.Clear();
lcd.setCursor(0,0);
LCD.Print(line1Value);
lcd.setCursor(0,1);
LCD.Print(line2Value);
}
Sträng getDateAndTime() {
DateTime nu = RTC.now();
Return String(now.year()) + "/" + String(now.month()) + "/" + String(now.day()) + "" + String(now.hour()) + ":" + String(now.minute()) + ":" + String(now.second());
}
void openDamper (int spjäll) {
om (spjäll == damper1Pin || spjäll == damper2Pin || spjäll == damper3Pin) {
digitalWrite (spjäll, hög);
} annat {
log ("Problem med att öppna spjället. Spjället hittades inte. Väntade 1, 2 eller 3. Fick "+ dämpare);
// }
}
void closeDamper (int spjäll) {
om (spjäll == damper1Pin || spjäll == damper2Pin || spjäll == damper3Pin) {
digitalWrite (spjäll, låg);
} annat {
log ("Problem stänger spjället. Spjället hittades inte. Väntade 1, 2 eller 3. Fick "+ dämpare);
// }
}
funktion för loggningsmeddelanden till konsolen.
Så småningom tänker skriva till loggfilen på RPi
Tom log (sträng kod, sträng meddelande) {
Serial.println (kod + ":" + meddelande);
}
void recordData (String typ, String objekt, strängvärde) {
TODO - utgång till RPi databas
}
void startFurnace() {
Lämplig signal till ugnen att starta upp
IF(!furnaceState) {
furnaceState =! furnaceState;
log ("INFO", "Starta ugnen");
digitalWrite (furnacePin, hög);
}
}
void stopFurnace() {
Lämplig signal till ugnen att stoppa
IF(furnaceState) {
furnaceState =! furnaceState;
log ("INFO", "Stoppa ugnen");
digitalWrite (furnacePin, låg);
}
}
< /tt >< /tt >< /tt >