Делаем умный холодильник часть 1.
Сдохший холодильник навеял на прямое использование ардуино.
Ну и тут понеслось…
И так, что нам понадобится:
ЦПУ. он же arduino (pro mini 5v.) 2 датчика температуры DHT22 Реле пусковое для компрессора. Реле затвора верхней камеры. Провода.
Остальное читаем дальше…
Вводная информация по пинам:
2 — Кнопка вверх
3 — Кнопка вниз
4 — Первый датчик DHT22 (верхняя камера)
5 — Второй датчик DHT22 (морозилка)
6 — реле компрессора
7 — биппер
9 — Кнопка меню
10 — не используется но в коде имеется бывшая кнопка вверх, теперь на прерываниях pin -2
11 — не используется но в коде имеется бывшая кнопка вниз, теперь на прерываниях pin — 3
12 — Кнопка SET
13 — индикатор работы программы
Скетч для нашего проекта:
#include "DHT.h" #include#define DHTTYPE DHT22 // тип DHT -> 22 #define DHT_UP_PIN 4 // Пин верхнего температурного датчика #define DHT_DOWN_PIN 5 // Пин нижнего температурного датчика #define PUMP_PIN 6 // Пин управления реле компрессора #define MENU_PIN 9 // Buttons menu #define TEMP_UP_PIN 10 // Button up #define TEMP_DOWN_PIN 11 // button down #define SET_PIN 12 // Button set #define OPERATE_PIN 13 // Button set #define BEEP_PIN 7 // Button set int select_camera = 0; // default 0 down camera (1 up camera) int new_up_temp = 0; // default new temperature int new_down_temp = 0; // default new temperature boolean menu = false; boolean pump = false; boolean serial = false; int target_temp_up; int target_temp_down; int up_trigger; int down_trigger; DHT dht_up(DHT_UP_PIN, DHTTYPE); // Создаем объект датчик 1 DHT dht_down(DHT_DOWN_PIN, DHTTYPE); // Создаем объект датчик 2 int EET_UP; // переменная температур для верхней камеры int EET_DOWN; // переменная температур для нижней камеры int EET_UP_TRIGGER; //триггер отрицательной температуры верхней камеры int EET_DOWN_TRIGGER; //триггер отрицательной температуры нижней камеры void setup(void) { pinMode(BEEP_PIN, OUTPUT); // beeper pinMode(MENU_PIN, INPUT); // Кнопка (menu) pinMode(TEMP_UP_PIN, INPUT); // Кнопка (up) pinMode(TEMP_DOWN_PIN, INPUT); // Кнопка (down) pinMode(SET_PIN, INPUT); // Кнопка (set) attachInterrupt(0,up,RISING); // digital pin 2 // up attachInterrupt(1,down,RISING); // digital pin 3 // down //interrupts mode: //LOW to trigger the interrupt whenever the pin is low, //CHANGE to trigger the interrupt whenever the pin changes value //RISING to trigger when the pin goes from low to high, //FALLING for when the pin goes from high to low. //pinMode(MENU_PIN, INPUT_PULLUP); //pinMode(TEMP_UP_PIN, INPUT_PULLUP); //pinMode(TEMP_DOWN_PIN, INPUT_PULLUP); //pinMode(SET_PIN, INPUT_PULLUP); digitalWrite(MENU_PIN, HIGH); //resistor pull-up //digitalWrite(TEMP_UP_PIN, HIGH); //resistor pull-up //digitalWrite(TEMP_DOWN_PIN, HIGH); //resistor pull-up digitalWrite(SET_PIN, HIGH); //resistor pull-up pinMode(PUMP_PIN, OUTPUT); // определяем пин компрессора pinMode(OPERATE_PIN, OUTPUT); // определяем пин для статуса мигалки if(serial == true){ Serial.begin(115200); //com port } dht_up.begin(); // DHT init ... dht_down.begin(); // DHT init ... digitalWrite(PUMP_PIN, HIGH); // предварительно отключаем компрессор if(serial == true){ Serial.println("Refrigerator started..."); } } void loop(void) { EET_UP = EEPROM.read(1); // address[1] температура из eeprom (верхняя камера) EET_DOWN = EEPROM.read(2); // address[2] температура eeprom (морозилка) EET_UP_TRIGGER = EEPROM.read(3); // Триггер отрицательной температуры (верхняя камера) [1 - (minus)] [0 +] EET_DOWN_TRIGGER = EEPROM.read(4); // Триггер отрицательной температуры (морозилка) [1 - (minus)] [0 +] float ha = dht_up.readHumidity(); // Считываем влажность датчика 1 float hb = dht_down.readHumidity(); // Считываем влажность датчика 2 float ta = dht_up.readTemperature(); // Считываем температуру датчика 1 float tb = dht_down.readTemperature(); // Считываем температуру датчика 2 if(serial == true){ Serial.println("=========================================================================="); } if(serial == true){ if (isnan(ha) || isnan(hb)) { Serial.println("Failed to read from DHT Humidity"); } if (isnan(ta) || isnan(tb)) { Serial.println("Failed to read from DHT Temperature"); } } // set all to int int curr_up_temp = (int) ta; // конвертим float to int int curr_down_temp = (int) tb; // конвертим float to int int up_delta_on = 2; // Пределы расхождений верхней камеры для включения (ON) int up_delta_off = 1; // Пределы расхождений верхней камеры для отключения (OFF) int down_delta_on = 5; // Пределы расхождений морозилки для включения (ON) int down_delta_off = 2; // Пределы расхождений морозилки для отключения (OFF) int corr_temp_up = neg(EET_UP, EET_UP_TRIGGER); // определяем отрицательные температуры из триггеров (верхняя камера) int corr_temp_down = neg(EET_DOWN, EET_DOWN_TRIGGER); // определяем отрицательные температуры из триггеров (морозилка) int float_temp_down_on = corr_temp_down + down_delta_on; // плавающее значение включения (-10) + delta-on (5) = (-5) = включение int float_temp_down_off = corr_temp_down - down_delta_off; // плавающее значение выключения (-10) - delta-off (2) = (-12) = выключение if(serial == true){ //Serial.print("EE Current state Address Up: "); //Serial.println(EET_UP); //Serial.print("EE Current state Address Down: "); //Serial.println(EET_DOWN); //Serial.print("EE Up temperature is negative: "); //Serial.println(EET_UP_TRIGGER); //Serial.print("EE Down temperature is negative: "); //Serial.println(EET_DOWN_TRIGGER); Serial.print("Target temperature [up camera]: "); Serial.print(corr_temp_up); Serial.print(" [down camera]: "); Serial.println(corr_temp_down); Serial.print("Current temperature [up camera]: "); Serial.print(curr_up_temp); Serial.print(" [down camera]: "); Serial.println(curr_down_temp); Serial.print("Compressor state: "); Serial.println(pump); Serial.print("Float temperature ON: "); Serial.print(float_temp_down_off); Serial.print(" OFF: "); Serial.println(float_temp_down_on); } if(curr_down_temp >= float_temp_down_on && pump == false){ // если текущая температура выше или равна плавающей температуре включения и компрессор выключен if(serial == true){ Serial.println(">>>>>>>>>>> Compressor is ON <<<<<<<<<<<<"); } digitalWrite(PUMP_PIN, LOW); // включаем компрессор pump = true; //запоминаем, что компрессор включился } if(curr_down_temp <= float_temp_down_off && pump == true){ // если текущая температура меньше или равна плавающей температуре отключения и компрессор включен if(serial == true){ Serial.println(">>>>>>>>>>> Compressor is OFF <<<<<<<<<<<<"); } digitalWrite(PUMP_PIN, HIGH); // льключаем компрессор pump = false; // запоминаем что компрессор выключен } //unfrezzzzzz режим разморозки. mainmenu(); // меню установок температур blinkLED(OPERATE_PIN); // помигиваем лампочкой что процессор работает } int mainmenu(){ if(menu == true){ if(serial == true){ Serial.print("Menu >>> selected [0 - down camera | 1 - up camera]: "); Serial.println(select_camera); Serial.print("New temperature >>> Up camera: "); Serial.print(new_up_temp); Serial.print(" Down camera: "); Serial.println(new_down_temp); } } int MENU_PIN_val = digitalRead(MENU_PIN); int TEMP_UP_PIN_val = digitalRead(TEMP_UP_PIN); int TEMP_DOWN_PIN_val = digitalRead(TEMP_DOWN_PIN); int SET_PIN_val = digitalRead(SET_PIN); //Serial.println(MENU_PIN_val, DEC); //Serial.println(TEMP_UP_PIN_val, DEC); //Serial.println(TEMP_DOWN_PIN_val, DEC); //Serial.println(SET_PIN_val, DEC); if (MENU_PIN_val == 0){ // нажатие кнопки меню if(serial == true){ Serial.println("Enter menu"); } menu = true; // запоминаем вход в меню beep(100); } if (MENU_PIN_val == 0 && menu == true){ // нажитие на кнопку меню if(select_camera == 1){ select_camera = 0; // select down camera }else{ select_camera = 1; // select up camera } beep(100); if(serial == true){ Serial.print("Setup temperature [0 - down camera | 1 - up camera]:"); Serial.println(select_camera); } } // обработка установок для верхней камеры (move to interrupts) /* if (TEMP_UP_PIN_val == 0 && menu == true && select_camera == 1){ // нажали кнопку + beep(50); new_up_temp++; // новая температура if(serial == true){ Serial.print("Temperature [up camera] (+): "); Serial.println(new_up_temp); } } if (TEMP_DOWN_PIN_val == 0 && menu == true && select_camera == 1){ // нажали кнопку - beep(50); new_up_temp--; // новая температура if(serial == true){ Serial.print("Temperature [up camera] (-): "); Serial.println(new_up_temp); } } // обработка установок для морозилки if (TEMP_UP_PIN_val == 0 && menu == true && select_camera == 0){ // нажали кнопку + beep(50); new_down_temp++; // новая температура if(serial == true){ Serial.print("Temperature [down camera] (+): "); Serial.println(new_down_temp); } } if (TEMP_DOWN_PIN_val == 0 && menu == true && select_camera == 0){ // нажали кнопку - beep(50); new_down_temp--; // новая температура if(serial == true){ Serial.print("Temperature [down camera] (-): "); Serial.println(new_down_temp); } } */ if (SET_PIN_val == 0 && menu == true){ // нажали кнопку "сет" // ================================================================================== if (new_up_temp != 0){ // если есть установки новой температуры для верхней камеры if(new_up_temp < 0){ up_trigger = 1; // температура ниже 0 target_temp_up = 0 - (new_up_temp); }else{ up_trigger = 0; // температура выше 0 target_temp_up = new_up_temp; } EEPROM.write(1, target_temp_up); EEPROM.write(3, up_trigger); new_up_temp = 0; //обнуляем if(serial == true){ Serial.print("Saved [up camera] setting up: "); Serial.println(target_temp_up); Serial.print("Triggered:"); Serial.println(up_trigger); } } // ================================================================================== if (new_down_temp != 0){ // если есть установки новой температуры для морозилки if(new_down_temp < 0){ down_trigger = 1; // температура ниже 0 target_temp_down = 0 - (new_down_temp); }else{ down_trigger = 0; // температура выше 0 target_temp_down = new_down_temp; } EEPROM.write(2, target_temp_down); EEPROM.write(4, down_trigger); new_down_temp = 0; //обнуляем if(serial == true){ Serial.print("Saved [down camera] setting up: "); Serial.println(target_temp_down); Serial.print("Triggered:"); Serial.println(down_trigger); } } // ================================================================================== menu = false; // exit menu beep(100); if(serial == true){ Serial.println("Exit menu"); } } } // функция преобразования в отрицательное число int neg(int temp, int trigger){ int result; if(trigger == 1){ result = 0 - temp; } else { result = temp; } return result; } // пищалка int beep(unsigned char delayms){ analogWrite(BEEP_PIN, 200); delay(delayms); analogWrite(BEEP_PIN, 0); delay(delayms); } // процессинг int blinkLED(int count) { digitalWrite(13, HIGH); delay(10); digitalWrite(13, LOW); delay(10); } //прерывания кнопка вверх void up() { if (menu == true && select_camera == 1){ // нажали кнопку + beep(50); new_up_temp++; // новая температура if(serial == true){ Serial.print("Temperature [up camera] (+): "); Serial.println(new_up_temp); } } // обработка установок для морозилки if (menu == true && select_camera == 0){ // нажали кнопку + beep(50); new_down_temp++; // новая температура if(serial == true){ Serial.print("Temperature [down camera] (+): "); Serial.println(new_down_temp); } } delay(150); } //прерывания кнопка вниз void down() { if (menu == true && select_camera == 1){ // нажали кнопку - beep(50); new_up_temp--; // новая температура if(serial == true){ Serial.print("Temperature [up camera] (-): "); Serial.println(new_up_temp); } } if (menu == true && select_camera == 0){ // нажали кнопку - beep(50); new_down_temp--; // новая температура if(serial == true){ Serial.print("Temperature [down camera] (-): "); Serial.println(new_down_temp); } } delay(150); }
Все вливается в ардуинку, подключается все согласно пинам, и вколачивается в холодильник.
Данные температур сохраняются в EEPROM и хранятся там.
ЗЫ: в задумках реализация вывода на дисплей.