You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
259 lines
5.2 KiB
259 lines
5.2 KiB
// load library for display |
|
#include <LiquidCrystal.h> |
|
// load library for DHT22 sensor |
|
#include <DHT22.h> |
|
|
|
#define TRESHOLD 1 |
|
#define HYSTERESIS 1 |
|
#define MIN_OUT_TEMP 5 // °C |
|
#define ALLOWED_HUMIDITY 50 // % |
|
|
|
#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 table(){ |
|
// 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"); |
|
} |
|
|
|
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); |
|
|
|
table(); |
|
|
|
// 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(); |
|
int secs = millis()/1000; |
|
if (secs % 3600 < 3) table(); |
|
|
|
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 (inside_humi > ALLOWED_HUMIDITY && tau_inside > tau_outside + TRESHOLD + HYSTERESIS) { |
|
relayOn(); |
|
} |
|
if (tau_inside < tau_outside + TRESHOLD) { |
|
relayOff(); |
|
} |
|
} |
|
}
|
|
|