Купил как-то на алиэкспресс осушитель воздуха LAQVLA (1 литр). Но вот у этого агрегата нет никакого контроля за влажностью воздуха и следовательно нет возможности автоматически отключать осушитель если воздух уже достиг необходимой сухости. Я решил устранить этот недостаток. У осушителя изначально было два режима – непосредственно рабочий режим и режим блокировки при заполнении контейнера водой.
Для осуществления проекта, выбран в качестве блока управления Arduino Nano (в силу небольших размеров платы). Так-же в качестве измерителя влажности и температуры выбран датчик DHT-11 и экран TFT IPS 240x240.
Код для ардуино, блока автоматического управления осушителем.
#include <Adafruit_GFX.h> // Базовая графическая библиотека от Adafruit #include <Arduino_ST7789.h> // Аппаратно-зависимая библиотека для ST7789 (с выводом CS или без него) #include <SPI.h> #include "DHT.h" #define rezhim 4 // пин кнопка Режим #define pusk 10 // пин кнопка Пуск (имитирует нажатие) #define work 12 // пин рабочий режим (зелёный светодиод) #define block 5 // пин блокировка (жёлтый светодиод)при заполнении контейнера водой #define DHTPIN 9 // пин датчик температуры и влажности DHT dht(DHTPIN, DHT11); // Инициация датчика #define TFT_DC 7 #define TFT_RST 6 #define TFT_CS 5 // только для дисплеев с выводом CS #define TFT_MOSI 11 // для вывода данных аппаратного SPI #define TFT_SCLK 13 // для аппаратного вывода SPI sclk // Вы можете использовать другой тип инициализации оборудования // с использованием аппаратного SPI (11, 13 на UNO; 51, 52 на MEGA; ICSP-4, ICSP-3 на DUE и т. д.) Arduino_ST7789 tft = Arduino_ST7789 (TFT_DC, TFT_RST); // для отображения без вывода CS // Arduino_ST7789 tft = Arduino_ST7789 (TFT_DC, TFT_RST, TFT_CS); // для отображения с выводом CS // или вы можете использовать программный SPI на всех доступных выводах (работает медленно) // Arduino_ST7789 tft = Arduino_ST7789 (TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK); // для отображения без вывода CS // Arduino_ST7789 tft = Arduino_ST7789 (TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK, TFT_CS); // для отображения с выводом CS // Arduino_ST7789 tft = Arduino_ST7789 (-1, TFT_RST, TFT_MOSI, TFT_SCLK, TFT_CS); // для отображения с выводом CS и DC через 9-битный SPI boolean buttonState = HIGH; // Зададим некую переменную и изначально присвоим ей нулевое значение (присвоим низкий уровень) boolean lastButton = HIGH; // Хранит состояние предыдущего нажатия int h; // переменная влажности int h1 = 0; // предидущее значение переменной влажности int t; // переменная температуры int t1 = 0; // предидущее значение переменной температуры int rezhim_kn = 0; // переменная состояния Режим boolean pusk_st = HIGH; // пременная кнопки Пуск (имитация нажатия) исходное состояние 1, срабатывание 0 boolean work_sv; // состояние режима Работа (зелёный светодиод) boolean work_sv1; // предидущее значение режима Работа boolean block_sv; // состояние режима Блокировка (жёлтый светодиод) uint32_t myTimer1; // Таймер очистки экрана uint32_t myTimer2; // Таймер задержки для термодатчика void setup() { Serial.begin(9600); tft.init(240, 240); // инициализировать чип ST7789, 240x240 пикселей dht.begin(); tft.fillScreen(BLACK); tft.drawChar(35, 100, 'L', 255, 0, 5), tft.drawChar(65, 100, 'A', 255, 0, 5), tft.drawChar(95, 100, 'U', 255, 0, 5), tft.drawChar(125, 100, 'N', 255, 0, 5), tft.drawChar(155, 100, 'C', 255, 0, 5), tft.drawChar(185, 100, 'H', 255, 0, 5), delay(2000); tft.fillScreen(BLACK); pinMode(rezhim,INPUT); pinMode(work,INPUT); pinMode(block,INPUT); pinMode(pusk,OUTPUT); } // функция для подавления дребезга кнопки Режим boolean debounce(boolean last) { boolean current = digitalRead(rezhim); if(last != current) { delay(5); current = digitalRead(rezhim); } return current; } void loop() { if (millis() - myTimer1 >= 120000) { // ищем разницу (120 сек) myTimer1 = millis(); // сброс таймера tft.fillScreen(BLACK); // Сброс экрана каждые 60 сек } if (millis() - myTimer2 >= 2000) { // ищем разницу (2 сек) myTimer1 = millis(); // сброс таймера h = dht.readHumidity(); //Измеряем влажность t = dht.readTemperature(); //Измеряем температуру if (isnan(h) || isnan(t)) { // Проверка. Если не удается считать показания, выводится «Ошибка считывания», // и программа завершает работу //Serial.println("Ошибка считывания"); tft.fillScreen(BLACK); tft.drawChar(25, 100, 'A', RED, 0, 5), tft.drawChar(55, 100, 'L', RED, 0, 5), tft.drawChar(85, 100, 'A', RED, 0, 5), tft.drawChar(115, 100, 'R', RED, 0, 5), tft.drawChar(145, 100, 'M', RED, 0, 5), delay(5000); return; } } digitalWrite(pusk,HIGH); // Выводим надпись Работа или Стоп охладителя. if (work_sv != work_sv1) tft.fillScreen(BLACK); work_sv1 = work_sv; if (work_sv == LOW) { tft.setCursor(25,60); // Позиционируем курсор на экране tft.setTextColor(BLUE); // Задаём цвет текста tft.setTextSize(4); // Задаём размер текста tft.print("WORK"); } else { tft.setCursor(25,60); // Позиционируем курсор на экране tft.setTextColor(BLUE); // Задаём цвет текста tft.setTextSize(4); // Задаём размер текста tft.print("STOP"); } // Выводим значение Влажности и Температуры на экран. if (h != h1 || t != t1) tft.fillRect(155,120 ,240, 150, BLACK); tft.setCursor(5,120); // Позиционируем курсор на экране tft.setTextColor(GREEN); // Задаём цвет текста tft.setTextSize(4); // Задаём размер текста tft.print(" HUM.="); // Выводим надпись "hum.=" на экран в заданной позиции tft.setTextColor(GREEN); tft.setCursor(155,120); tft.print(h); // Выводим значение Влажности tft.print("% "); // Выводим надпись "%" с последующим переводом курсора на следующую строку h1 = h; tft.setCursor(5,185); tft.print(" TEM.="); tft.setCursor(155,185); tft.print(t); // Выводим значение температуры tft.print("C"); t1 = t; // Чтение портов состояния режимов работы work_sv = digitalRead(work); // Чтение состояния Вкл или Откл осушителя. block_sv = digitalRead(block); // Чтение состояния блокировки (заполнен контейнер). // Чтение нажатия кнопки Режим с использованием функции для подавления дребезга кнопки. buttonState = debounce(lastButton); if (lastButton == HIGH && buttonState == LOW){ // Срабатывает если предидущее состояние HIGH, // а действующее состояние LOW tft.fillRect(0,0 ,240, 50, BLACK); // Рисуем чёрный прямоугольник для затирания предидущей // надписи режима работы на экране rezhim_kn = rezhim_kn + 1; // Увеличиваем счётчик нажатий кн. "Режим" на 1 } lastButton = buttonState; // Переписываем значение предидущего состояния кн. "Режим". if (rezhim_kn == 4) rezhim_kn = 0; // Если значение счётчика Режим = 4, то сброс счётчика. if (block_sv == HIGH) { // Проверка заполнен ли контейнер, если HIGH, то не заполнен. // Включение ручного режима if (rezhim_kn == 0) { // Если значение счётчика Режим = 0, то выводиться надпись Manual tft.setTextColor(YELLOW); tft.setCursor(5,5); tft.print(" Manual"); } // Включение режима спальня if (rezhim_kn == 1) { // Если значение счётчика Режим = 1, то выводиться надпись Bedroom // и включается автоматическое поддержание влажности от 40% до 50% tft.setTextColor(YELLOW); tft.setCursor(5,5); tft.print(" Bedroom"); // Надпись Bedroom (Спальня) if (h >= 50 & work_sv == HIGH) {digitalWrite(pusk,LOW); // Если влажность > 50% delay (1000); // и индикатор осушителя Вкл, то подаётся отрицательный импульс digitalWrite(pusk,HIGH);} // длительностью 1 сек. if (h <= 40 & work_sv == LOW){digitalWrite(pusk,LOW); delay (1000); digitalWrite(pusk,HIGH);} } // Включение режима Зал (Гостиная) if (rezhim_kn == 2) { tft.setTextColor(YELLOW); tft.setCursor(5,5); tft.print(" Hall"); if (h >= 60 & work_sv == HIGH) {digitalWrite(pusk,LOW); delay (1000); digitalWrite(pusk,HIGH);} if (h <= 40 & work_sv == LOW){digitalWrite(pusk,LOW); delay (1000); digitalWrite(pusk,HIGH);} } // Включение режима Рабочий кабинет if (rezhim_kn == 3) { tft.setTextColor(YELLOW); tft.setCursor(5,5); tft.print(" Workroom"); if (h >= 40 & work_sv == HIGH) {digitalWrite(pusk,LOW); delay (1000); digitalWrite(pusk,HIGH);} if (h <= 30 & work_sv == LOW){digitalWrite(pusk,LOW); delay (1000); digitalWrite(pusk,HIGH);} } }else {tft.fillRect(0,0 ,240, 50, BLACK); // Если контейнер переполнен, то выводится надпись // "Container". tft.setTextColor(RED); tft.setCursor(5,5); tft.print("Container"); delay (2000);} }
Архивы со скетчем, библиотеками и схемой можно скачать с Яндекса.
Напишите отзыв.
На TFT экране отображаются:
- Режим работы (4 режима);
- Состояние охладителя (работа или стоп);
- Влажность;
- Температура.
На левой стороне осушителя датчик DHT-11. На правой кнопка переключения режимов работы.
Блок управления поддерживает 4 режима:
- Manual (Ручной режим), блок не подаёт команды управления, а только отображает состояние;
- Bedroom (Спальня), блок поддерживает влажность в пределах 40 – 50%;
- Hall (Зал или Гостинная), блок поддерживает влажность 40 – 60%;
- Workroom (Рабочий кабинет), блок поддерживает влажность 30 – 40%.
Схема устройства изображена на рисунке
На схеме отображены входы «На зелёный светодиод» и «На жёлтый светодиод». Эти входы подключены к светодиодам, индицирующим режимы работы «Работа» и «Блокировка» на блоке управления в осушителе. Когда светодиод горит на ардуино подаётся логический 0, а когда светодиод гаснет то логическая 1. Резисторные делители нужны для согласования уровней на светодиодах и входе ардуино. Кстати, если экран будет некорректно отображать информацию – необходимо добавить резисторы 2.2кОм в разрыв линий DC, RES, SDA, SCL, для избежание перегрузки портов драйвера экрана.
На схеме также отображён выход «К осушителю кнопка Пуск». Этот выход подключён к кнопке запуска на блоке управления в осушителе. Имитация нажатия кнопки «Пуск» осуществляется подачей логического нуля в течении 1 сек на выход - «К осушителю кнопка Пуск».
Код для ардуино приведена на рисунке ниже. Для работы кода необходимы библиотеки - Adafruit_GFX.h, Arduino_ST7789.h, SPI.h и DHT.h. Первые две библиотеки имеются в архиве.