Купил как-то на алиэкспресс осушитель воздуха 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. Первые две библиотеки имеются в архиве.

Автомат для осушителя воздуха на Arduino.