/********************************************************************* Работа с газовыми сенсорами для управления открытием и закрытием окна в зависимости от загрязнения атмосферы **********************************************************************/ #include //библиотека для дисплея #include //библиотека для дисплея #include //библиотека для датчика температуры и влажности //------------------- String inputString = ""; // строка для приема данных от компьютера int invar1; // данные с компьютера int invar2; // данные с компьютера char bufstr[10]; // массив для передачи данных в компьютер //------------------- #if defined(ARDUINO) && ARDUINO >= 100 #define printByte(args) write(args); #else #define printByte(args) print(args,BYTE); #endif //----массивы символов для дисплея------------ uint8_t heart[8] = {0x0, 0xa, 0x1f, 0x1f, 0xe, 0x4, 0x0}; //сердечко uint8_t celc[8] = {0xc, 0x12, 0x12, 0xc, 0x0, 0x0, 0x0}; //цельсия //-------------------------------------------- LiquidCrystal_I2C lcd(0x27, 16, 2); // установить адрес для дисплея 0x27 (16 символов и 2 строки dht11 DHT11; #define DHT11PIN 2 //pin 2 для снятия отсчета с датчика String instring = ""; int sensorValue0 = A0; int sensorValue1 = A1; int sensorTermo = A3; int Value0 = 0; int Value1 = 0; int Val_cikl = 0; //******изменяемые параметры************** int Value0_max = 40; //красная зона int Value0_min = 30; //желтая зона int Value1_max = 90; //красная зона int Value1_min = 75; //желтая зона int time_open = 5; //время открытия окна сек. int period = 300; //частота отсчетов //**************************************** boolean window_open = true; int open_level = 20; int ledState = LOW; int count_opencom = 16; //время полного открытия окна //**************************************************** int buf_int; //временный буфер //**************** void setup() { Serial.begin(9600); pinMode(DHT11PIN, INPUT); //установить 2 ножку на ввод DDRD = B01100000; //установить 5 и 6 ноги на вывод //pinMode(window_on, OUTPUT); lcd.init(); // initialize the lcd lcd.backlight(); lcd.createChar(3, heart); //записать матрицу символа сердечко lcd.createChar(4, celc); //записать матрицу символа градус lcd.home(); //Перемещает курсор в левый верхний угол экрана. lcd.print("This programm by"); lcd.setCursor(0, 1); //перевести курсор на вторую строку lcd.print("Ruben Lachinov "); lcd.printByte(3); //сердечко //---передача настроек в компьютер--- save_info(); } void loop() { if (ledState == LOW) { //частота преобразований 13 ledState = HIGH; PORTB = PORTB | B00100000; } else { ledState = LOW; PORTB = PORTB & B11011111; } //============================= int chk = DHT11.read(DHT11PIN); //снять информацию с сенсора DHT11 //============================= Value0 = Value0 + analogRead(A0); delay(10); Value1 = Value1 + analogRead(A1); delay(10); Val_cikl = Val_cikl + 1; if (Val_cikl == 8) { Val_cikl = 0; // lcd.clear(); Value0 = Value0 / 8; Value1 = Value1 / 8; //получили усредненное значение после 8ми измерений if (window_open == true and Value0 >= Value0_max) { //закрыть окно win_open(-1, 16, 0); //count_opencom); } else if (window_open == false and Value0 <= Value0_min) { //открыть окно win_open(1, time_open, 0); //count_opencom); } else if (Value1 >= Value1_max and Value0 <= Value0_min and count_opencom < 16) { //приоткрыть окно win_open(1, 1, 0); } instring = "@f"; instring += Value0, DEC; Serial.println(instring); delay(1); instring = "@s"; instring += Value1, DEC; Serial.println(instring); //****************** LCD **************** lcd.clear(); lcd.setCursor(0, 0); lcd.print("C="); lcd.print((float)DHT11.temperature, 0); lcd.printByte(4); //цельсия lcd.print(" H="); lcd.print((float)DHT11.humidity, 0); lcd.print("%"); lcd.setCursor(0, 1); lcd.print(" "); lcd.print(Value0, DEC); lcd.print(" // "); lcd.print(Value1, DEC); instring = "@t"; instring += (float)DHT11.temperature; Serial.println(instring); instring = "@h"; instring += (float)DHT11.humidity; Serial.println(instring); Value0 = 0; Value1 = 0; } delay(period); // delay in between reads for stability } void serialEvent() { while (Serial.available()) { char inChar = (char)Serial.read(); // принять новый байт: inputString += inChar; // добавить в inputString: if (inChar == ';') { // признак конца сообщения decoder(); // расшифровать послание inputString = ""; //очистить строку break; //выйти из цикла } } inputString = ""; } void decoder() { int vvv = firstkey(inputString); //============================== switch (vvv) { case 1: //канал A0 - установка границ Value0_max = invar1; //красная зона Value0_min = invar2; //желтая зона break; case 2: //канал A1 - установка границ Value1_max = invar1; //красная зона Value1_min = invar2; //желтая зона break; case 3: //открыть/закрыть окно win_open(invar1, invar2, 1); break; case 4: //время открытия time_open = invar1; break; case 5: //период period = invar1; break; case 6: //передать установки в компьютер save_info(); break; case 7: break;//резерв default: invar2 = 2; } } int firstkey(String buf_str) { int result; String str1 = buf_str; int lenstr = str1.length(); str1.remove(2, lenstr - 2); //оставили первые два сивола if (str1 == "%a") result = 1; else //канал A0 - 2 параметра if (str1 == "%b") result = 2; else //канал A1 - 2 параметра if (str1 == "%w") result = 3; else //открыть/закрыть окно if (str1 == "%t") result = 4; else //время открытия if (str1 == "%p") result = 5; else //период опроса датчиков if (str1 == "%i") result = 6; else //передать установки в компьютер if (str1 == "%r") result = 7; else //резерв result = 0; //=== if (result != 0) { //есть данные - выделение параметров. buf_str.remove(0, 2); //удалили первые два символа str1 = buf_str; int buf_int = str1.indexOf(","); int lenstr = str1.length(); str1.remove(buf_int, lenstr); invar1 = str1.toInt(); str1 = buf_str; //принятая строка без первых 2х символов buf_int = str1.indexOf(","); str1.remove(0, buf_int + 1); //удалить все до запятой buf_int = str1.indexOf(";"); lenstr = str1.length(); str1.remove(buf_int, lenstr); invar2 = str1.toInt(); } return result; } void win_open(int win_com, int win_time, int key_in) { switch (win_com) { case 0: //снять напряжение PORTD = PORTD & B10011111; //сброс 5 и 6 ножки break; case 1: //открыть окно PORTD = PORTD & B10011111; //сброс 5 и 6 ножки PORTD = PORTD | B00100000; //сигнал на 5 ногу - открыть окно if (key_in == 0) window_open = true; //иначе без изменения флага открытого окна count_opencom = count_opencom + win_time; if (count_opencom > 16 ) count_opencom = 16; break; case -1: //закрыть окно PORTD = PORTD & B10011111; //сброс 5 и 6 ножки PORTD = PORTD | B01000000; //сигнал на 6 ногу - закрыть окно if (key_in == 0) window_open = false; count_opencom = count_opencom - win_time; if (count_opencom < 0 ) count_opencom = 0; break; } delay(win_time * 1000); PORTD = PORTD & B10011111; //сброс 5 и 6 ножки open_level = open_level + win_com * win_time * 10; //10 * кол-во секунд if (open_level < 0 ) open_level = 0; instring = "@w"; instring += String(open_level); instring += ","; instring += String(count_opencom); Serial.println(instring); //установить на компьютере индикатор открытого окна } void save_info(void) { save_date("@a", Value0_max, Value0_min);//формирование строки с параметрами первого канала //"@a" - префикс первого канала, Value0_max - граница красной зоны,Value0_min - граница желтой зоны save_date("@b", Value1_max, Value1_min); save_date("@w", open_level, count_opencom); save_date("@v", time_open, 0); save_date("@p", period, 0); } void save_date(String prefics, int par1, int par2) { instring = prefics; // instring = "@a"; //префикс первого канала instring += par1, DEC; //instring += Value0_max, DEC; //граница красной зоны if (par2 != 0) { instring += ","; //разделитель значений instring += par2, DEC; //instring += Value0_min, DEC; //граница желтой зоны } Serial.println(instring); //передать в компьютер delay(10); }