Делаем метеостанцию на базе arduino

Общий принцип работы

Измеряющая данные окружающей среды метеостанция на Ардуино состоит из нескольких основных компонентов:

  • собственно плата управления Arduino (например, Uno). На нее поступает информация со внешних датчиков, контроллер выполняет вычисления и выводит информацию на экран;
  • электронный дисплей — служит для отображения поступивших с контроллера данных в понятной человекочитаемой форме;
  • сенсор влажности температуры. В подобных схемах популярны датчики DHT11 и DHT22. Они регистрируют данные среды и отдают их контроллеру;
  • макетная плата — основа для сборки всех компонентов. На ней фиксируются все элементы метеостанции, по ней же прокладываются электрические соединения;
  • соединительные провода — с «оголенными» концами под пайку или оснащенные штекерами.

Кроме того, в плату понадобится залить соответствующее программное обеспечение — скетч. Его содержимое зависит от набора элементов и выполняемых задач, примеры скетчей мы также рассмотрим ниже.

API

Ключевое, что делает 99% времени сервер — это простой. Но в остальные 1% он отдаёт и получает данные, и за это, помимо отображения страниц через веб-интерфейс отвечает API. 

Именно через Flask REST API мы будем посылать или получать данные от сенсоров.

home_server/routes/api.py

Данные пишутся в лог:

В моём случае, если мы получили данные от датчика (получили POST запрос с верным JSON), то мы их сохраняем в БД. Так же, если мы получили GET запрос на отправку данных (send_data), то данные отправляем данные на облако.

home_server/pages/weather_station/send_data.py

Ах да, забыл упомянуть камеру. Если мы подключили камеру к Raspberry Pi, то можем отправлять или сохранять изображения погоды за окном. Для этого есть отдельный метод:

home_server/pages/shared/tools.py

Ардуино. Метеостанция на LCD 1602 и DHT11


Ардуино. Метеостанция с дисплеем LCD 1602 и DHT22 После сборки схемы, загрузите в микроконтроллер следующий скетч (здесь ссылка на скачивание архива со скетчем для метеостанции и необходимыми библиотеками). Информация с датчика DHT22 выводиться будет на монитор порта Arduino IDE и на жидкокристаллический дисплей 1602a, для отображения информации использован русский шрифт для LCD и символы (в скетче есть подробные комментарии).

Скетч для метеостанции с DHT11 на Ардуино

#include <Wire.h> // библиотека для протокола IIC #include <LiquidCrystal_I2C.h> // подключаем библиотеку LCD IIC LiquidCrystal_I2C lcd(0x27,20,2); // присваиваем имя lcd для дисплея #include «DHT.h» // подключаем библиотеку для DHT11 DHT dht(2, DHT11); // к какому порту подключаем датчик // создаем символ градуса и присваиваем имя «gradus» byte gradus = { 0b01100,0b10010,0b10010,0b01100,0b00000,0b00000,0b00000,0b00000 }; // создаем русскую букву «П» byte P = { 0b11111,0b10001,0b10001,0b10001,0b10001,0b10001,0b10001,0b00000 }; // создаем русскую букву «У» byte Y = { 0b10001,0b10001,0b10001,0b01111,0b00001,0b00001,0b01110,0b00000 }; // создаем русскую букву «Л» byte L = { 0b00111,0b01001,0b10001,0b10001,0b10001,0b10001,0b10001,0b00000 }; // создаем русскую букву «Ж» byte ZH = { 0b10101,0b10101,0b10101,0b01110,0b10101,0b10101,0b10101,0b00000 }; // создаем русскую букву «Ь» byte znak = { 0b10000,0b10000,0b10000,0b11110,0b10001,0b10001,0b11110,0b00000 }; void setup() { Serial.begin(9600); // запуск последовательного порта lcd.init(); // инициализация LCD дисплея lcd.backlight(); // включение подсветки дисплея lcd.createChar(1, gradus); lcd.createChar(2, P); lcd.createChar(3, Y); lcd.createChar(4, L); lcd.createChar(5, ZH); lcd.createChar(6, znak); } void loop() { // если нужны точные значение, то используйте float, вместо byte byte h = dht.readHumidity(); // считываем значение температуры byte t = dht.readTemperature(); // считываем значение влажности Serial.print(«Temperature: «); Serial.println(t); // отправляем значение температуры на монитор Serial.print(«Humidity: «); Serial.println(h); // отправляем значение температуры на монитор Serial.println(» «); // пустая строка lcd.setCursor(0,0); // ставим курсор на 1 символ первой строки lcd.print(«TEM»); // используем латинские буквы lcd.print(char(2)); // выводим русскую букву «П» lcd.print(«EPAT»); // используем латинские буквы lcd.print(char(3)); // выводим русскую букву «У» lcd.print(«PA: «); // используем латинские буквы lcd.print(t); // выводим значение температуры на LCD lcd.print(char(1)); // выводим знак градуса lcd.setCursor(2,1); // ставим курсор на 3 символ второй строки lcd.print(«B»); // используем латинские буквы lcd.print(char(4)); // выводим русскую букву «Л» lcd.print(«A»); // используем латинские буквы lcd.print(char(5)); // выводим русскую букву «Ж» lcd.print(«HOCT»); // используем латинские буквы lcd.print(char(6)); // выводим русскую букву «Ь» lcd.print(«: «); // используем латинские буквы lcd.print(h); // выводим значение влажности на LCD lcd.print(«%»); // выводим знак процент delay(1000); }

Пояснения к коду:

  1. в скетче можно использовать до 8 русских букв и символов, при необходимости заменяйте буквы из кириллицы — латинскими буквами;
  2. скорость обновления данных замените на необходимое значение.

Заключение. Мы рассмотрели, как сделать простую домашнюю метеостанцию на Ардуино c дисплеем 1602а и датчиком температуры и влажности воздуха DHT11. Данный проект можно доработать, добавив к схеме еще больше датчиков для анализа метеоусловий. Также можно сделать беспроводную метеостанцию на Arduino Uno, используя блютуз или радио модули для передачи информации на расстояние.

Дисплей 16×4 LCD1604

Подробнее о дисплее и работе с ним погуглите «Работа с символьными ЖКИ на базе HD44780». Отметим, что нужно внимательно отнестись к полярности подключения питания к ЖК-индикатору и чтобы напряжение питания было в диапазоне +4,5…5,5 В. Невнимательное отношение к этому может привести к выходу индикатора из строя!

Пин LCD 1604 Arduino MEGA Arduino UNO Описание
VSS GND GND GND
VDD 5 V 5 V 4,7 — 5,3V
RS 22 4 Высокий уровень означает, что сигнал на выходах DB0—DB7 является данными, низкий — командой
RW GND GND Определяет направление данных (чтение/запись). Так как операция чтения данных из индикатора обычно бывает невостребованной, то можно установить постоянно на этом входе низкий уровень
E 23 5 Импульс длительностью не менее 500 мс на этом выводе определяет сигнал для чтения/записи данных с выводов DB0-DB7, RS и WR
DB4 24 8 Входящие/исходящие данные
DB5 25 9
DB6 26 10
DB7 27 11
LED A+ +5V или резистор 220 Ом → +5VLED-A
LED B- GND
V0 GND или подстроечник на 10кОм

Программная инициализация будет выглядеть так:

Температура, влажность DHT11

Подключение датчика температуры и влажности DHT11 (SainSmart). Датчик расположите лицевой стороной вверх, выводы будут описаны слева направо.

DHT11 Arduino Mega
DATA Digital pin 2 (PWM) (см. ниже DHTPIN)
VCC 3,3—5 В (рекомендуется 5 В, лучше внешнее питание)
GND GND

Программная инициализация

Барометр BMP180

Подключение датчика атмосферного давления BMP180 (барометр) + температура по интерфейсу I2C/TWI.

BMP180 Arduino Mega
VCC не подключен
GND GND
SCL 21 (SCL)
SDA 20 (SDA)
3,3 3,3 В

Для UNO: A4 (SDA), A5 (SCL).

nRF24L01+

Краткие характеристики:

  • Диапазон частот 2,401 — 2,4835 Ггц
  • 126 каналов. Нулевой канал начинается с 2400 Мгц и далее с шагом 1 Мгц, например 70 канал находится соответственно на 2470 Мгц. При установке скорости передачи 2Mbps занимается ширина канала в 2 Мгц
  • Питание 1,9 — 3,6 В (рекомендуется 3,3 В)

Вот распиновка модуля.

Некоторые советуют сразу же припаять керамический конденсатор 100nF (можно 1µF, 10µF) на выводы питания RF для избежания электрических помех.

Распиновка nRF24L01+ (смотреть сверху платы там где чип, пины должны быть внизу) :

пин 2 3,3V пин 4 CSN пин 6 MOSI пин 8 IRQ
пин 1 GND пин 3 CE пин 5 SCK пин 7 MISO

Подключение для метеостанции:

Arduino Mega nRF24L01+
3,3 В VCC пин 2 (лучше внешнее питание)
пин D8 CE пин 3 (chip enable in)
SS пин D53 CSN пин 4 (chip select in)
SCK пин D52 SCK пин 5 (SPI clock in)
MOSI пин D51 SDI пин 6 (SPI Data in)
MISO пин D50 SDO пин 7 (SPI data out)
IRQ пин 8 (Interrupt output) не подсоединен
GND GND пин 1 (ground in)

Программирование радиомодуля будет подробно описано в программной части.

ESP8266

Распиновка ESP8266 (смотреть сверху платы там где чипы, пины должны быть внизу):

GND GPIO2 GPIO0 RX
TX CH_PD RESET VCC

Подключение ESP8266 для метеостанции:

ESP8266 Arduino Mega
TX 10 пин (SoftwareSerial RX)
RX 11 пин (SoftwareSerial TX)
VCC 3,3 В
GND GND
CH_PD Через резистор 10К к 3,3 В Arduino
GPI0 Необязательно. Через резистор 10К к 3,3 В Arduino
GPI2 Необязательно. Через резистор 10К к 3,3 В Arduino

КДПВ

Центральный блок в сборе. «Материнскую плату» вырезал из картонной коробки из-под обуви и к ней винтиками на 3 прикрутил всё остальное.

Как видим в этом месте всё питание осуществляется от пинов Ардуино, т.е. к блоку питания напрямую ничего не идёт, и пока мощи хватает.

Вроде всё. Ничего не забыл.

Паяйте, соединяйте. В следующей части будет приведен рабочий скетч для центрального блока и наша метеостанция уже что-то покажет.

Что это такое?

Наша метеостанция будет состоять из двух устройств: компактного автономного
устройства, измеряющего погодные показатели, и устройства-ретранслятора,
получающего эти показатели и отправляющего их на «народный мониторинг».
Устройства будут связываться по беспроводному каналу связи на частоте 433 МГц.
Автономная часть будет питаться от трёх пальчиковых батареек и сможет
просуществовать на одном комплекте батарей до года при периоде опроса датчиков
в 20 мин.

Такая конструкция позволяет не сверлить стены для прокладки проводов с улицы, где необходимо производить измерения, в помещение, где результатами этих
измерений надо пользоваться.

Что ещё можно сделать?

  1. Мы установили только сенсор температуры и влажности. Но у Teensy остаётся ещё много свободных ножек, т.ч. можно добавить разных датчиков: освещённости, атмосферного давления, скорости ветра и т.д.
  2. Teensy прямо на борту имеет часы реального времени (RTC). Для их работоспособности не хватает только кварца. Можно купить кварц на 32,768 КГц в любом магазине радиоэлементов и припаять его. Тогда можно пробуждать Teensy по будильнику RTC. Достоинство в том, что можно будить устройство чаще в те часы, когда нужны более точные показания. Например, в рабочее время будить устройство каждые 5 минут, а в остальное — каждые полчаса.

Скетч для работы с датчиками DHT11 и DHT22 в Arduino

#include "DHT.h"
#define DHTPIN 2 // Тот самый номер пина, о котором упоминалось выше
// Одна из следующих строк закоментирована. Снимите комментарий, если подключаете датчик DHT11 к arduino
DHT dht(DHTPIN, DHT22); //Инициация датчика
//DHT dht(DHTPIN, DHT11);
void setup() {
  Serial.begin(9600);
  dht.begin();
}
void loop() {
  delay(2000); // 2 секунды задержки
  float h = dht.readHumidity(); //Измеряем влажность
  float t = dht.readTemperature(); //Измеряем температуру
  if (isnan(h) || isnan(t)) {  // Проверка. Если не удается считать показания, выводится «Ошибка считывания», и программа завершает работу
    Serial.println("Ошибка считывания");
    return;
  }
  Serial.print("Влажность: ");
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("Температура: ");
  Serial.print(t);
  Serial.println(" *C "); //Вывод показателей на экран
}

После загрузки скетча и подключения датчика, результат измерений можно посмотреть в окне монитора порта. Там будут выводиться значения температуры и влажности. Если что-то пошло не так, проверьте правильность подключения датчика, соответствие номера порта на плате Arduino и в скетче, надежность контактов.
Если все работает и датчик дает показания, можете провести эксперименты. Например, поместить датчик в более холодное место или подышать на него, отслеживая при этом изменения . Если при запотевании уровень влажности увеличивается, значит датчик работает исправно. Подуйте на него тонкой струйкой – влажность уменьшится и температура вернется в норму.

На этом этапе вы сможете заметить разницу между реальным значением температуры и показаниями датчика с ардуино. Точность DHT11 гораздо хуже точности DHT22, о чем мы уже говорили в этой статье. Если у вас есть оба датчика, подключите их к плате Arduino и сравните результаты. По моему опыту, в среднем расхождение составляет больше градуса. Учитывайте это, используя эти датчики в своих проектах.

Радиодатчики

Там, где не дотянуться Wi-Fi, нужно использовать альтернативные варианты передачи данных. В моём случае — это использование LoRa-модулей (в связке, например, с Arduino Nano.

Таких устройств у меня два — это датчик скорости и направления ветра (компас). Пока не буду останавливаться на этом в текущей статье, если будет интерес — напишу отдельно. Второе устройство — это вольтметр и два амперметра, для контроля работы ветряка, зарядки АКБ и потребления.

SX1278

Arduino Nano

3.3V

3.3V

GROUND

GROUND

MOSI

D10

MISO

D11

SCK

D13

NSS/ENABLE

D12

DIO0

D2

RST

D9

И, код, соответственно:

iot/arduino/*_meter/*_meter.ino

Достаточно просто, не правда ли?

Создание базы данных

Начнем с самого начала, а именно с проектирования и создания базы данных.

Базы данных это свой мир и изучать его можно долго, поэтому бегло коснёмся только тех вещей, которые нам непосредственно необходимы.

Все SQL скрипты находятся в каталоге

С чего начинается проектирование БД? С логического и физического представления.

Логическое представление или схема базы данных:

  • таблица с данными DHT датчика температуры и влажности
  • таблица с данными BMP датчика давления и температуры
  • указанные таблицы не имеют связей между собой, точнее связи не нужны.

Физическая схема опирается на конкретную СУБД и типы данных. Проще разбирать на конкретном примере. SQL скрипт раскрывает логическую и физическую схемы.

В каждой таблице должно быть поле типа

Имя поля может отличаться в разных БД, но смысл один — это уникальный идентификатор, ключ записи. На будущее, если вы видите базу данных в таблицах которой нет подобного счётчика, знайте, эту БД проектировал человек весьма далёкий от программирования, скорее всего гуманитарий.

Данные от однотипных датчиков храним в одной таблице, для датчиков другого типа создаём еще таблицу. Это чуть усложняет базу данных и PHP обвязку к ней, но это упрощает расширение или модификацию всей системы в дальнейшем.

В нашем проекте две таблицы. В таблице хранятся данные от датчика(ов) типа DHT (температура, влажность), в таблице хранятся данные от датчика(ов) типа BMP (температура, давление). Если вы в будущем захотите иметь, например, датчик газов или детектор движения, то создаёте дополнительные таблицы, не поленитесь. Если подключаете ещё один датчик типа DHT11 или DHT22, то создавать дополнительную таблицу не нужно, используете таблицу . Надеюсь принцип ясен: отдельная физическая сущность — отдельная таблица.

Если в таблице будут храниться данные от несколько однотипных датчиков, то как же их различить? Для этого в каждой таблице вводится поле

Фактически это который мы прописывали в файле для каждого экземпляра удаленного датчика-клиента и в для датчика, который подключен непосредственно к серверу — центральному блоку.

В промышленных системах должна быть ещё одна таблица — соответствия и его словесного, человекочитаемого описания. Например, датчик с = 2 это «Температура, влажность в квартире» и т.д. Но в нашем проекте не будем усложнять, просто помните, что :

  • датчик с , он же , равным 11 — это есть домашний датчик на сервере — центральном блоке,
  • датчик с , он же , равным 20 — это первый (в нашем проекте и единственный) заоконный датчик-клиент.

Далее. В таблицах хранятся следующие данные:

  • ipRemote — IP адрес метеостанции (сервера) с которого пришли данные, полезно для отладки и мониторинга,
  • dateCreate — дата время создания записи,
  • millis — полезно для отладки, это время в миллисекундах с момента начала выполнения скетча на Arduino,
  • temperature — температура,
  • humidity — влажность,
  • voltage — напряжение питания,
  • pressure — давление,
  • errors — количество ошибок (не используется). Задумывалось для хранения количества ошибок при передаче и т.п., чтобы можно было удаленно оценить состояние всей системы.

Как видим таблицы и очень похожи, отличие только в полях pressure и humidity, и возникает желание свалить всё в одну кучу (таблицу). Но делать так не велит первая нормальная форма, множество начинающих программистов пытались её обойти, но ни у одного не получилось, и мы не будем. Это как не замечать закон всемирного тяготения, до поры до времени вполне может получиться.

Таблица полезна при отладке — это журнал ошибок и прочих системных сообщений.

Создание БД и её пользователя с правами описано в

Это делается один раз, имя БД и имя пользователя можете придумать свои. И что точно необходимо сделать — это задать свой пароль.

Печатные платы.

Печатные платы разработаны в программе Dip Trace. Они выполнены на одностороннем фольгированном стеклотекстолите. Расположение деталей на основной печатной плате показано на рисунке (Рисунок 4). На рисунке перемычки со стороны монтажа выделены цветными ломаными линиями. Печатная плата со стороны дорожек показана на рисунке (Рисунок 5).

Рисунок 4. Печатная плата (вид со стороны радиодеталей).

Рисунок 5. Печатная плата (вид снизу, зеркальное отображение).

Кнопки и переключатели пульта управления станцией установлены на отдельной печатной плате (Рисунок 6 и Рисунок 7).

Рисунок 6. Печатная плата Пульта управления (вид сверху).

Рисунок 7. Печатная плата Пульта управления (вид со стороны дорожек).

Гнездо для подключения USB кабеля установлено на отдельной плате, купленной на AliExpress (Рисунок 8).

Рисунок 8. Плата с гнездом USB.

Пояснения к коду

  • Очень часто бывает полезно обмениваться данными, например, с компьютером. В частности, для отладки работы устройства: можно, например, смотреть, какие значения принимают переменные.
  • В данном эксперименте мы знакомимся со стандартным объектом , который предназначен для работы с последовательным портом (UART) Arduino, и его методами (функциями, созданными для работы с данным объектом) , и , которые вызываются после точки, идущей за именем объекта:
    • чтобы обмениваться данными, нужно начать соединение, поэтому вызывается в

    • отправляет содержимое . Если мы хотим отправить текст, можно просто заключить его в пару двойных кавычек: . Кириллица, скорее всего, будет отображаться некорректно.
    • делает то же самое, только добавляет в конце невидимый символ новой строки.
  • В и можно использовать второй необязательный параметр: выбор системы счисления, в которой выводить число (это может быть , , , для десятичной, двоичной, шестнадцатеричной и восьмеричной систем счисления соответственно) или количество знаков после запятой для дробных чисел.

Например,

Serial.println(18,BIN);
Serial.print(3.14159,3);

в мониторе порта даст результат

10010
3.142
  • Монитор порта, входящий в Arduino IDE, открывается через меню Сервис или сочетанием клавиш Ctrl+Shift+M. Следите за тем, чтобы в мониторе и в скетче была указана одинаковая скорость обмена данными, . Скорости 9600 бит в секунду обычно достаточно. Другие стандартные значения можете посмотреть в выпадающем меню справа внизу окна монитора порта.
  • Вам не удастся использовать цифровые порты 0 и 1 одновременно с передачей данных по последовательному порту, потому что по ним также идет передача данных, как и через USB-порт платы.
  • При запуске монитора порта скетч в микроконтроллере перезагружается и начинает работать с начала. Это удобно, если вам нельзя упустить какие-то данные, которые начинаю передаваться сразу же. Но в других ситуациях это может мешать, помните об этом нюансе!
  • Если вы хотите читать какие-то данные в реальном времени, не забывайте делать хотя бы на 100 миллисекунд, иначе бегущие числа в мониторе будет невозможно разобрать. Вы можете отправлять данные и без задержки, а затем, к примеру, скопировать их для обработки в стороннем приложении.
  • Последовательность выводится как символ табуляции (8 пробелов с выравниванием). Также вы можете использовать, например, последовательность для перевода строки. Если вы хотите использовать обратный слеш, его нужно экранировать вторым таким же: .

Скетч

p160_meteostation.ino
#include <math.h>
int minute = 1;
 
// Параметр конкретного типа термистора (из datasheet):
#define TERMIST_B 4300 
 
#define VIN 5.0
 
void setup()
{
  // мы хотим передавать информацию на компьютер через USB, а
  // точнее через последовательный (англ. serial) порт.
  // Для этого необходимо начать (англ. begin) передачу, указав
  // скорость. 9600 бит в секунду — традиционная скорость.
  // Функция «begin» не является глобальной, она принадлежит
  // объекту с именем «Serial». Объекты — это «продвинутые»
  // переменные, которые обладают собственными функциями,
  // к которым обращаются через символ точки.
  Serial.begin(9600);
  // передаём заголовок нашей таблицы в текстовом виде, иначе
  // говоря печатаем строку (англ. print line). Символы «\t» —
  // это специальная последовательность, которая заменяется на
  // знак табуляции (англ. tab): 8-кратный выровненный пробел
  Serial.println("Minute\tTemperature");
}
 
void loop()
{
  // вычисляем температуру в °С с помощью магической формулы.
  // Используем при этом не целые числа, а вещественные. Их ещё
  // называют числами с плавающей (англ. float) точкой. В
  // выражениях с вещественными числами обязательно нужно явно
  // указывать дробную часть у всех констант. Иначе дробная
  // часть результата будет отброшена
 
   float voltage = analogRead(A0) * VIN  1024.0;
   float r1 = voltage  (VIN - voltage);
 
 
   float temperature = 1.( 1.(TERMIST_B)*log(r1)+1.(25. + 273.) ) - 273;
  // печатаем текущую минуту и температуру, разделяя их табом.
  // println переводит курсор на новую строку, а print — нет
  Serial.print(minute);
  Serial.print("\t");
  Serial.println(temperature);
 
  delay(60000); // засыпаем на минуту
  ++minute;     // увеличиваем значение минуты на 1
 
  // откройте окно Serial Monitor в среде Arduino, оставьте на
  // сутки, скопируйте данные в Excel, чтобы построить графики
}

Ардуино. Метеостанция на LCD 1602 и DHT11

Ардуино. Метеостанция с дисплеем LCD 1602 и DHT22

После сборки схемы, загрузите в микроконтроллер следующий скетч (здесь ссылка на скачивание архива со скетчем для метеостанции и необходимыми библиотеками). Информация с датчика DHT22 выводиться будет на монитор порта Arduino IDE и на жидкокристаллический дисплей 1602a, для отображения информации использован русский шрифт для LCD и символы (в скетче есть подробные комментарии).

Скетч для метеостанции с DHT11 на Ардуино

#include <Wire.h>                 // библиотека для протокола IIC 
#include <LiquidCrystal_I2C.h>    // подключаем библиотеку LCD IIC
LiquidCrystal_I2C lcd(0x27,20,2); // присваиваем имя lcd для дисплея

#include "DHT.h"   // подключаем библиотеку для DHT11
DHT dht(2, DHT11); // к какому порту подключаем датчик

// создаем символ градуса и присваиваем имя "gradus"
byte gradus = {
0b01100,0b10010,0b10010,0b01100,0b00000,0b00000,0b00000,0b00000
};

// создаем русскую букву "П"
byte P = {
0b11111,0b10001,0b10001,0b10001,0b10001,0b10001,0b10001,0b00000
};

// создаем русскую букву "У"
byte Y = {
0b10001,0b10001,0b10001,0b01111,0b00001,0b00001,0b01110,0b00000
};

// создаем русскую букву "Л"
byte L = {
0b00111,0b01001,0b10001,0b10001,0b10001,0b10001,0b10001,0b00000
};

// создаем русскую букву "Ж"
byte ZH = {
0b10101,0b10101,0b10101,0b01110,0b10101,0b10101,0b10101,0b00000
};

// создаем русскую букву "Ь"
byte znak = {
0b10000,0b10000,0b10000,0b11110,0b10001,0b10001,0b11110,0b00000
};

void setup() {
  Serial.begin(9600); // запуск последовательного порта
  lcd.init();         // инициализация LCD дисплея
  lcd.backlight();    // включение подсветки дисплея

  lcd.createChar(1, gradus);
  lcd.createChar(2, P);
  lcd.createChar(3, Y);
  lcd.createChar(4, L);
  lcd.createChar(5, ZH);
  lcd.createChar(6, znak);
}

void loop() {
  // если нужны точные значение, то используйте float, вместо byte
  byte h = dht.readHumidity();    // считываем значение температуры
  byte t = dht.readTemperature(); // считываем значение влажности

  Serial.print("Temperature: ");
  Serial.println(t);   // отправляем значение температуры на монитор

  Serial.print("Humidity: ");
  Serial.println(h);   // отправляем значение температуры на монитор

  Serial.println(" "); // пустая строка

  lcd.setCursor(0,0);  // ставим курсор на 1 символ первой строки
  lcd.print("TEM");    // используем латинские буквы
  lcd.print(char(2));  // выводим русскую букву "П"
  lcd.print("EPAT");   // используем латинские буквы
  lcd.print(char(3));  // выводим русскую букву "У"
  lcd.print("PA: ");   // используем латинские буквы
  lcd.print(t);        // выводим значение температуры на LCD
  lcd.print(char(1));  // выводим знак градуса

  lcd.setCursor(2,1);  // ставим курсор на 3 символ второй строки
  lcd.print("B");      // используем латинские буквы
  lcd.print(char(4));  // выводим русскую букву "Л"
  lcd.print("A");      // используем латинские буквы
  lcd.print(char(5));  // выводим русскую букву "Ж"
  lcd.print("HOCT");   // используем латинские буквы
  lcd.print(char(6));  // выводим русскую букву "Ь"
  lcd.print(": ");     // используем латинские буквы
  lcd.print(h);        // выводим значение влажности на LCD
  lcd.print("%");      // выводим знак процент
  
  delay(1000);
}

Пояснения к коду:

  1. в скетче можно использовать до 8 русских букв и символов, при необходимости заменяйте буквы из кириллицы — латинскими буквами;
  2. скорость обновления данных замените на необходимое значение.

Заключение. Мы рассмотрели, как сделать простую домашнюю метеостанцию на Ардуино c дисплеем 1602а и датчиком температуры и влажности воздуха DHT11. Данный проект можно доработать, добавив к схеме еще больше датчиков для анализа метеоусловий. Также можно сделать беспроводную метеостанцию на Arduino Uno, используя блютуз или радио модули для передачи информации на расстояние.