Advertisement
Antropex

Termostat

May 7th, 2017
307
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 15.48 KB | None | 0 0
  1. /*
  2.       TERMOSTAT V1.0
  3.  Działa jak zwykły termostat tylko że:
  4.  -Każde wyjście może mieć przypisaną własną czujkę, lub korzystać ze średniej wartości
  5.  -Ilość przewidzianych czujek to 8.
  6.  -Ilość przewidzianych wyjść to 8, ale lekko modyfikując kod i dodając odpowiednią ilość ekspanderów można uzyskać ich b.d ilość.
  7.  (Gdyby użyć jeszę multiplekserów to ilość wyjść przekroczy pewnie każde wymagania)
  8.  -Można podglądać wartości odbierane z czujek.
  9.  -Można sterować manualnie (tryb automatyczny nie aktywny)
  10.  -Wartości załączania ustawiamy z poziomu keypada podłączonego do arduino
  11.  -Wsparcie dla wyświetlacza lcd (hd...) z konwerterem I2C oraz monitora portu szeregowego
  12.  
  13.  Dodatkowo planuję:
  14.  -Dodać "first setup" czyli konfigurowanie która czujka jest na dworzu a która w środku, zakres tolrerancji, czas odświeżania, ustawianie wartości eeprom itp.
  15.  -Dodać krytyczną wartośc dla danej czujki która spowoduję wyłączenie wszystkich wyjść.
  16.  -*Sterowanie wyjściami za pomocą SMS i wysyłanie danych na żądanie.
  17.  -*Setrowanie z poziomu przeglądarki
  18.  * - Może kiedyś, ale nie w najbliższym czasie.
  19.  
  20.  Do podstawowego działania wymagane jest:
  21.  -Jakieś arduino (ja użyłem UNO, ale finalnie planuję zapakować w nano)
  22.  -Wyświetlacz z konwerterem  I2C 2x16 (może być większy, polecam wtedy zmodyfikować kod aby    czytelniej wyświetlał dane )
  23.  -2 ekspandery pcf8574
  24.  -Klawiatury 4x4
  25.  -Czujnika temperatury i wilgotności (Domyślnie DHT22)  
  26.  -No i oczywiście zasilania 5V oraz przewody.
  27.  
  28.  Wykonał Michał Wysocki
  29.  Stworzono 07.05.2017
  30.  
  31.  */
  32. #include <Wire.h>
  33. #include <Keypad_I2C.h>
  34. #include <Keypad.h>
  35. #include <LiquidCrystal_I2C.h>
  36. #include <LiquidCrystal_I2C.h>
  37. #include <EEPROM.h>
  38. #include <PCF.h>
  39. #include <dht.h>
  40. LiquidCrystal_I2C lcd(0x27,16,2);//Inicjacja wyświetlacza
  41.  
  42. dht DHT;
  43. PCF expander;
  44.  
  45. const byte ROWS = 4;
  46. const byte COLS = 4;
  47.  
  48. char keys[ROWS][COLS] = {
  49.   {
  50.     '1', '2', '3', 'A'                        }
  51.   ,
  52.   {
  53.     '4', '5', '6', 'B'                        }
  54.   ,
  55.   {
  56.     '7', '8', '9', 'C'                        }
  57.   ,
  58.   {
  59.     '*', '0', '#', 'D'                        }
  60. };
  61.  
  62. byte rowPins[ROWS] = {
  63.   0, 1, 2, 3};
  64. byte colPins[COLS] = {
  65.   4, 5, 6, 7};
  66. int i2caddress = 0x20;//Inicjacja klawiatury
  67. Keypad_I2C kpd = Keypad_I2C( makeKeymap(keys), rowPins, colPins, ROWS, COLS, i2caddress );
  68.  
  69. // KONIEC INICJALIZACJI
  70.  
  71. int mode = 0 ;//Ustawia tryb
  72. int ekran;//Inaczej krok (pozostałości po inny pomyśle wyświetlania)
  73. //Zmienne konfiguracji
  74. int value;
  75. boolean TH;  
  76. int PIN;
  77. int czujka;
  78. //ZMIENNE AUTOMATU;
  79. int TValue[8];//Temperatury załączania
  80. int HValue[8];
  81. int Czujka[8];//Która czujka odpowiada za jakie wyjście
  82. int temps;//Średnie wartośći
  83. int humas;
  84. long last;//Ostatni czas sprawdzania czujek
  85. long now;
  86. int temp[9];//Odczyty z czujek
  87. int huma[9];
  88. boolean wlacz[8];
  89. boolean first = 1;
  90. void setup() {
  91.   // set up the LCD's number of columns and rows:
  92.   lcd.init();  
  93.   lcd.backlight();
  94.   // Print a message to the LCD.
  95.   lcd.print("Termostat");
  96.   lcd.setCursor(0, 1);
  97.   lcd.print("V1.0");
  98.   //KEYPAD
  99.   Serial.begin(9600);
  100.   kpd.begin();
  101.   expander.begin(0x21);
  102.   expander.pinMode(1, OUTPUT);
  103.   expander.pinMode(2, OUTPUT);
  104.   expander.pinMode(3, OUTPUT);
  105.   expander.pinMode(4, OUTPUT);
  106.   expander.pinMode(5, OUTPUT);
  107.   expander.pinMode(6, OUTPUT);
  108.   expander.pinMode(7, OUTPUT);
  109.   expander.pinMode(8, OUTPUT);
  110.   pinMode(2, OUTPUT);
  111.   int i;
  112.   for(int i = 0; i < 9; i++){
  113.     wlacz[i]=0;
  114.     Serial.println(i);
  115.     //Reczny format ustawien
  116.     //    EEPROM.write(i,0);
  117.     //    EEPROM.write(i+10,0);
  118.     //    EEPROM.write(i+20,0);
  119.     value = EEPROM.read(i+10);
  120.     if (value >= 100){
  121.       value = -value +100;
  122.     }
  123.     TValue[i] = value;
  124.  
  125.     value = EEPROM.read(i+20);
  126.     if (value >= 100){
  127.       value = -value +100;
  128.     }
  129.     HValue[i] = value;
  130.     Czujka[i] = EEPROM.read(i);
  131.   }
  132.  
  133. }
  134. void loop() {
  135.  
  136.   char key = kpd.getKey();
  137.   if (key) {
  138.     lcd.clear();
  139.     byte change = true;
  140.     switch (key) {//Ustawianie trybów
  141.     case 'A' :
  142.       lcd.print("Automat");
  143.       mode = 1;
  144.       Serial.println(key);
  145.       ekran = 1;//EKRAN = KROK POZOSTALOSCI PO CASE
  146.       break;
  147.     case 'B' :
  148.       lcd.print("Manual");
  149.       mode = 2;
  150.       Serial.println(key);
  151.       ekran = 2;
  152.       break;
  153.     case 'C' :
  154.       lcd.print("Setup");
  155.       mode = 3;
  156.       Serial.println(key);
  157.       ekran = 3;
  158.       break;
  159.     case 'D' :
  160.       lcd.print("Dane");
  161.       mode = 4;
  162.       Serial.println(key);
  163.       ekran = 4;
  164.       break;
  165.     }
  166.     //KONIEC USTAWIANIA TRYBÓW
  167.     int Key = key - '0';
  168.     switch (mode) {
  169.     case 1 :
  170.       { //JEŚLI AUTOMAT
  171.         switch(key){
  172.         case 'A':
  173.           break;
  174.         default:
  175.           lcd.print(Key);
  176.           lcd.print(" TEMP->");
  177.           lcd.print(temp[Key]);
  178.           lcd.setCursor(0,1);
  179.           lcd.print(Key);
  180.           lcd.print("WILG->");
  181.           lcd.print(huma[Key]);  
  182.           break;
  183.         }
  184.       }
  185.       break;
  186.     case 2 ://MANUAL
  187.       {
  188.         if((Key > 0 ) & (Key < 9) & (Key != 18)){
  189.           Key = Key - 1;
  190.           expander.digitalWrite(Key, !expander.digitalRead(Key));
  191.           ekran = 6;
  192.           Serial.println(Key);
  193.           if(expander.digitalRead(Key) == HIGH){
  194.             lcd.print("WLACZAM  ");
  195.             lcd.print(Key);
  196.           }
  197.           else{
  198.  
  199.             lcd.print("WYLACZAM ");
  200.             lcd.print(Key);
  201.  
  202.           }
  203.         }
  204.         else{
  205.           if(Key != 18){
  206.             lcd.print("POZA ZAKRESEM ");
  207.             Serial.println("POZA ZAKRESEM ");
  208.             Serial.println(Key);
  209.           }
  210.         }
  211.         if (key == '*'){
  212.           ekran = 7;
  213.           int i = 0;
  214.           while (i < 8){
  215.             lcd.clear();
  216.             lcd.print("Wylaczam");
  217.             lcd.setCursor(0, 1);
  218.             lcd.print(i);
  219.             expander.digitalWrite(i, HIGH);
  220.             Serial.print("SETING ");
  221.             Serial.print(i);
  222.             Serial.println(" HIGH");
  223.             delay (1500);
  224.             i++;
  225.           }
  226.         }
  227.         if (key == '#'){
  228.           ekran = 8;
  229.           int i = 0;
  230.           while (i < 8){
  231.             lcd.clear();
  232.             lcd.print("Zalczam");
  233.             lcd.setCursor(0, 1);
  234.             lcd.print(i);
  235.             expander.digitalWrite(i, LOW);
  236.             Serial.print("SETING ");
  237.             Serial.print(i);
  238.             Serial.println(" LOW");
  239.             delay(1500);
  240.             i++;
  241.           }
  242.         }
  243.       }
  244.       break;
  245.     case 3:
  246.       {
  247.         switch (ekran)
  248.         {
  249.         case 3://Ustawianie wartości
  250.           lcd.clear();
  251.           lcd.print("PODAJ PIN");
  252.           Serial.println("PODAJ PIN");
  253.           ekran = 80;
  254.           break;
  255.         case 80:
  256.           if((Key > 8) || (Key < 0)){
  257.             lcd.print("POZA ZAKRESEM");
  258.             Serial.println("POZA ZAKRESEM");
  259.           }
  260.           else{
  261.             lcd.print("PIN =");
  262.             lcd.print(Key);
  263.             Serial.print("PIN = ");
  264.             Serial.println(Key);
  265.             PIN = Key;
  266.             delay(500);
  267.             Serial.println("TEMP/HUM");
  268.             lcd.setCursor(0, 1);
  269.             lcd.print("TEM/HUM");
  270.             ekran = 81;
  271.           }
  272.           break;
  273.         case 81:
  274.           if(Key == 1){
  275.             Serial.print("TEMPERATURA");
  276.             TH = 0;
  277.             value = TValue[PIN];
  278.             ekran = 82;
  279.             lcd.setCursor(0, 1);
  280.             Serial.print("Wartosc:");
  281.             lcd.print("TEMP WARTOSC");
  282.           }
  283.           else if (Key == 2){
  284.             Serial.print("WILOGOTNOSC");
  285.             TH = 1;
  286.             value = HValue[PIN];
  287.             Serial.print("Wartosc");
  288.             ekran = 82;
  289.             lcd.print("WILGO WATOSC");
  290.           }
  291.           break;
  292.         case 82:
  293.           switch(key) {
  294.           case '1' :
  295.             value++;
  296.             Serial.print("WARTOSC= ");
  297.             Serial.println(value);
  298.             lcd.print("WARTOSC:");
  299.             lcd.setCursor(0, 1);
  300.             lcd.print(value);
  301.             break;
  302.           case '2' :
  303.             value = value +5;
  304.             Serial.print("WARTOSC= ");
  305.             Serial.println(value);
  306.             lcd.print("WARTOSC:");
  307.             lcd.setCursor(0, 1);
  308.             lcd.print(value);
  309.             break;
  310.           case '4' :
  311.             value--;
  312.             Serial.print("WARTOSC= ");
  313.             Serial.println(value);
  314.             lcd.print("WARTOSC:");
  315.             lcd.setCursor(0, 1);
  316.             lcd.print(value);
  317.             break;
  318.           case '5' :
  319.             value = value - 5;
  320.             Serial.print("WARTOSC= ");
  321.             Serial.println(value);
  322.             lcd.print("WARTOSC:");
  323.             lcd.setCursor(0, 1);
  324.             lcd.print(value);
  325.             break;
  326.           case '#' :
  327.             ekran = 83;
  328.             Serial.println("CZUJKA->");
  329.             lcd.print("CZUJKA->");
  330.             break;
  331.           }
  332.           //KONTROLA
  333.           if(value > 99){
  334.             value = 99;
  335.             ekran = 82;
  336.             Serial.print("MAX");
  337.             Serial.println(value);
  338.             lcd.print("MAX:");
  339.             lcd.setCursor(0, 1);
  340.             lcd.print(value);
  341.           }
  342.           else if (value < -99) {
  343.             value = -99;
  344.             ekran = 82;
  345.             Serial.print("MIN");
  346.             Serial.println(value);
  347.             lcd.print("MIN:");
  348.             lcd.setCursor(0, 1);
  349.             lcd.print(value);
  350.           }
  351.           break;
  352.         case 83:
  353.           if((Key > 8) || (Key < 0)){
  354.             Serial.println("POZA ZAKRESEM");
  355.             lcd.print("POZA ZAKRESEM");
  356.           }
  357.           else{
  358.             lcd.print("Czujka = ");
  359.             lcd.print(Key);
  360.             Serial.print("CZUJKA = ");
  361.             Serial.println(Key);
  362.             czujka = Key;
  363.             ekran = 84;
  364.           }
  365.           break;
  366.         case 84:
  367.           if (TH == 0){
  368.             lcd.print("PIN=");
  369.             lcd.print(PIN);
  370.             lcd.print(" TEMP>");
  371.             lcd.print(value);
  372.             lcd.setCursor(0, 1);
  373.             lcd.print("Czujka");
  374.             lcd.print(czujka);
  375.             Serial.print("Zalaczam PIN ");
  376.             Serial.println(PIN);
  377.             Serial.print("Dla temperatury wyzszej niz ");
  378.             Serial.println(value);
  379.             Serial.print("Czujka zalaczajaca ");
  380.             Serial.println(czujka);
  381.             TValue[PIN]= value;
  382.             Czujka[PIN]= czujka;
  383.             if(value >= 0){
  384.               EEPROM.write(PIN+10, value);
  385.             }
  386.             else {
  387.               value = -value +100;
  388.               EEPROM.write(PIN+10, value);
  389.             }
  390.             EEPROM.write(PIN, czujka);
  391.           }
  392.           else {
  393.             lcd.print("PIN=");
  394.             lcd.print(PIN);
  395.             lcd.print(" WILGO>");
  396.             lcd.print(value);
  397.             lcd.setCursor(0, 1);
  398.             lcd.print("Czujka");
  399.             lcd.print(czujka);
  400.             Serial.print("Zalaczam PIN ");
  401.             Serial.println(PIN);
  402.             Serial.print("Dla wilgotnosci wyzszej niz ");
  403.             Serial.println(value);
  404.             Serial.print("Czujka zalaczajaca ");
  405.             Serial.println(czujka);
  406.             HValue[PIN]= value;
  407.             Czujka[PIN]= czujka;
  408.             if(value >= 0){
  409.               EEPROM.write(PIN+20, value);
  410.             }
  411.             else {
  412.               value = -value +100;
  413.               EEPROM.write(PIN+20, value);
  414.             }
  415.             EEPROM.write(PIN, czujka);
  416.           }
  417.           ekran = 85;
  418.           break;
  419.         }
  420.  
  421.       }
  422.       break;
  423.     case 4:
  424.       {//Wyświetlanie ustawień
  425.         switch (Key){
  426.         case -6:
  427.           lcd.print(" NIEDOSTEPNE");
  428.           for(int i = 1; i < 9; i++)
  429.           {
  430.             Serial.print(TValue[i]);
  431.             Serial.print("<-TEMP |");
  432.             Serial.print(Czujka[i]);
  433.             Serial.print("| WILGO ->");
  434.             Serial.println(HValue[i]);
  435.           }
  436.           break;
  437.         case 20:
  438.           break;
  439.         default:
  440.           if((Key > 8) || (Key < 0) && (Key != 20)){
  441.             Serial.println("POZA ZAKRESEM");
  442.             lcd.print("POZA ZAKRESEM");
  443.           }
  444.           else {
  445.             lcd.print(Key);
  446.             lcd.print(" TEMP ->");
  447.             lcd.print(TValue[Key]);
  448.             lcd.setCursor(0, 1);
  449.             lcd.print(Czujka[Key]);
  450.             lcd.print(" WILGO ->");
  451.             lcd.print(HValue[Key]);
  452.             Serial.print(TValue[Key]);
  453.             Serial.print("<-TEMP |");
  454.             Serial.print(Czujka[Key]);
  455.             Serial.print("| WILGO ->");
  456.             Serial.println(HValue[Key]);
  457.           }
  458.           break;
  459.         }
  460.         break;
  461.       }
  462.  
  463.     }
  464.   }
  465.   now = millis();//Automat
  466.  
  467.   // Wykonuje zadanie co pewien czas
  468.   if  ( ( (now % 10000) < 10) && ( (now - last) > 200) ) {
  469.     Serial.println("Lapie");
  470.     last = now;
  471.     int b=0;
  472.  
  473.     int tsv =0;
  474.     int hsv =0;
  475.     for(int i = 0; i < 9;i++){
  476.       temp[i] = -200;
  477.       huma[i] = -200;
  478.     }
  479.     for(int i = 1; i <= 8;i++){
  480.       int chk = DHT.read22(i+2);//PIN początkowy = 3
  481.       if(!((chk == DHTLIB_ERROR_CHECKSUM) || (chk == DHTLIB_ERROR_TIMEOUT))){
  482.         b++;
  483.         temp[i] = DHT.temperature;
  484.         huma[i] = DHT.humidity;
  485.         tsv = tsv + temp[i];
  486.         hsv = hsv + huma[i];
  487.         Serial.print("WYKRYTO CZUJKE PIN->");
  488.         Serial.print(i);
  489.         Serial.print(" TEMP->");
  490.         Serial.print(temp[i]);
  491.         Serial.print(" HUMA->");
  492.         Serial.println(huma[i]);
  493.         Serial.print(" hsv->");
  494.         Serial.println(hsv);
  495.       }
  496.     }
  497.     tsv = tsv/b;
  498.     hsv = hsv/b;
  499.     //Czujka zero ma być zawsze średnią
  500.     for(int i = 0; i <= 8;i++){
  501.       if(temp[i] < -150){
  502.         temp[i] = tsv;
  503.         huma[i] = hsv;
  504.  
  505.       }
  506.  
  507.     }
  508.     //Uzywane do sprawdzania czujek
  509.     //    for(int i = 0; i <= 8;i++){
  510.     //      Serial.print(temp[i]);
  511.     //      Serial.print("<-TEMP|");
  512.     //      Serial.print(i);
  513.     //      Serial.print("|huma->");
  514.     //      Serial.println(huma[i]);
  515.     //
  516.     //    }
  517.  
  518.     if(mode != 2){//Odpowiednie ustawianie wyjść
  519.       for(int i = 1; i <= 8;i++){
  520.  
  521.         boolean stan = expander.digitalRead(i);
  522.         if(stan = 1){
  523.           //Jeśli któraś z wartości spadnie poza zakres tolerancji to wyłączam
  524.           if((temp[Czujka[i]] + 2) < TValue[i])
  525.           {
  526.             wlacz[i] = 0;           }
  527.  
  528.           if((huma[Czujka[i]] + 10) < HValue[i])
  529.           {
  530.             wlacz[i] = 0;           }
  531.  
  532.         }
  533.         //Jeśli przekroczy wartość zadaną uruchamiam wyjście
  534.         if(temp[Czujka[i]] > TValue[i]){
  535.             wlacz[i] = 1;
  536.          
  537.         }
  538.         //Jeśli przekroczy wartość zadaną uruchamiam wyjście
  539.         if(huma[Czujka[i]] > HValue[i]){
  540.            wlacz[i] = 1;
  541.          
  542.         }
  543.         //Właśiwe załączanie
  544.         if(wlacz[i] == 1){
  545.           expander.digitalWrite(i -1, LOW);//Sterowanie wyjściami LOW = WLACZONY (sterowanie masą)
  546.           //Serial.println("ON->");
  547.           //Serial.println(i);
  548.         }
  549.         else{
  550.           expander.digitalWrite(i -1, HIGH);
  551.           //Serial.println("OFF->");
  552.           // Serial.println(i);
  553.         }  
  554.       }
  555.  
  556.       Serial.println("END");
  557.     }
  558.     if(first){
  559.       first = 0;
  560.       lcd.clear();
  561.       lcd.print("Automat");
  562.       lcd.setCursor(0, 1);
  563.     }
  564.   }
  565.  
  566. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement