Данную статью решил написать в следствии довольно таки долгой и безрезультатной борьбы с датчиком измерения температуры и влажности серии DHT. Если измерения температуры были нормальными, то с измерением влажности у данных датчиков полная катастрофа. То он показывает значительно заниженные значения, то сразу 99%. Все ухищрения с датчиками рекомендуемые в интернете к существенному изменению ситуации не приводили, тем более датчик использовался в экстремальных условиях (на улице у нас часто бывает очень высокая влажность).

      Поэтому решено было использовать другой датчик BME-280. Испытания датчика проводилось на двух предыдущих проектах – «Метеостанция на основе Ардуино» и «Автомат для осушителя воздуха на Arduino». В данной статье рассмотрены доработки схем и прошивок упомянутых проектов.

Имя  
Эл. почта  
Сообщение  
  

// Передатчик.
//Arduino Uno, датчик температуры и влажности DHT-22 (DHT-11),
// индикатор двухстрочный 1602А, блок LoRa XL1278-SMT.
// Для анимометра используется оптический прерыватель KY-010.
// Для позиционера использкутся угловой датчик WDD35D4-5K.
// Датчик давления BME280.

#include <Adafruit_Sensor.h>

#include <GyverBME280.h>  //Библиотека для барометра

#include <SPI.h> //Библиотека для подключение внешних устройств

#include <RH_RF95.h> // Библиотека для работы с блоком LoRa.

#include <math.h> //Библиотека для простых мат вычислений

#include <Wire.h> // Библиотека для работы с протоколом I2C

// создаем объект-экран, передаём используемый адрес и разрешение экрана:
#include <LiquidCrystal_PCF8574.h> // библиотека лдя обмена с экраном по I2C

//LiquidCrystal_PCF8574 lcd(0x27); // Указываем I2C адрес (наиболее распространенное
// значение), а также параметры экрана в случае LCD 1602
// - 2 строки по 16 символов в каждой

LiquidCrystal_PCF8574 lcd(0x27);// адрес экрана 0x27


// подключаем библиотеку DHT
#include "DHT.h"       //Скетч по умолчанию рассчитан на датчик DH22, 

#define DHTPIN 6          // поэтому вам нужно сначала закомментировать 
#define DHTTYPE DHT22     // строчку #define DHTTYPE DHT22 
// #define DHTTYPE DHT11  // Для датчика DHT11 - #define DHTTYPE DHT11.
//#define DHTTYPE DHT21   // DHT 21 (AM2301) 

DHT dht(DHTPIN, DHTTYPE); // Инициализация датчика DHT.



RH_RF95 rf95(7, 2);  // Подключаем блк LoRa 7 - выбор чипа NSS (пин на ардуино)
                     // 2 - прерывание (пин на ардуино)

int analogInput = 1; // Аналоговый вход позиционера.
int vout = 0;        // Значение с входа с позиционера.
int switchPin = 5;   // Защитный контур.
int pin_anem = 4;    // Назначаем пин подключения анимометра
byte v;
int v1;

float ob_per_sec = 0; // Частота оборотов
float ob_per_sec1 = 0;
int speed_wind = 0;   // Значение после пересчета частоты обор. в скорость ветра м/с

int otobr = 0;
int otobr_max = 0;
int z = 0;            // Переменная счетчика общего сброса

GyverBME280 bme;      // Инициализация датчика BME280

void setup() {

  pinMode(switchPin, INPUT); // Назначаем пин периметра на вход.

  pinMode(pin_anem, INPUT); // Назначаем пин анемометра на вход.

  lcd.begin(16, 2);// у нас экран 16 столбцов на 2 строки
  lcd.setBacklight(255); //установить яркость подсветки на максимум


  Serial.begin(9600); //Открывает последовательный порт, на скорости 9600 бит/с

  bme.begin(); 

  if (!bme.begin(0x76)) {
    lcd.println(F("No BME280 sensor"));
    delay(10000);
    lcd.clear(); //Очистка памяти диспея
  }

  dht.begin();

  while (!Serial);
  if (!rf95.init()) {
    lcd.println("LoRa failed!");      //В случае не выполнения условия появится
    //Serial.println("LoRa failed!");   //написать LoRa failed!
  } else lcd.println(" LoRa ");
  rf95.setTxPower(3);                // Устанавливаем выходную мощность.
  rf95.setFrequency(433.00);         // Устанавливаем частоту.
  rf95.setModemConfig(RH_RF95::Bw125Cr48Sf4096 );
}

// Создаём массив данных для передачи через LoRa
struct SEND_DATA {
  int Temperature;
  double Pozicion;
  int Skorost;
  // int Skorost_max;
  boolean Perimetr;
  int Vlazhnost;
  int Press;
  int Alt;
};
SEND_DATA mydata;
String Azm = ("N");

void(* resetFunc) (void) = 0; // объявляем функцию reset

void loop() {


  // Скорость ветра

  unsigned long Ltime1 = pulseInLong(pin_anem, LOW); // Отрицательный полупериод в мкС
  unsigned long Htime1 = pulseInLong(pin_anem, HIGH); // Положительный полупериод в мкС

  //Отладочная информация
//  Serial.print(" Ltime1 = "); 
//  Serial.print(Ltime1);
//  Serial.print(" Htime1 = ");
//  Serial.print(Htime1);

  // Полный оборот в мкС
  unsigned long Time = Ltime1 + Htime1; 

  //Отладочная информация
//  Serial.print(" Time = ");
//  Serial.print(Time);

  // Часторта оборотов в сек.
  if (Ltime1 == 0 || Htime1 == 0){ob_per_sec = 0;}else{ 
  ob_per_sec =  250000 /(float) Time;}    

  // Присвоение значения скорости ветра отностельно частоты оборотов диска анемометра
  if (ob_per_sec == 0) {speed_wind = 0;}
  if (ob_per_sec > 0.0 && ob_per_sec <= 1.0)   {speed_wind = 1;}
  if (ob_per_sec > 1.0 && ob_per_sec <= 1.5)   {speed_wind = 2;}
  if (ob_per_sec > 1.5 && ob_per_sec <= 2.0)   {speed_wind = 3;}
  if (ob_per_sec > 2.0 && ob_per_sec <= 2.5)   {speed_wind = 4;}
  if (ob_per_sec > 2.5 && ob_per_sec <= 3.0)   {speed_wind = 5;}
  if (ob_per_sec > 3.0 && ob_per_sec <= 3.5)   {speed_wind = 6;}
  if (ob_per_sec > 3.5 && ob_per_sec <= 4.0)   {speed_wind = 7;}
  if (ob_per_sec > 4.0 && ob_per_sec <= 4.5)   {speed_wind = 8;}
  if (ob_per_sec > 4.5 && ob_per_sec <= 5.0)   {speed_wind = 9;}
  if (ob_per_sec > 5.0 && ob_per_sec <= 5.5)  {speed_wind = 10;}
  if (ob_per_sec > 5.5 && ob_per_sec <= 6.0) {speed_wind = 11;}
  if (ob_per_sec > 6.0 && ob_per_sec <= 6.5) {speed_wind = 12;}
  if (ob_per_sec > 6.5 && ob_per_sec <= 7.0) {speed_wind = 13;}
  if (ob_per_sec > 7.0 && ob_per_sec <= 7.5) {speed_wind = 14;}
  if (ob_per_sec > 7.5 && ob_per_sec <= 8.0) {speed_wind = 15;}
  if (ob_per_sec > 8.0 && ob_per_sec <= 8.5) {speed_wind = 16;}
  if (ob_per_sec > 8.5 && ob_per_sec<= 9.0) {speed_wind = 17;}
  if (ob_per_sec > 9.0 && ob_per_sec <= 9.5) {speed_wind = 18;}
  if (ob_per_sec > 9.5 && ob_per_sec <= 10.0) {speed_wind = 19;}
  if (ob_per_sec > 10.0 && ob_per_sec <= 10.5) {speed_wind = 20;}
  if (ob_per_sec > 10.5 && ob_per_sec <= 11.0) {speed_wind = 21;}
  if (ob_per_sec > 11.0 && ob_per_sec <= 11.5) {speed_wind = 22;}
  if (ob_per_sec > 11.5 && ob_per_sec <= 12.0) {speed_wind = 23;}
  if (ob_per_sec > 12.0 && ob_per_sec <= 12.5) {speed_wind = 24;}
  if (ob_per_sec > 12.5 && ob_per_sec <= 13.0) {speed_wind = 25;}
  if (ob_per_sec > 13.0 && ob_per_sec <= 13.5) {speed_wind = 26;}
  if (ob_per_sec > 13.5 && ob_per_sec <= 14.0) {speed_wind = 27;}
  if (ob_per_sec > 14.0 && ob_per_sec <= 14.5) {speed_wind = 28;}
  if (ob_per_sec > 14.5 && ob_per_sec <= 15.0) {speed_wind = 29;}
  if (ob_per_sec > 15.0) {speed_wind = 30;}

  // if (speed_wind > speed_wind_max) {speed_wind_max = speed_wind;} // Проверяем и
  // переписываем, если действующее значение больше чем предыдущее значение.

  mydata.Skorost = speed_wind;

  // Температура, влажность и давление.

  float p1 = bme.readPressure();   // Измерение Атм. давления

  int P = (pressureToMmHg(p1));   // Давление в [мм рт. столба]

  mydata.Press = P;               // Запись значения давления в переменную массива

  // Отладочная информация
//  Serial.print(F("Атм.Давление = "));
//  Serial.print (P);
//  Serial.println(" мм.рт.ст.");  // mmHg

  // Определяем высоту над уровнем моря (в дальнейшем не используется)
  int A = (pressureToAltitude(p1));
  mydata.Alt = A;
  Serial.print(F("Высота над уровнем моря = "));
  Serial.print(A);
  Serial.println(" м");

  float h = bme.readHumidity();        // Чтение данных о влажности и запись в h.
  float t = dht.readTemperature();     // Чтение температуры в град. цельсия  и запись в t.
  if (isnan(h) || isnan(t)) {          // Проверка. Если не удается считать показания,
                                       // выводится «Ошибка считывания»
    lcd.println("Failed to read from DHT sensor!");
  }

  mydata.Temperature = t;  // Запись значения температуры в переменную массива
  mydata.Vlazhnost = h;    // Запись значения влажности в переменную массива

  // Проверка состояния зашитного контура (Открыта ли дверь доступа к станции).
  if (digitalRead(switchPin) == HIGH) mydata.Perimetr = HIGH;
  else mydata.Perimetr = LOW;

  // Отладочная информация
// Serial.print(" Perimetr = ");
// Serial.println(mydata.Perimetr);

  // Позиционер

  vout = analogRead(analogInput); // чтение значения позиционера.
  mydata.Pozicion = vout * 5.0 / 1024.0 * 72; // Вычесление знач. позиции Аз

  if (0 <= mydata.Pozicion && 11.25 > mydata.Pozicion)
    Azm = ("N");
  if (11.25 <= mydata.Pozicion && 33.75 > mydata.Pozicion)
    Azm = ("NNE");
  if (33.75 <= mydata.Pozicion && 56.25 > mydata.Pozicion)
    Azm = ("NE");
  if (56.25 <= mydata.Pozicion && 78.75 > mydata.Pozicion)
    Azm = ("ENE");
  if (78.75 <= mydata.Pozicion && 101.25 > mydata.Pozicion)
    Azm = ("E");
  if (101.25 <= mydata.Pozicion && 123.75 > mydata.Pozicion)
    Azm = ("ESE");
  if (123.75 <= mydata.Pozicion && 146.25 > mydata.Pozicion)
    Azm = ("SE");
  if (146.25 <= mydata.Pozicion && 168.75 > mydata.Pozicion)
    Azm = ("SSE");
  if (168.75 <= mydata.Pozicion && 191.25 > mydata.Pozicion)
    Azm = ("S");
  if (191.25 <= mydata.Pozicion && 213.75 > mydata.Pozicion)
    Azm = ("SSW");
  if (213.75 <= mydata.Pozicion && 236.25 > mydata.Pozicion)
    Azm = ("SW");
  if (236.25 <= mydata.Pozicion && 258.75 > mydata.Pozicion)
    Azm = ("WSW");
  if (258.75 <= mydata.Pozicion && 281.25 > mydata.Pozicion)
    Azm = ("W");
  if (281.25 <= mydata.Pozicion && 303.75 > mydata.Pozicion)
    Azm = ("WNW");
  if (303.75 <= mydata.Pozicion && 326.25 > mydata.Pozicion)
    Azm = ("NW");
  if (326.25 <= mydata.Pozicion && 348.75 > mydata.Pozicion)
    Azm = ("NNW");
  if (348.75 <= mydata.Pozicion && 360.00 > mydata.Pozicion)
    Azm = ("N");

  // Вывод данных.

  // Отладочная информация
  // Serial.print("Temp = "); // Печать заголовка
  // Serial.print(mydata.Temperature); // Выводим показания датчика в порт
  // Serial.print("  ");

  // Serial.print("Влажн = "); // Печать заголовка
  // Serial.print(mydata.Vlazhnost); // Выводим показания датчика в порт
  // Serial.print(" % ");

  // Вывод информации на дисплей метеостанции
  lcd.clear(); //Очистка памяти диспея
  lcd.setCursor(0, 0); //Установка курсора в начало 1 строки
  lcd.print("Tmp= "); // Печать заголовка
  lcd.print(mydata.Temperature); // Выводим показания датчика
  lcd.print(" C");

  lcd.setCursor(10, 0); //Установка курсора в начало 1 строки
  lcd.print("P= "); // Печать заголовка
  lcd.print(mydata.Press); // Выводим показания датчика


  // Отладочная информация
  // Serial.print("Poz = "); // Печать заголовка
  // Serial.print(mydata.Pozicion); // Выводим показания датчика в порт
  // Serial.print("  ");

  lcd.setCursor(0, 1); //Установка курсора в начало 2 строки
  lcd.print("Az = "); // Печать заголовка
  lcd.print(Azm); // Выводим показания датчика

  // Отладочная информация
  // Serial.print("U пин = "); // Печать заголовка
  // Serial.print(currentButton); // Выводим показания датчика в порт
  // Serial.print(" ");

  // Serial.print("U пин1 = "); // Печать заголовка
  // Serial.print(ob_per_sec); // Выводим показания датчика в порт
  // Serial.print(" ");

  // Serial.print("U = "); // Печать заголовка
  // Serial.print(mydata.Skorost); // Выводим показания датчика в порт
  // Serial.print(" m/s ");

  lcd.setCursor(8, 1); //Установка курсора в 10 позицию 2 строки
  lcd.print(" U= "); // Печать заголовка
  lcd.print(mydata.Skorost); // Выводим показания датчика
  
  // Отладочная информация
  // Serial.print (" Umax = ");
  // Serial.println (speed_wind_max);
  
  // Выводим информацию массива данных с помощью LoRa
  rf95.send((uint8_t*)&mydata, sizeof(mydata));
  rf95.waitPacketSent();

  if (z >= 7200) {
    resetFunc(); //вызываем reset каждые 12 часов
  }
  z = z + 1;
  delay(600); // Время индикации
  
}

Архив с программами, библиотекой и схемой можно скачать с Яндекса.

Напишите отзыв.

       В данный проект «Метеостанция на основе Ардуино» внесены, пожалуй, самые минимальные изменения. Так как на метеостанции уже был установлен датчик BMP-280, то изменения заключались лишь только в замене датчика на BME-280 и небольшого изменения прошивки для «Передатчика метеостанции». Данный датчик измеряет (в данной схеме) атмосферное давление и влажность воздуха (измерение температуры по-прежнему измеряется датчиком DHT–22).

      Схема включения датчика BMP-280 и BME-280 одинаковые (оба датчика должны быть на 5В, если датчик на 3.3В то необходимо установить дополнительно преобразователь напряжения питания на 3.3В).

      В скетче для работы датчика использовал библиотеку «GyverBME280.h» (данная библиотека имеется в архиве – ссылка в конце статьи).

       Ниже приведён изменённый скетч с комментариями.

Датчик BME-280 измеритель влажности, давления, температуры.

Датчик BME-280 в метеостанции.

Датчик BME-280 в автомате осушителя воздуха.

      Проект «Автомат для осушителя воздуха на Arduino» претерпел более серьезные изменения как в схеме, так и в программном обеспечении. В схеме заменён датчик DHT-11 на BME-280. Датчик BME-280 подключён по I2C интерфейсу, что привело к изменению схемы включения датчика. Датчик подключается строго к определённым выводам платы Arduino nano – SDA к А4, SCL к А5.

      Ниже приведена изменённая схема устройства.

      Помимо включения датчика в схеме отображены ограничивающие резисторы по 2.2кОм в схеме шины ISP дисплея, эти резисторы предназначены для совместимости интерфейса шины 5В от ардуино и 3.3В экрана.

      В скетче добавлена штатная библиотека для работы с I2C интерфейсом «Wire.h» и упомянутая ранее «GyverBME280.h». Алгоритм работы программы остался прежним изменён только синтаксис.

      Ниже представлен изменённый скетч с описанием.

#include <Adafruit_GFX.h>    // Базовая графическая библиотека от Adafruit
#include <Arduino_ST7789.h> // Аппаратно-зависимая библиотека для ST7789 (с выводом CS или без него)
#include <SPI.h>    //Библиотека для подключение внешних устройств
#include <Wire.h>   // Библиотека для работы с протоколом I2C
#include <GyverBME280.h>  // Библиотека для работы с модулем BME-280

#define rezhim    4      // пин кнопка Режим
#define pusk      10     // пин кнопка Пуск (имитирует нажатие)
#define work      12     // пин рабочий режим (зелёный светодиод)
#define block     5      // пин блокировка (жёлтый светодиод)при заполнении контейнера водой
#define DHTPIN    9      // пин датчик температуры и влажности
  
GyverBME280 bme;     // Инициация датчика

#define TFT_DC    7
#define TFT_RST   6 
#define TFT_CS    3   // только для дисплеев с выводом 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, TFT_MOSI, TFT_SCLK);
 
// для отображения без вывода 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 пикселей
  tft.fillScreen(BLACK);  // окрашивание экрана в чёрный цвет
  if (!bme.begin(0x76)) {    // Проверка инициализации датчика
    tft.setTextColor(RED);   // Задаём цвет текста
    tft.setCursor(25,100);    // Позиционируем курсор на экране
    tft.setTextSize(4);      // Задаём размер текста  
    tft.print("Connect the sensor"); 
    delay(5000);
    }

  tft.fillScreen(BLACK);

  // Вывод надписи LAUNCH на экран
  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 = bme.readHumidity();            //Измеряем влажность
    t = bme.readTemperature();         //Измеряем температуру    
   
  if (isnan(h) || isnan(t)) {  // Проверка. Если не удается считать показания, выводится «Ошибка считывания», 
                               // и программа завершает работу
                               // Serial.println("Ошибка считывания");
    tft.fillScreen(BLACK);     // Отчистка экрана

  // Выводим надпись ALARM 
  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);}       

}