// load library for display #include // load library for DHT22 sensor #include #define TRESHOLD 2 #define HYSTERESIS 1 #define MIN_OUT_TEMP 5 // °C #define RELAY_PIN 5 #define DHT22_OUTSIDE_PIN 6 #define DHT22_INSIDE_PIN 7 #define LCD_D7_PIN 8 #define LCD_D6_PIN 9 #define LCD_D5_PIN 10 #define LCD_D4_PIN 11 #define LCD_EN_PIN 12 #define LCD_RS_PIN 13 // create objects for sensor communication DHT22 dht22inside(DHT22_INSIDE_PIN); DHT22 dht22outside(DHT22_OUTSIDE_PIN); // create object for LCD communication LiquidCrystal lcd(LCD_RS_PIN, LCD_EN_PIN, LCD_D4_PIN, LCD_D5_PIN, LCD_D6_PIN, LCD_D7_PIN); // these variables are used to capture error states of the sensors: int inside_state = 0; int outside_state = 0; // these variables hold measures from the sensors float inside_temp = 0, outside_temp = 0, inside_humi = 0, outside_humi = 0; // these arrays are used to create some special characters for the LCD byte degree[8] = { 0b00010, 0b00101, 0b00010, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000 }; byte tau[8] = { 0b00000, 0b00000, 0b11110, 0b01000, 0b01000, 0b01001, 0b00110, 0b00000 }; byte on[8] = { 0b11111, 0b10001, 0b11111, 0b11111, 0b11111, 0b11111, 0b10001, 0b11111 }; byte off[8] = { 0b11111, 0b10001, 0b10001, 0b10001, 0b10001, 0b10001, 0b10001, 0b11111 }; void setup() { // set up the LCD lcd.begin(16, 4); lcd.createChar(0, degree); lcd.createChar(1, tau); lcd.createChar(2, on); lcd.createChar(3, off); // prepare "table" on LCD lcd.setCursor(0,0); lcd.print(" IN OUT"); lcd.setCursor(0,1); lcd.print("Temp . . "); lcd.write((int)0); lcd.print("C"); lcd.setCursor(0,2); lcd.print("Humi . . %"); lcd.setCursor(0,3); lcd.print(" "); lcd.write((int)1); lcd.print(" . . "); lcd.write((int)0); lcd.print("C"); // set up the relay pinMode(RELAY_PIN,OUTPUT); // TODO: is this needed any longer? pinMode(4,OUTPUT); digitalWrite(4,LOW); } void printVal(float v){ if (v<10) lcd.print(" "); lcd.print(v,1); } void relayOff(){ lcd.setCursor(0,0); lcd.print("OFF"); digitalWrite(RELAY_PIN,LOW); } void relayOn(){ lcd.setCursor(0,0); lcd.print("ON "); digitalWrite(RELAY_PIN,HIGH); } void fehler(int col, int code){ lcd.setCursor(col,1); lcd.print("Err "); lcd.setCursor(col,2); lcd.print(" "); lcd.print(code); lcd.print(" "); lcd.setCursor(col,3); lcd.print("--- "); relayOff(); } float taupunkt(float t, float r) { float a, b; if (t >= 0) { a = 7.5; b = 237.3; } else { a = 7.6; b = 240.7; } // Sättigungsdampfdruck in hPa float sdd = 6.1078 * pow(10, (a*t)/(b+t)); // Dampfdruck in hPa float dd = sdd * (r/100); // v-Parameter float v = log10(dd/6.1078); // Taupunkttemperatur (°C) return (b*v) / (a-v); } void loop() { delay(2500); // dht 22 sensor may only be read every two seconds inside_temp = dht22inside.getTemperature(); inside_humi = dht22inside.getHumidity(); inside_state = dht22inside.getLastError(); outside_temp = dht22outside.getTemperature(); outside_humi = dht22outside.getHumidity(); outside_state = dht22outside.getLastError(); boolean inside_error = false, outside_error = false; if (inside_state != dht22inside.OK || isnan(inside_temp)||isnan(inside_humi)) { fehler(5,inside_state); inside_error = true; } else { if (inside_temp<-40 || inside_temp>80){ lcd.setCursor(5,1); lcd.print("OOR!"); // out of range! inside_error = true; } else { lcd.setCursor(5,1); printVal(inside_temp); } if (inside_humi<0 || inside_humi>100){ lcd.setCursor(5,2); lcd.print("OOR!"); // out of range inside_error = true; } else { lcd.setCursor(5,2); printVal(inside_humi); } } if (outside_state != dht22outside.OK) { fehler(10,outside_state); outside_error = true; } else { if (outside_temp<-40 || outside_temp>80){ lcd.setCursor(10,1); lcd.print("OOR!"); // out of range! outside_error = true; } else { lcd.setCursor(10,1); printVal(outside_temp); } if (outside_humi<0 || outside_humi>100){ lcd.setCursor(10,2); lcd.print("ORR!"); // out of range! outside_error = true; } else { lcd.setCursor(10,2); printVal(outside_humi); } } lcd.setCursor(5,3); float tau_outside, tau_inside; if (inside_error){ lcd.print("----"); } else { tau_inside = taupunkt(inside_temp,inside_humi); printVal(tau_inside); } lcd.setCursor(10,3); if (outside_error){ lcd.print("----"); } else { tau_outside = taupunkt(outside_temp,outside_humi); printVal(tau_outside); } if (inside_error || outside_error || outside_temp < MIN_OUT_TEMP){ relayOff(); } else { if (tau_inside > tau_outside + TRESHOLD + HYSTERESIS) { relayOn(); } if (tau_inside < tau_outside + TRESHOLD) { relayOff(); } } }