Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- TERMOSTAT V2.0
- Działa jak zwykły termostat tylko że:
- -Każde wyjście może mieć przypisaną własną czujkę, lub korzystać ze średniej wartości
- -Ilość przewidzianych czujek to 8.
- -Ilość przewidzianych wyjść to 8, ale lekko modyfikując kod i dodając odpowiednią ilość ekspanderów można uzyskać ich b.d ilość.
- (Gdyby użyć jeszę multiplekserów to ilość wyjść przekroczy pewnie każde wymagania)
- -Można podglądać wartości odbierane z czujek.
- -Można sterować manualnie (tryb automatyczny nie aktywny)
- -Wartości załączania ustawiamy z poziomu keypada podłączonego do arduino
- -Wsparcie dla wyświetlacza lcd (hd...) z konwerterem I2C oraz monitora portu szeregowego
- o
- Dodatkowo planujÄ™:
- -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.
- -Dodać krytyczną wartośc dla danej czujki która spowoduję wyłączenie wszystkich wyjść.
- -*Sterowanie wyjściami za pomocą SMS i wysyłanie danych na żądanie.
- -*Setrowanie z poziomu przeglÄ…darki
- * - Może kiedyś, ale nie w najbliższym czasie.
- Do podstawowego działania wymagane jest:
- -Jakieś arduino (ja użyłem UNO, ale finalnie planuję zapakować w nano)
- -Wyświetlacz z konwerterem I2C 2x16 (może być większy, polecam wtedy zmodyfikować kod aby czytelniej wyświetlał dane )
- -2 ekspandery pcf8574
- -Klawiatury 4x4
- -Czujnika temperatury i wilgotności (Domyślnie DHT22)
- -No i oczywiście zasilania 5V oraz przewody.
- Wykonał Michał Wysocki
- Stworzono 07.05.2017
- */
- #include <Wire.h>
- #include <Keypad_I2C.h>
- #include <Keypad.h>
- #include <LiquidCrystal_I2C.h>
- #include <LiquidCrystal_I2C.h>
- #include <EEPROM.h>
- #include <PCF.h>
- #include <dht.h>
- LiquidCrystal_I2C lcd(0x27,16,2);//Inicjacja wyświetlacza
- dht DHT;
- PCF expander;
- const byte ROWS = 4;
- const byte COLS = 4;
- char keys[ROWS][COLS] = {
- {
- '1', '2', '3', 'A' }
- ,
- {
- '4', '5', '6', 'B' }
- ,
- {
- '7', '8', '9', 'C' }
- ,
- {
- '*', '0', '#', 'D' }
- };
- byte rowPins[ROWS] = {
- 0, 1, 2, 3};
- byte colPins[COLS] = {
- 4, 5, 6, 7};
- int i2caddress = 0x38;//Inicjacja klawiatury
- Keypad_I2C kpd = Keypad_I2C( makeKeymap(keys), rowPins, colPins, ROWS, COLS, i2caddress );
- // KONIEC INICJALIZACJI
- int mode = 0 ;//Ustawia tryb
- int ekran;//Inaczej krok (pozostałości po inny pomyśle wyświetlania)
- //Zmienne konfiguracji
- int value;
- boolean TH;
- int PIN;
- int czujka;
- int dmuchanie;
- //ZMIENNE AUTOMATU;
- int TValue[9];//Temperatury załączania
- int HValue[9];
- int Czujka[9];//Która czujka odpowiada za jakie wyjście
- int temps;//Średnie wartośći
- int humas;
- long last;//Ostatni czas sprawdzania czujek
- long now;
- int temp[9];//Odczyty z czujek
- int huma[9];
- boolean wlacz[9];
- boolean first = 1;
- boolean update = 0;
- void setup() {
- // set up the LCD's number of columns and rows:
- lcd.init();
- lcd.backlight();
- // Print a message to the LCD.
- lcd.print("Termostat");
- lcd.setCursor(0, 1);
- lcd.print("V1.0");
- //KEYPAD
- Serial.begin(9600);
- kpd.begin();
- expander.begin(0x39);
- for(int i = 0; i <= 8; i++){
- expander.pinMode(i, OUTPUT);
- expander.digitalWrite(i,1);
- }
- pinMode(13, OUTPUT);
- pinMode(2, OUTPUT);
- Serial.print("Termostat1");
- for(int i = 0; i < 9; i++){
- wlacz[i]=0;
- Serial.println(i);
- //Reczny format ustawien
- // EEPROM.write(i,0);
- // EEPROM.write(i+10,0);
- // EEPROM.write(i+20,0);
- value = EEPROM.read(i+10);
- if (value >= 100){
- value = -value +100;
- }
- TValue[i] = value;
- value = EEPROM.read(i+20);
- if (value >= 100){
- value = -value +100;
- }
- HValue[i] = value;
- Czujka[i] = EEPROM.read(i);
- }
- Serial.print("Termostat2");
- }
- void loop() {
- char key = kpd.getKey();
- if (key && !first) {
- update = 0;
- lcd.clear();
- byte change = true;
- switch (key) {//Ustawianie trybów
- case 'A' :
- lcd.print("Automat");
- mode = 1;
- Serial.println(key);
- ekran = 1;//EKRAN = KROK POZOSTALOSCI PO CASE
- update = 1;
- break;
- case 'B' :
- lcd.print("Manual");
- mode = 2;
- Serial.println(key);
- ekran = 2;
- break;
- case 'C' :
- lcd.print("Setup");
- mode = 3;
- Serial.println(key);
- ekran = 3;
- break;
- case 'D' :
- lcd.print("Dane");
- mode = 4;
- Serial.println(key);
- ekran = 4;
- break;
- }
- //KONIEC USTAWIANIA TRYBÓW
- int Key = key - '0';
- switch (mode) {
- case 1 :
- { //JEÅšLI AUTOMAT
- switch(key){
- case 'A':
- break;
- default:
- lcd.print(Key);
- lcd.print(" TEMP->");
- lcd.print(temp[Key]);
- lcd.setCursor(0,1);
- lcd.print(Key);
- lcd.print("WILG->");
- lcd.print(huma[Key]);
- break;
- }
- }
- break;
- case 2 ://MANUAL
- {
- if((Key > 0 ) & (Key < 9) & (Key != 18)){
- expander.digitalWrite(Key -1, !expander.digitalRead(Key -1));
- ekran = 6;
- Serial.println(Key);
- if(expander.digitalRead(Key -1) == HIGH){
- lcd.print("WYLACZAM ");
- lcd.print(Key);
- }
- else{
- lcd.print("WLACZAM ");
- lcd.print(Key);
- }
- }
- else{
- if(Key != 18){
- lcd.print("POZA ZAKRESEM ");
- //Serial.println("POZA ZAKRESEM ");
- //Serial.println(Key);
- }
- }
- if (key == '*'){
- ekran = 7;
- int i = 0;
- while (i < 8){
- lcd.clear();
- lcd.print("Wylaczam");
- lcd.setCursor(0, 1);
- lcd.print(i);
- expander.digitalWrite(i, HIGH);
- Serial.print("SETING ");
- Serial.print(i);
- Serial.println(" HIGH");
- delay (1500);
- i++;
- }
- }
- if (key == '0'){
- ekran = 8;
- int i = 0;
- while (i < 8){
- lcd.clear();
- lcd.print("Zalczam");
- lcd.setCursor(0, 1);
- lcd.print(i);
- expander.digitalWrite(i, LOW);
- Serial.print("SETING ");
- Serial.print(i);
- Serial.println(" LOW");
- delay(1500);
- i++;
- }
- i = 0;
- while (i < 360){
- lcd.clear();
- lcd.print("Nadmuch czas.");
- delay(1000);
- lcd.setCursor(0, 1);
- lcd.print(i);
- lcd.print("sec");
- }
- ekran = 7;
- i = 0;
- while (i < 8){
- lcd.clear();
- lcd.print("Wylaczam");
- lcd.setCursor(0, 1);
- lcd.print(i);
- expander.digitalWrite(i, HIGH);
- Serial.print("SETING ");
- Serial.print(i);
- Serial.println(" HIGH");
- delay (1500);
- i++;
- }
- }
- if (key == '#'){
- ekran = 8;
- int i = 0;
- while (i < 8){
- lcd.clear();
- lcd.print("Zalczam");
- lcd.setCursor(0, 1);
- lcd.print(i);
- expander.digitalWrite(i, LOW);
- Serial.print("SETING ");
- Serial.print(i);
- Serial.println(" LOW");
- delay(1500);
- i++;
- }
- }
- }
- break;
- case 3:
- {
- switch (ekran)
- {
- case 3://Ustawianie wartości
- lcd.clear();
- lcd.print("PODAJ PIN");
- Serial.println("PODAJ PIN");
- ekran = 80;
- break;
- case 80:
- if((Key > 8) || (Key < 0)){
- lcd.print("POZA ZAKRESEM");
- Serial.println("POZA ZAKRESEM");
- }
- else{
- lcd.print("PIN =");
- lcd.print(Key);
- Serial.print("PIN = ");
- Serial.println(Key);
- PIN = Key;
- delay(500);
- Serial.println("TEMP/HUM");
- lcd.setCursor(0, 1);
- lcd.print("TEM/HUM");
- ekran = 81;
- }
- break;
- case 81:
- if(Key == 1){
- Serial.print("TEMPERATURA");
- TH = 0;
- value = TValue[PIN];
- ekran = 82;
- lcd.setCursor(0, 1);
- Serial.print("Wartosc:");
- lcd.print("TEMP WARTOSC");
- }
- else if (Key == 2){
- Serial.print("WILOGOTNOSC");
- TH = 1;
- value = HValue[PIN];
- Serial.print("Wartosc");
- ekran = 82;
- lcd.print("WILGO WATOSC");
- }
- break;
- case 82:
- switch(key) {
- case '1' :
- value++;
- Serial.print("WARTOSC= ");
- Serial.println(value);
- lcd.print("WARTOSC:");
- lcd.setCursor(0, 1);
- lcd.print(value);
- break;
- case '2' :
- value = value +5;
- Serial.print("WARTOSC= ");
- Serial.println(value);
- lcd.print("WARTOSC:");
- lcd.setCursor(0, 1);
- lcd.print(value);
- break;
- case '4' :
- value--;
- Serial.print("WARTOSC= ");
- Serial.println(value);
- lcd.print("WARTOSC:");
- lcd.setCursor(0, 1);
- lcd.print(value);
- break;
- case '5' :
- value = value - 5;
- Serial.print("WARTOSC= ");
- Serial.println(value);
- lcd.print("WARTOSC:");
- lcd.setCursor(0, 1);
- lcd.print(value);
- break;
- case '#' :
- ekran = 83;
- Serial.println("CZUJKA->");
- lcd.print("CZUJKA->");
- break;
- }
- //KONTROLA
- if(value > 99){
- value = 99;
- ekran = 82;
- Serial.print("MAX");
- Serial.println(value);
- lcd.print("MAX:");
- lcd.setCursor(0, 1);
- lcd.print(value);
- }
- else if (value < -99) {
- value = -99;
- ekran = 82;
- Serial.print("MIN");
- Serial.println(value);
- lcd.print("MIN:");
- lcd.setCursor(0, 1);
- lcd.print(value);
- }
- break;
- case 83:
- if((Key > 8) || (Key < 0)){
- Serial.println("POZA ZAKRESEM");
- lcd.print("POZA ZAKRESEM");
- }
- else{
- lcd.print("Czujka = ");
- lcd.print(Key);
- Serial.print("CZUJKA = ");
- Serial.println(Key);
- czujka = Key;
- ekran = 84;
- }
- break;
- case 84:
- if (TH == 0){
- lcd.print("PIN=");
- lcd.print(PIN);
- lcd.print(" TEMP>");
- lcd.print(value);
- lcd.setCursor(0, 1);
- lcd.print("Czujka");
- lcd.print(czujka);
- Serial.print("Zalaczam PIN ");
- Serial.println(PIN);
- Serial.print("Dla temperatury wyzszej niz ");
- Serial.println(value);
- Serial.print("Czujka zalaczajaca ");
- Serial.println(czujka);
- TValue[PIN]= value;
- Czujka[PIN]= czujka;
- if(value >= 0){
- EEPROM.write(PIN+10, value);
- }
- else {
- value = -value +100;
- EEPROM.write(PIN+10, value);
- }
- EEPROM.write(PIN, czujka);
- }
- else {
- lcd.print("PIN=");
- lcd.print(PIN);
- lcd.print(" WILGO>");
- lcd.print(value);
- lcd.setCursor(0, 1);
- lcd.print("Czujka");
- lcd.print(czujka);
- Serial.print("Zalaczam PIN ");
- Serial.println(PIN);
- Serial.print("Dla wilgotnosci wyzszej niz ");
- Serial.println(value);
- Serial.print("Czujka zalaczajaca ");
- Serial.println(czujka);
- HValue[PIN]= value;
- Czujka[PIN]= czujka;
- if(value >= 0){
- EEPROM.write(PIN+20, value);
- }
- else {
- value = -value +100;
- EEPROM.write(PIN+20, value);
- }
- EEPROM.write(PIN, czujka);
- }
- ekran = 85;
- break;
- }
- }
- break;
- case 4:
- {//Wyświetlanie ustawień
- switch (Key){
- case -6:
- lcd.print(" NIEDOSTEPNE");
- for(int i = 1; i < 9; i++)
- {
- Serial.print(TValue[i]);
- Serial.print("<-TEMP |");
- Serial.print("| WILGO ->");
- Serial.println(HValue[i]);
- }
- break;
- case 20:
- break;
- default:
- if((Key > 8) || (Key < 0) && (Key != 20)){
- if(Key == 9){
- lcd.print(" TEMP->");
- lcd.print(temp[0]);
- lcd.setCursor(0, 1);
- lcd.print(" HUMA->");
- lcd.println(huma[0]);
- }
- else{
- Serial.println("POZA ZAKRESEM");
- lcd.print("POZA ZAKRESEM");
- }
- }
- else {
- lcd.print(Key);
- lcd.print(" TEMP ->");
- lcd.print(TValue[Key]);
- lcd.setCursor(0, 1);
- lcd.print(Czujka[Key]);
- lcd.print(" WILGO ->");
- lcd.print(HValue[Key]);
- Serial.print(TValue[Key]);
- Serial.print("<-TEMP |");
- Serial.print(Czujka[Key]);
- Serial.print("| WILGO ->");
- Serial.println(HValue[Key]);
- }
- break;
- }
- break;
- }
- }
- }
- now = millis();//Automat
- // Wykonuje zadanie co pewien czas
- if ( ( (now % 10000) < 10) && ( (now - last) > 200) ) {
- Serial.println("Lapie");
- digitalWrite(13,!digitalRead(13));
- last = now;
- int b=0;
- int tsv =0;
- int hsv =0;
- for(int i = 0; i < 9;i++){
- temp[i] = -200;
- huma[i] = -200;
- }
- for(int i = 1; i <= 8;i++){
- int temperatura;
- int chk = DHT.read22(i+2);//PIN poczÄ…tkowy = 3
- if(!((chk == DHTLIB_ERROR_CHECKSUM) || (chk == DHTLIB_ERROR_TIMEOUT))){
- b++;
- temperatura = DHT.temperature;
- int err_T = temp[i] - temperatura;// Wykrywanie błędów zabużeń w pracy czujki
- err_T = abs(err_T);
- if(err_T < 5 or temp[i] == -200){
- Serial.print("Odczyt poprawny T");
- temp[i] = temperatura;
- }
- else{
- Serial.println("Blad odczytu Temp");
- }
- int err_H = huma[i] - DHT.humidity;// Wykrywanie błędów zabużeń w pracy czujki
- err_H = abs(err_H);
- if(err_H < 5 or huma[i] == -200){
- huma[i] = DHT.humidity;
- Serial.println("Odczyt poprawny W");
- }
- else{
- Serial.println("Blad odczytu Wilgo");
- }
- tsv = tsv + temp[i];
- hsv = hsv + huma[i];
- Serial.print("WYKRYTO CZUJKE PIN->");
- Serial.print(i);
- Serial.print(" TEMP->");
- Serial.print(temp[i]);
- Serial.print(" HUMA->");
- Serial.println(huma[i]);
- Serial.print(" hsv->");
- Serial.println(hsv);
- }
- }
- tsv = tsv/b;
- hsv = hsv/b;
- //Czujka zero ma być zawsze średnią
- for(int i = 0; i <= 8;i++){
- if(temp[i] < -150){
- temp[i] = tsv;
- huma[i] = hsv;
- }
- }
- //Uzywane do sprawdzania czujek
- // for(int i = 0; i <= 8;i++){
- // Serial.print(temp[i]);
- // Serial.print("<-TEMP|");
- // Serial.print(i);
- // Serial.print("|huma->");
- // Serial.println(huma[i]);
- //
- // }
- if(mode != 2){//Odpowiednie ustawianie wyjść
- for(int i = 1; i <= 8;i++){
- boolean stan = expander.digitalRead(i);
- if(stan = 1){
- //Jeśli któraś z wartości spadnie poza zakres tolerancji to wyłączam
- if((temp[Czujka[i]] + 1) <= TValue[i])
- {
- wlacz[i] = 0;
- Serial.print("wylaczam->");
- Serial.println(i);
- }
- //if((huma[Czujka[i]] + 10) < HValue[i])
- //{
- // wlacz[i] = 0;
- //}
- }
- //Jeśli przekroczy wartość zadaną uruchamiam wyjście
- if(temp[Czujka[i]] > TValue[i]){
- wlacz[i] = 1;
- Serial.print(i);
- Serial.print("->");
- Serial.print(temp[Czujka[i]]);
- Serial.print(">");
- Serial.println(TValue[i]);
- }
- //Jeśli przekroczy wartość zadaną uruchamiam wyjście
- if(huma[Czujka[i]] > HValue[i]){
- //wlacz[i] == 1;
- //Serial.print(huma[Czujka[i]]);
- //Serial.print(">");
- //Serial.println(HValue[i]);
- }
- //Właśiwe załączanie
- if(wlacz[i] == 1){
- expander.digitalWrite(i -1, LOW);//Sterowanie wyjściami LOW = WLACZONY (sterowanie masą)
- Serial.print("ON->");
- Serial.println(i);
- }
- else{
- expander.digitalWrite(i -1, HIGH);
- Serial.print("OFF->");
- Serial.println(i);
- }
- if(update){
- lcd.clear();
- lcd.print("Automat");
- lcd.setCursor(0, 1);
- lcd.print("temp->");
- lcd.print(temp[0]);
- }
- }
- Serial.println("END");
- }
- if(first){
- update = 1;
- mode = 1;
- first = 0;
- lcd.clear();
- lcd.print("Automat");
- lcd.setCursor(0, 1);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement