#include <Wire.h> //vložené knihovny
#include <Adafruit_SSD1306.h>
#include <U8g2lib.h>
#include <dht.h>
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0); //inicializace I2C displeje
#define DHT22_PIN 5 //vstup pro teplotní čidlo
#define POWER 9 //vstup pro ovládací přepínač
#define HEAT 7 //výstup pro topné těleso
dht DHT; //inicializece teplotního čidla
float wanted = 0;
int heatState = LOW;
int chk = DHT.read22(DHT22_PIN);
int minValue = 20; //minimální možná teplota
int maxValue = 45; //maximální možná teplota
bool indicator = false;
bool powerSW = false;
bool overheat = false;
bool error = false;
unsigned long lastTemp = 0; //místo pro ukládání času poslední kontroly teploty
unsigned long lastMillis = 0; //místo pro ukládání času spínání tělesa
const long onDuration = 4000; //doba spuštění topného tělesa při blížící se toplotě
const long offDuration = 1800; //pauza mezi spouštěními topného tělesa
struct {
uint32_t total;
uint32_t ok;
uint32_t connect;
} stat = { 0, 0, 0};
void setup() {
u8g2.begin();
u8g2.setBitmapMode (1);
u8g2.setColorIndex(1);
u8g2.clearDisplay();
pinMode (A0, INPUT);
pinMode (POWER, INPUT);
pinMode (HEAT, OUTPUT);
}
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - lastTemp >= 1000) { //čas mezi kontrolami teploty (1s)
chk = DHT.read22(DHT22_PIN);
lastTemp = currentMillis;
}
//control
wanted = analogRead (A0); //čtení hodnot potenciometru
wanted = map (wanted, 0, 1023, minValue, maxValue); //upravení hodnot podle limitních teplot
if (digitalRead (POWER) == HIGH && error != true) { //ovládání přepínačem
powerSW = true;
}
else {
powerSW = false;
overheat = false;
}
if (DHT.temperature > 47) { //chyba - přehřátí (47°C)
overheat = true;
heatState = LOW;
digitalWrite (HEAT, heatState);
}
//logic
stat.total++;
switch (chk)
{
case DHTLIB_OK: //kontrola funkčnosti teplotního čidla
stat.ok++;
error = false;
break;
case DHTLIB_ERROR_CONNECT: //chyba - čidlo nebylo detekováno
stat.connect++;
error = true;
break;
}
if (powerSW == HIGH && overheat == false) { //provoz topného tělesa, mezi požadovanou a
if (wanted - DHT.temperature >= 2) { //dokud nebude dosaženo rozdílu 2°C
heatState = HIGH; //mezi současnou a požadovanou teplotou
digitalWrite (HEAT, heatState);
indicator = true;
}
else if (wanted - DHT.temperature <= 2 && wanted - DHT.temperature >= 0) { //provoz tělesa
if (heatState == HIGH) { //po dosažení rozdílu
if (currentMillis - lastMillis >= onDuration) {
heatState = LOW;
digitalWrite (HEAT, heatState); //spouštění tělesa v intervalech
indicator = false;
lastMillis = currentMillis;
}
}
else {
if (currentMillis - lastMillis >= offDuration) { //pauza mezi sepnutími
heatState = HIGH;
digitalWrite (HEAT, heatState);
indicator = true;
lastMillis = currentMillis;
}
}
}
else if (DHT.temperature - wanted > 1) { //odstaení tělesa po dosažení teploty
heatState = LOW;
digitalWrite (HEAT, heatState);
indicator = false;
}
else {
return;
}
}
else {
heatState = LOW; //stav při vypnutém přepínači
digitalWrite (HEAT, heatState);
indicator = false;
}
//displej
u8g2.firstPage(); //zobrazení na displeji
do {
if (error == false) {
if (overheat == false || overheat == true && powerSW == false) { //aktuální teplota
u8g2.setFontDirection(0);
u8g2.setDrawColor(1);
u8g2.setFont(u8g2_font_fub30_tn);
u8g2.setCursor(0, 31);
u8g2.print(DHT.temperature, 1);
u8g2.setFont(u8g2_font_fub20_tf);
u8g2.drawUTF8(80, 25, "°C");
}
else if (overheat == true && powerSW == true) { //zobrazení chyby přahřátí
u8g2.setFontDirection(0);
u8g2.setDrawColor(1);
u8g2.setFont(u8g2_font_fub20_tf);
u8g2.setCursor(1, 28);
u8g2.print("OverHeat");
}
//wanted temperature //požadovaná teplota
u8g2.setFont(u8g2_font_fub20_tf);
u8g2.setCursor(25, 60);
u8g2.print(wanted, 1);
//min-max temperature //minimální x maximální teplota
u8g2.setFont (u8g2_font_7x13B_tf);
u8g2.setCursor (1, 46);
u8g2.print (maxValue);
u8g2.setCursor (1, 60);
u8g2.print (minValue);
u8g2.drawTriangle (18,36, 14,41, 22,41);
u8g2.drawBox (17, 41, 3, 5);
u8g2.drawTriangle(18,60, 15,56, 22,56);
u8g2.drawBox (17, 51, 3, 5);
//heating indicator
if (indicator == true) { //aktuální stav topného tělesa
u8g2.drawRBox(87,40,20,20,7);
}
if (powerSW == true) { //ukazatel zapnutého tělesa
u8g2.setFont(u8g2_font_7x13B_tr);
u8g2.setFontDirection(1);
u8g2.drawStr(115, 44, "ON");
}
else if (powerSW == false) { //ukazatel vypnutého tělesa
u8g2.setFont(u8g2_font_7x13B_tr);
u8g2.setFontDirection(1);
u8g2.drawStr(115, 41, "OFF");
}
}
else if (error == true) { //zobrazení chyby čtení z teplotní čidla
u8g2.setFontDirection(0);
u8g2.setDrawColor(1);
u8g2.setFont(u8g2_font_fub20_tf);
u8g2.setCursor(10, 28);
u8g2.print("Reading");
u8g2.setCursor(30, 50);
u8g2.print("error");
}
}while ( u8g2.nextPage() );
}