Repozitár projektu Ethernet termostat - strojové kódy: Github
Verzia 1.0.4 projektu Ethernet termostat je posledným updatom verzie zdarma. Ďalšie chyby, bugy a bezpečnostné chyby nebudú riešené.
Článok k projektu na Chiptron.cz: Izbový termostat - Arduino + Ethernet
Arduino Ethernet Wiznet W5100 / W5500 DS18B20 OneWire Dallas HTML Webserver WebSocket

Kompatibilný riadiaci hardvér pre Ethernet termostat:



Kompatibilné Ethernet moduly a shieldy pre Ethernet termostat:


Ethernet shield Wiznet W5100
Ethernet Wiznet W5100
Ethernet modul Wiznet W5200
Ethernet Wiznet W5200
Ethernet modul Wiznet W5200
Ethernet Wiznet W5300
Ethernet modul Wiznet W5500
Ethernet Wiznet W5500

Izbový termostat - Arduino + Ethernet


Arduino je šikovná embeeded platforma, ktorú je možné využiť napríklad na stavbu izbového termostatu s Ethernet konektivitou a webserverom implementovaným na Arduine. Implementácia využíva Arduino Uno / Nano s čipom AVR ATmega328P v kombinácii s Ethernet shieldom Wiznet W5100 / W5500 s ktorým komunikuje cez SPI zbernicu, resp. ICSP header. Programovo funguje termostat v režime webservera, kde dokáže prijímať požiadavky (requesty) od klientov v sieti po HTTP protokole a odosielať na ne odpoveď (response) - HTML / JSON kód a vykonávať pri ich spustení funkcie backendu (vykonanie scriptu, ovládanie GPIO, zápis do pamäte, funkčnosť...). Termostat je prístupný z LAN siete v ktorej sa nachádza, pričom je vybavený webovým rozhraním ktoré slúži na konfiguráciu všetkých prvkov termostatu, t.j. cieľovej (referenčnej) teploty a hysterézy. Webserver umožňuje beh niekoľkých na sebe nezávislých HTML stránok, ktoré môžu mať informatívny (textový výstup), alebo aj funkcionálny charakter (implementovaný backend s funkciami termostatu). Webserver beží na štandardnom HTTP porte - 80.


Termostat dokáže automatizovane prostredníctvom GPIO výstupu ovládať signalizačné relé pre zapnutie / vypnutie kotla. Dokáže tak nahradiť existujúci izbový termostat a sprístupniť ho v sieti klientom. Termostat dokáže obsluhovať akékoľvek zariadenie s prehliadačom - počítač / smartfón / tablet / Smart TV a podobne. Ako rozhodovací algoritmus sa využíva cieľová teplota s hysterézou, ktorá sa porovnáva s nameranou teplotou z digitálneho senzora teploty Dallas DS18B20. Cieľová teplota a hysteréza je načítaná z EEPROM pamäte, kde je uchovaná aj v prípade výpadku napájania permanentne a pri zápise nových dát sa prepíše. Rozlíšenie senzora DS18B20 pri meraní je 12-bitov, čomu rozpovedá rozlíšenie na teploty 0.0625 °C, čo je minimálny rozlišovací krok medzi rozlišnými meraniami. Dáta po OneWire zbernici môžu prísť do mikrokontroléru po vyžiadaní za 500 až 1000 ms v závislosti od počtu senzorov na OneWire zbernici, dĺžke zbernice a podobne... Rozhodovacia logika termostatu sa vykonáva každých 10 sekúnd nezávisle na webaplikácii, nevyžaduje sa keep-alive spojenie pre vykonanie logiky, systém tak funguje autonómne a nevyžaduje pozornosť používateľa.

Po hardvérovej stránke projekt využíva:
  • Arduino Uno
  • Ethernet shield Wiznet W5100 / Ethernet modul Wiznet W5200-W5500
  • Teplotný senzor DS18B20 na OneWire zbernici v puzdre TO-92, alebo vo vodotesnom vyhotovení v hliníkovej rúrke
  • Elektromagnetické relé SRD-5VDC-SL-C / SSR relé OMRON G3MB-202P slúžiace na spínanie kotla (Active-LOW signál)
  • HTML stránky bežiace na Arduine:

  • / - root stránka obsahujúca formulár, aktuálny výpis logického výstupu pre relé, teplotu
  • /action.html - spracúvava hodnoty z formulára, zapisuje ich do EEPROM pamäte, presmeruje používateľa späť na root stránku
  • /get_data.json - distribuuje dáta o aktuálnej teplote, referenčnej teplote a hysteréza tretej strane (počítač, mikrokontróler, iný klient...) v JSON formáte

  • Elektromagnetické relé SRD-5VDC-SL-C, ktoré je v projekte použité umožňuje spínať až 10A pri 230V - maximálny výkon 2300W. V prípade spínania jednosmerného obvodu (záťaže) je možné spínať 300W (10A pri 30V DC max). Pre schému zapojenia je plne kompatibilné aj SSR relé OMRON G3MB-202P, ktoré je vhodné iba pre neindukčnú záťaž a výhradne pre záťaž so striedavým napätím (DC obvod nedokáže po zopnutí rozopnúť). Maximálny spínaný výkon 460W (230V, 2A). Termostat je možné používať celoročne. V prípade nepotrebného riadenia je možné výstup fyzicky odpojiť a termostat využívať ako Ethernet teplomer pre zisk dát z miestnosti, kde sa nachádza.

    Webové rozhranie pre Ethernet termostat umožňuje:
  • Prehliadať v reálnom čase teplotu zo senzora DS18B20 na OneWire zbernici, uptime zariadenia, stav výstupu s dynamickou zmenou, aktuálne nastavené konfiguračné údaje pre termostat t.j. cieľovú teplotu a hysterézu z EEPROM
  • Modifikovať cieľovú (referenčnú) teplotu v rozsahu 5 až 50 °C s 0,25 °C krokom
  • Modifikovať hysterézu v rozsahu 0 až 10 °C s 0,25 °C krokom
  • ZAP/VYP regulácia kotla:
  • Príklad ZAP/VYP regulácie vykurovania - VIZUALIZÁCIA NIE JE SÚČASŤOU PROJEKTU
  • Kotol je aktívny po dobu dostiahnutia cieľovej teploty + hysterézy
  • Na vizualizácii teplôt vody je patrný tzv. dobeh vykurovania a následné chladnutie vody až do opätovnej aktivity vykurovania, kedy je nameraná teplota pod nastavenú cieľovú teplotu - hystérzu
  • ZAP/VYP regulácia kotla s hysterézou

    Webové rozhranie je navrhnuté pre prispôsobenie sa väčším i menším obrazovkám. Je reponzívne, podporuje širokouhlé obrazovky s vysokým rozlíšením, ale aj mobilné zariadenia. Rozhranie využíva importované CSS štýly Bootstrap frameworku z externého CDN servera, ktorý načíta client-side zariadenie pri otvorení stránky bežiacej na Arduine. Nakoľko je Arduino Uno limitované pamäťou, dokáže spustiť iba stránky s veľkosťou pár kB. Importovaním CSS štýlov z externého servera umožní žnížiť výkonové a pamäťové zaťaženie Arduina. Programová implementácia (pri Arduine Uno) využíva cca 70% flash pamäte (32kB - 4kB Bootloader) a 44% RAM pamäte (2kB). Statické časti webovej stránky (hlavička a pätička HTML dokumentu, linkovanie Bootstrap CSS, meta tagy, HTTP response hlavička, Content Type, formulár a ďalšie) sú uložené priamo vo flash pamäti Arduina, čo dokáže výrazne redukovať veľkosť používanej RAM pamäte pre obsah generovaný používateľovi. Webserver je tak stabilnejší a zvláda aj multi-pripojenie viacerých zariadení v sieti súčasne. Spotreba celého termostatu je na úrovni do 200 mA pri 5V napájaní - pod 1W.


    Aby ostali nastavené hodnoty zachované aj po výpadku napájania, sú uložené do EEPROM pamäte Arduina (celkom k dispozícii 512 B). Referenčná teplota je zapísaná na offset 10, hysteréza na offset 100. Každá z hodnôt zaberá maximálne 5B v EEPROM pamäti + ukončovací znak - terminátor. Limit prepisov EEPROM je na úrovni 100-tisíc prepisov. Dáta sa prepisujú iba pri odoslaní HTML formulára. Prevádzka termostatu je tak maximálne šetrná k EEPROM pamäti s cieľom maximalizovať jej životnosť. V prípade, že zariadenie pri prvom spustení nemá nič uložené na spomenutých EEPROM offsetoch, vykoná sa automatický zápis s predvolenými hodnotami - referencia: 20.25 °C, hysteréza 0.25 °C, tzv. fail-safe riešenie, aby bol termostat ihneď funkčný a pripravený k prevádzke.


    Prostredníctvom meta tagu Refresh vykonáva webserver obnovu celej stránky každých 30 sekúnd a prostredníctvom Javascriptu sa vypisuje do HTML stránky aj orientačný čas do refreshu. Do tohto času je potrebné stihnúť zapísať zmenu pre termostat, inak sa input okná pre číselné vstupy do formulára resetujú pri obnovení stránky. Na základe spätnej väzby od používateľov Android zariadení bol čas pre Refresh predĺžený z 10 na 30 sekúnd. Nakoľko built-in knižnica Ethernet neobsahuje využitie asynchrónneho webservera (ktorý je možné využiť napríklad u mikrokontrolérov Espressif ESP8266 / ESP32), je nutné prepisovať celú stránku. Dynamický údaj, ktorý sa predovšetkým mení je aktuálna hodnota výstupu - Zapnutý / Vypnutý, ktorý informuje prevádzkovateľa o skutočnom stave výstupu spoločne aj s farebným označením. Nakoľko sa logika systému vykonáva nezávisle na webserveri, do refreshu môže už byť výstup v inom stave, ako aktuálne vypísanom vo webaplikácii. Zmena výstupu je ihneď vypísaná napríklad na UART monitor (115200 baud/s). Na webovej stránke termostatu nájde používateľ aj informácie o uptime zariadenia (ako dlho beží), t.j. čas v dňoch, hodinách, minútach a sekundách.

    Autor Ethernet termostatu nezodpovedá za funkčnosť termostatu, poruchu kotla, úraz elektrickým prúdom pri neodbornej montáži termostatu do siete. Termostat je šírený pod MIT licenciou.
    Hlavná stránka pre modifikáciu cieľovej teploty a hysterézy - ukážka zapnutého:
    Ukážkové dáta
  • Cieľová teplota: 22.75 °C
  • Hysteréza: 0.25 °C
  • Namerané dáta: 21.59 °C
  • Výstup: Zapnutý

  • Termostat vykuruje od nameranej teploty 22.49 °C a nižšej. V prípade dosiahnutia teploty 23.01 °C sa výstup vypne, signalizačné relé sa rozpojí a plynový kotol prestáva kúriť. Nastáva dobeh vykurovania a chladnutie miestnosti v ktorej sa vykonávajú merania. Termostat sa opäť aktivuje až pri dosiahnutí teploty 22.49 °C, alebo nižšej.

    Ethernet termostat - Hlavný prehľad s modifikáciou cieľovej teploty a hysterézy - Vypnutý Priebeh spracovania zadaných údajov (presmerovanie používateľa): Ethernet termostat - spracovanie údajov z HTML formulára JSON výstup webservera v prehliadači / klientovi cez websocket:
    Ethernet termostat - JSON output
    Výstup do UART monitoru - logika systému + nastavenie Ethernet adaptéru:
    Ethernet termostat - UART
    Rozšírená verzia tohto termostatu obsahuje navyše - NIE JE OBSIAHNUTÁ V GITHUB REPOZITÁRI SO STROJOVÝMI KÓDMI:
    Pri záujme o kúpu plnej verzie projektu so zdrojovým kódom (.ino) - martinius96@gmail.com
  • Manuálny režim pre relé (neobmedzená doba, natvrdo ZAP/VYP)
  • Watchdog timer
  • Dostupné senzory SHT21, SHT31, DHT22, BME280, BMP280 a iné
  • Režim chladenia
  • Ovládanie a konfigurácia po RS232 / UART nezávisle na Ethernete
  • PID regulácia teploty pre termostat
  • Možnosť využitia platforiem ESP8266, ESP32 pre termostat

  • Fragmenty zdrojových kódov (bez backendu)


  • ZDROJOVÉ KÓDY SÚ IBA FRAGMENTY A NIE JE ICH MOŽNÉ BEZ ĎALŠÍCH (TU NEDOSTUPNÝCH) ČASTÍ POUŽIŤ. OBSAHUJÚ PREMENNÉ, FUNKCIE, KTORÝCH DEFINÍCIE, RESP. DEKLARÁCIE NIE SÚ DOSTUPNÉ.
  • Fragment zdrojového kódu pre logiku termostatu - Rozhodovací threshold

  • Vykonáva sa každých 10 sekúnd bez ohľadu na webserver, či pripojenie klienta
  •     teplota = sensorsA.getTempCByIndex(0);
        String referencia = read_String(10);
        String hystereza = read_String(100);
        float referencia_teplota = referencia.toFloat();
        float hystereza_teplota = hystereza.toFloat();
        float minus_hystereza_teplota = (-1 * hystereza_teplota);
        float rozdiel = referencia_teplota - teplota;
        if (rozdiel > hystereza_teplota) {
          Serial.println("RELE ZAP");
          stav = "ZAP";
          digitalWrite(rele, LOW);
        } else if (rozdiel < minus_hystereza_teplota) {
          Serial.println("RELE VYP");
          stav = "VYP";
          digitalWrite(rele, HIGH);
        }
        sensorsA.requestTemperatures();
    

    Fragment zdrojového kódu pre stránku Hlavného prehľadu - bez spracovania údajov z HTML formuláru

              HTTP header
    	  DOCTYPE
    	  HTML
    	  HEAD
    	  client.println(F("<meta charset='utf-8'>"));
              client.println(F("<meta name='author' content='Martin Chlebovec'>"));
              client.println(F("<meta http-equiv='Refresh' content='10'; />"));
              client.println(F("<title>HTTP webserver - Arduino + Ethernet</title>"));
              client.println(F("</head>"));
              client.println(F("<body>"));
              client.println(F("<center><h3>Zadajte dáta pre webserver (budú uložené do EEPROM):</h3>"));
              client.println(F("<form action='/action.html' method='get'>"));
              client.println("<b>Referenčná teplota:</b><br><input type='number' id='fname' name='fname' min='5' max='50' step='0.25' value=" + read_String(10) + "><br>");
              client.println("<b>Hysteréza:</b><br><input type='number' id='fname2' name='fname2' min='0' max='10' step='0.25' value=" + read_String(100) + "><br>");
              client.println(F("<input type='submit' class='btn btn-success' value='Zapísať'>"));
              client.println(F("</form><hr>"));
              if (stav == "ZAP") {
                client.println(F("<b><font color='green'>Výstup: Zapnutý</font></b>"));
              }
              if (stav == "VYP") {
                client.println(F("<b><font color='red'>Výstup: Vypnutý</font></b>"));
              }
              client.println(F("<div id=\"countdown\"></div>"));
              client.print(F("<b>Aktuálna teplota senzora DS18B20:</b> "));
              client.print(teplota);
              client.println(F(" °C"));
              client.print(F("<hr>"));
              client.println(F("<h3>Autor: Martin Chlebovec - martinius96@gmail.com - https://martinius96.github.io/termostat-ethernet/</h3>"));
              client.println(F("<h4>Verzia free - 1.0.2.1 build: 12. Jan 2021</h4>"));
              client.println(F("</center>"));
              client.println(F("</body>"));
              client.println(F("</html>"));
    	  FLUSH CLIENT
    	  STOP CLIENT
    

    Fragment zdrojového kódu s výpisom nastavených riadiacich dát po odoslaní HTML formuláru

  • S následným presmerovaním používateľa späť na hlavnú stránku po 5-tich sekundách od spracovania - tzv. lazy loading... (Spracovanie neobsiahnuté vo fragmente)
  • 	    backend_spracovanie dát z HTML formuláru (NEDOSTUPNÉ)
    	    .
    	    .
    	    .
                HTTP header
    	    DOCTYPE
    	    HTML
    	    HEAD
                client.println(F("<meta charset='utf-8'>"));
                client.println(F("<meta http-equiv='Refresh' content='5; url=/' />"));
                client.println(F("<title>HTTP webserver - Arduino + Ethernet</title>"));
                client.println(F("</head>"));
                client.println(F("<body>"));
                client.println(F("<center><h3>Server prijal data z formulára:</h3>"));
                client.println("<li><b>Referenčná teplota: </b>" + String(H_1) + "</li>");
                client.println("<li><b>Hysteréza: </b>" + String(H_2) + "</li>");
                client.println(F("<b>Presmerovanie... Prosim cakajte</b></center>"));
                client.println(F("</body>"));
                client.println(F("</html>"));
    	    FLUSH CLIENT
    	    STOP CLIENT
    

    Ukážkový výpis - JSON output pre ďalších klientov, spracovanie

    {
    "Hysteresis":0.25,
    "Target_Temperature":21.75,
    "Actual_Temperature":21.43
    }

    Programovú implementáciu v strojových kódoch pre izbový (Ethernet) termostat je možné nájsť na: https://github.com/martinius96/termostat-ethernet/. Implmentácia obsahuje programy pre statickú / dynamickú IPv4 adresu priradenú k Ethernet shieldu. Termostat je určený iba pre interiérové teploty! (nad 0°C), čomu je prispôsobená aj logika systému! Termostatom je možné nahradiť už existujúci izbový termostat, možno dočasne nahradiť ohrievač v akváriu / teráriu pre udržiavanie stálej teploty.

    Changelog verzie 1.0.4 Ethernet termostatu:
  • Optimalizácia webaplikácie, zvýšená rýchlosť odozvy pre low-latency response
  • Pre HTML form museli byť pre nekompatibilitu prehliadača Google Chrome pre Android odstránené typy number pre input.
  • Upravený backend, pre porovnanie dátového typu vstupu s (ne)akceptáciou vstupu.
  • Opravený JSON output (prehodené riadiace teploty) k opačným entitám
  • Opravený Content-type pre JSON output z text/html na application/json
  • Všetky statické časti HTML stránok presunuté do ROM pamäte cez F() makro
  • Maximálne ohľahčená RAM pamäť pre bezproblémový beh low-latency webservera.
  • Pre DHCP príklad použitá funkcia Ethernet.maintain() pre renew času DHCP poolu.
  • (predĺženie rovnakej IP adresy / vyžiadanie novej - v závislosti od konfigurácie DHCP služby)
  • Zmena názvu JSON súboru z get_data na get_data.json
  • Zobrazený uptime zariadenia - dni, hodiny, minúty, sekundy
  • HTTP 404 - Not Found pri zobrazení umiestnenia, na ktoré nemá webserver callback