Смартфоны        10.08.2023   

Схемы метеостанции на ардуино uno. Комнатная метеостанция на Arduino. Самое время собрать корпус

Однажды, исследуя просторы интернета наткнулся я на интересную плату Arduino. Меня очень заинтересовала эта плата. С ее помощью можно сделать самому робота, метеостанцию, сигнализацию и даже что-то посерьезней, например - «Умный Дом».

Прикупив сей девайс, начал изучать его особенности. Наигравшись со светодиодами, датчиком температуры и LCD дисплеем, решил сделать что-то такое интересное и то что может пригодиться мне дома.
И вот что получилось из этого…

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

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

Наверно, вам захотелось собрать такое же устройство, ну что же, не будем тянуть.

Возможности

Но для начала посмотрим, что наша метеостанция может делать:

1) Показывать текущую дату и время;
2) Показывать текущую температуру;
3) Показывать текущую влажность;
4) Показывать текущее атмосферное давление.

Состав

Что нам понадобится для реализации этой метеостанции:

1) Сам микроконтроллер Arduino (я использовал Arduino nano v3);
2) Датчик температуры и влажности Dht22 (маленькие погрешности в показаниях);
3) Барометр BMP085, он много чего может, например, измерение атмосферного давления, температуры, уровень над уровнем моря;
4) Часы реального времени DS3231 (он очень точный и легко настраивается);
5) Нам надо еще это выводить куда-то, мной был выбрал всем известный экран от Nokia 5110;
6) Прямые руки, без этого никак.

По необходимости:

7) Блок для батареек, для питания всей конструкции. Я питаю от Usb. От батареек не живет пару дней;
8) Переключатель, он тут для того, чтобы включать подсветку у экрана по мере необходимости;
9) Кусок фанеры и ножки.
10) Разъем для подключения блока питания.

Подключение

Теперь давайте рассмотрим, куда и как что подключать.

1) Первым будет наш экран:
pin 3 - Serial clock out (SCLK)
pin 4 - Serial data out (DIN)
pin 5 - Data/Command select (D/C)
pin 7 - LCD chip select (CS)
pin 6 - LCD reset (RST)
Питание 3.3V

3) Третьим будет барометр:
pin 4 - SDA
pin 5 - SCL
Питание 5V

Не забываем подключать питание и землю.

Код

Ну что, теперь самое интересное, это наш код.
Я постарался его хорошо комментировать, чтобы было понятно, но тут будут вставки и на английском с библиотек. Я думаю, с переводом проблем не будет.

Код

#include #include "DHT.h" #include #include #include "RTClib.h" #define DHTPIN 10 // 10 pin для датчика DHT22 #define DHTTYPE DHT22 RTC_DS1307 RTC; BMP085 dps = BMP085(); DHT dht(DHTPIN, DHTTYPE); long temp3 = 0, Pressure = 0, Altitude = 0; // pin 3 - Serial clock out (SCLK) // pin 4 - Serial data out (DIN) // pin 5 - Data/Command select (D/C) // pin 7 - LCD chip select (CS) // pin 6 - LCD reset (RST) LCD5110 myGLCD(3, 4, 5, 6, 7); extern unsigned char SmallFont; void setup() { myGLCD.InitLCD(); myGLCD.setFont(SmallFont); Wire.begin(); RTC.begin(); dht.begin(); delay(2000); dps.init(MODE_ULTRA_HIGHRES, 3200, true); // 3200 это 32 метра над уровнем моря (Питер на такой высоте располагается+ надо добавить несколько метров в зависимости от этажа на котором живете) } void loop() { dps.getPressure(&Pressure); dps.getAltitude(&Altitude); dps.getTemperature(&temp3); DateTime now = RTC.now(); // Sensor readings may also be up to 2 seconds "old" (its a very slow sensor) float h = dht.readHumidity(); // Read temperature as Celsius float t = dht.readTemperature(); myGLCD.setFont(SmallFont); // задаем маленький размер шрифта на экране myGLCD.clrScr(); // Очистка экрана myGLCD.print("Time=", LEFT, 0); //задаем время myGLCD.printNumI(int(now.hour()), 32, 0); // 32,0 означет 32=номер пропуска в строке, те откуда будем печатать. 0=номер строки myGLCD.print(":", 45, 0); myGLCD.printNumI(int(now.minute()), 50, 0); myGLCD.print(":", 62, 0); myGLCD.printNumI(int(now.second()), 67, 0); myGLCD.print("Date=", LEFT, 10); //задаем дату myGLCD.printNumI(int(now.day()), 32, 10); myGLCD.print("/", 44, 10); myGLCD.printNumI(int(now.month()), 50, 10); myGLCD.print("/", 62, 10); myGLCD.printNumI(int(now.year() - 2000), 68, 10); myGLCD.print("T=", LEFT, 20); //задаем температуру myGLCD.printNumF(t, 2, 13, 20); //Это температура с DHT22 myGLCD.print("/", 45, 20); myGLCD.printNumF(temp3 * 0.1, 2, 53, 20); //Это температура с барометра myGLCD.print("Hum=", LEFT, 30); // задаем влажность с DHT22 myGLCD.printNumF(h, 2, 28, 30); myGLCD.print("%", 63, 30); myGLCD.print("Pres=", LEFT, 40); // задаем атмосферное давление myGLCD.printNumF(Pressure / 133.3, 2, 31, 40); //рассчет атмосферного давления myGLCD.print("mm", 68, 40); // Serial.print(" Alt(m):"); кому надо, это текущая высота над уровнем моря // Serial.print(Altitude / 100); myGLCD.update(); // Вывод вместимого буфера на дисплей delay (1000); // Задержка 1 с }

Наблюдение за погодой - весьма увлекательное занятие. Я решил построить свою погодную станцию на базе популярного .

Прототип метеостанции выглядит так:

Функции моей метеостанции:

  • измерение и отображение комнатной и наружной температур;
  • отображение текущего времени (часы и минуты);
  • отображение текущих фазы Луны и лунного дня;
  • передача результатов измерений на компьютер через последовательное соединение;
  • передача результатов измерений по протоколу MQTT с помощью приложения на компьютере.


Hex
-файл
прошивки для (версия от 9 мая 2018 года) - .
Как прошить hex -файл в плату Arduino , я описал .

Микроконтроллер Arduino Nano 3.0

"Сердцем" моей метеостанции является микроконтроллер eBay ):

Для управления индикацией и опросом датчиков я использую таймер 1 Arduino , вызывающий прерывания с частотой 200 Гц (период - 5 мс).

Индикатор

Для отображения измеряемых показаний датчиков и текущего времени я подключил к Arduino четырехразрядный светодиодный индикатор Foryard FYQ-5643BH с общими анодами (аноды одинаковых сегментов всех разрядов объединены).
Индикатор содежит четыре семисегментных разряда и две разделительные (часовые) точки:

Аноды индикатора подключены через токограничивающие резисторы к выводам Arduino :

разряд 1 2 3 4
вывод A3 A2 D3 D9

Катоды сегментов подключены к выводам Arduino :

сегмент a b c d e f g p
вывод D7 D12 D4 D5 D6 D11 D8 D13

Сегмент индикатора светится, если на аноде соответствующего разряда высокий потенциал (1), а на катоде - низкий (0).

Я использую динамическую индикацию для отображения информации на индикаторе - в каждый момент времени активен только один разряд. Активные разряды чередуются с частотой 200 Гц (период отображения 5 мс). При этом для глаз мерцание сегментов незаметно.

Датчик температуры DS18x20

Для возможности удаленного измерения температуры я подключил датчик , который обеспечивает измерение наружной температуры в широких пределах. Датчик подключается к шине 1-Wire и имеет три вывода - питание (VCC ), данные (DAT ), земля (GND ):

вывод датчика VCC DAT GND
вывод Arduino 5V A1 GND

Между выводами VCC и DAT я включил подтягивающий резистор сопротивлением 4,7 кОм.

Для перевода между градусами Цельсия и Фаренгейта можно использовать такую табличку:

Я разместил датчик за окном дома в пластиковом корпусе от шариковой ручки:

\

В профессиональных метеостанциях для защиты термометра от прямых солнечных лучей и обеспечения циркуляции воздуха используется экран Стивенсона (англ. Stevenson screen ):

Датчик давления и температуры BMP280

Для измерения атмосферного давления традиционно используют ртутные барометры и барометры-анероиды.

В ртутном барометре атмосферное давление уравновешивается весом столба ртути, высота которого и ипользуется для измерения давления:

В барометре-анероиде используется сжатие и растяжение коробки под действием атмосферного давления:

Для измерения атмосферного давления и комнатной температуры в своей домашней метеостанции я использую датчик - маленький SMD -датчик размером 2 x 2,5 мм, основанный на пьезорезистивной технологии:

Платка с датчиком приобретена на торговой площадке eBay :

Датчик подключается к шине I2C (контакт данных - SDA/SDI , контакт синхронизации - SCL/SCK ):

вывод датчика VCC GND SDI SCK
вывод Arduino 3V3 GND A4 A5

Adafruit - файлы Adafruit_Sensor.h , Adafruit_BMP280.h , Adafruit_BMP280.cpp .

Единицы измерения атмосферного давления

Датчик через функцию readPressure выдает значение атмосферного давления в паскалях. Основной единицей измерения атмосферного давления служит гектопаскаль (гПа) (1 гПа = 100 Па), аналогом которого является внесистемная единица "миллибар " (мбар) (1 мбар = 100Па = 1гПа). Для перевода между часто используемой внесистемной единицей измерения давления "миллиметр ртутного столба " (мм рт. ст.) и гектопаскалями используются соотношения:
1гПа = 0,75006 мм рт. ст. ≈ 3/4 мм рт.ст.; 1 мм рт.ст. =1,3332 гПа ≈ 4/3 гПа.

Зависимость атмосферного давления от высоты над уровнем моря

Атмосферное давление может быть представлено как в абсолютной, так и в относительной форме.
Абсолютное давление QFE (англ. absolute pressure ) – это актуальное атмосферное давление, не учитывающее поправку над уровнем моря.
Атмосферное давление уменьшается примерно на 1 гПа при повышении высоты на 1 м:

Барометрическая формула позволяет определить коррекцию показаний барометра для получения относительного давления (в мм рт. ст.):
$\Delta P = 760 \cdot (1 - {1 \over {10^ { {0,0081350 \cdot H} \over {T + 0,00178308 \cdot H} }}})$ ,
где $T$ - средняя температура воздуха по шкале Ранкина, °Ra , $H$ - высота над уровнем моря, футы.
Перевод градусов Цельсия в градусы Ранкина:
$^{\circ}Ra = {^{\circ}C \cdot 1,8} + 491,67$
Барометрическая формула используется при барометрическом нивелировании - определении высот (с погрешностью 0,1 - 0,5 %). В формуле не учитывается влажность воздуха и изменение ускорения свободного падения с высотой. Для небольших перепадов высоты эту экспоненциальную зависимость можно с достаточной точностью аппроксимировать линейной зависимостью.
Относительное давление QNH (англ. relative pressure , Q-code Nautical Height ) – это атмосферное давление, учитывающее поправку к среднему уровню моря (англ. Mean Sea Level, MSL ) (для ISA и температуры 15 градусов Цельсия), и первоначально выставляется с учётом высоты, на которой находится метеостанция. Его можно узнать из данных метеослужбы, показаний откалиброванных приборов в публичных местах, аэропорту (из сводок METAR ), из Интернета.
Например, для расположенного рядом аэропорта Гомель (UMGG ) я могу посмотреть сводку фактической погоды METAR на ru.allmetsat.com/metar-taf/russia.php?icao=UMGG :
UMGG 191800Z 16003MPS CAVOK M06/M15 Q1014 R28/CLRD// NOSIG ,
где Q1014 - давление QNH на аэродроме равно 1014 гПа.
Историю сводок METAR можно получить на aviationwxchartsarchive.com/product/metar .
За нормальное относительное давление воздуха QNH принимается давление 760 мм рт. ст. или 1013,25 гПа (при температуре 0ºС, под широтой 45º Северного или Южного полушария).
Я выставил для барометра-анероида давление QNH с помощью винта настройки чуткости:

Прогноз погоды

Анализ изменения давления позволяет строить прогноз погоды, причем его точность тем выше, чем более резко меняется давление. Например, старое эмпирическое правило мореплавателей гласит - падение давления на 10 гПа (7,5 мм рт. ст.) за период 8 часов говорит о приближении сильного ветра.

Откуда же возникает ветер? Воздух стекается к центру области низкого давления, возникает ветер - горизонтальное перемещение воздуха из областей высокого давления в области низкого давления (высокое атмосферное давление выдавливает воздушные массы в область низкого атмосферного давления). Если давление очень низкое, ветер может достигать силы шторма . При этом в области пониженного давления (барическая депрессия или циклон) теплый воздух поднимается вверх и формирует облака, которые часто приносят дождь или снег .

За направление ветра в метеорологии принимается направление, откуда дует ветер:

Это направление сводится к восьми румбам.

Для предсказания погоды на основе атмосферного давления и направления ветра часто используется алгоритм Zambretti .

Датчик влажности

Для определения относительной влажности воздуха я использую модуль DHT11 (приобретен на торговой площадке eBay ):

Датчик влажности DHT11 имеет три вывода - питание (+ ), данные (out ), земля (- ):

вывод датчика + out -
вывод Arduino 5V D10 GND

Для работы с датчиком я использую библиотеку от Adafruit - файлы DHT.h , DHT.cpp .

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

Для человека оптимальный интервал влажности воздуха - 40 ... 60 %.

Часы реального времени

В качестве часов реального времени я применил модуль RTC DS1302 (платка с часиками приобретена на торговой площадке eBay ):

Модуль DS1302 подключается к шине 3-Wire . Для использования этого модуля совместно с Arduino разработана библиотека iarduino_RTC (от iarduino.ru ).

Плата с модулем DS1302 имеет пять выводов, которые я соединил с выводами платы Arduino Nano :

вывод RTC VCC GND RST CLK DAT
вывод Arduino 5V GND D2 D1 D0

Для сохранения верных показаний часов при отключенном питании в гнездо на плате я вставил батарейку CR2032 .

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

Передача данных на компьютер и работа по протоколу MQTT

Для передачи данных через последовательное соединение к Arduino подключается USB -UART преобразователь:

Вывод Arduino используется для передачи данных в формате 8N1 (8 бит данных, без бита четности, 1 стоп-бит) со скоростью 9600 бит/с. Данные передаются пакетами, причем длина пакета - 4 символа. Передача данных осуществляется в "bit-bang " режиме, без использования аппаратного последовательного порта Arduino .

Формат передаваемых данных:

Параметр 1-й байт 2-й байт 3-й байт 4-й байт
наружная температура o пробел либо минус десятки градусов либо пробел единицы градусов
комнатная температура i пробел либо минус десятки градусов либо пробел единицы градусов
атмосферное давление p сотни мм р. ст. десятки мм рт.ст. единицы мм рт. с.
относительная влажность h пробел десятки процентов либо пробел единицы процентов
текущее время десятки часов единицы часов десятки минут единицы минут

MQTT

Golang приложение - клиент протокола MQTT , отправляющую принятую от метеостанции информации на сервер (MQTT -брокер) :

Сервис позволяет создать акаунт с бесплатным тарифным планом "" (ограничения: 10 соединений, 10 Кб/с):

Для мониторинга показаний метеостанции при этом можно использовать Android -приложение :

Питание

Для питания метеостанции я использую зарядное устройство от старого мобильного телефона Motorola , выдающее напряжение 5 В с током до 0,55 А и подключаемое к контактам 5V (+) и GND (-):

Также можно использовать для питания батарейку напряжением 9 В, подключаемую к контактам VIN (+) и GND (-).

Эксплуатация метеостанции

При запуске происходит инициализация и проверка датчиков.

При отсутствии датчика DS18x20 выдается ошибка "E1", при отсутствии датчика - ошибка "E3".

Затем запускается рабочий цикл метеостанции:

  • измерение и отображение наружной температуры;
  • измерение и отображение комнатной температуры;
  • измерение и отображение атмосферного давления и тренда его изменения;
  • измерение и отображение относительной влажности воздуха;
  • отображение текущего времени;
  • отображение фазы Луны и лунного дня.


Видео работы моей метеостанции доступно на моем -канале: https://youtu.be/vVLbirO-FVU

Отображение температуры

При измерении температуры индицируется две цифры температуры и для отрицательной температуры знак "минус" (с символом градуса в крайнем правом разряде);
для наружной температуры знак градуса отображается вверху:


для комнатной температуры - внизу:

Отображение давления

При измерении давления индицируются три цифры давления в мм ртутного столба (с символом "P " в крайнем правом разряде):

Если давление резко упало, то вместо символа "P " в крайнем правом разряде отображается символ "L ", если резко выросло - то "H ". Критерий резкости изменения - 8 мм рт. ст. за 8 часов:

Так как моя метеостанция отображает абсолютное давление (QFE ), то показания оказываются несколько заниженными по сравнению со сведениями в сводке METAR (в которой приводится QNH ) (14 UTC 28 марта 2018 года):

Отношение давлений (по сведениями ATIS ) составило ${1015 \over 998} = 1,017$. Возвышение аэропорта Гомель (код ИКАО UMGG ) над уровнем моря составляет 143,6 м. Температура по данным ATIS составляла 1 °C .

Показания моей метеостанции практически совпали с абсолютным давлением QFE по сведениями ATIS !

Максимальное/минимальное давления (QFE ), зарегистрированные моей метеостанцией за все время наблюдений:

Отображение относительной влажности воздуха

Относительная влажность воздуха отображается в процентах (в двух правых разрядах отображается символ процента):

Отображение текущего времени

Текущее время отображается на индикаторе в формате "ЧЧ:ММ", причем разделительное двоеточие мигает раз в секунду:

Отображение фаз Луны и лунного дня

Первые два разряда индикатора отображают текущую лунную фазу, а следующие два - текущий лунный день:

У Луны выделяются восемь фаз (приведены английские и русские (синим цветом - неточные) названия):

На индикаторе фазы отображаются пиктограммами:

фаза пиктограмма
растущий серп (полумесяц)
убывающий серп (полумесяц)

Передача данных на компьютер

Если соединить метеостанцию с USB -UART преобразователем (например, на базе микросхемы CP2102 ), подключенным к USB -порту компьютера, то можно с помощью терминальной программы наблюдать передаваемые метеостанцией данные:

Я разработал на языке программирования golang программу, ведущую журнал метеонаблюдений и отправляющую данные в сервис , и их можно просматривать на Android -смартфоне с помощью приложения :

По данным журнала метеонаблюдений можно, например, строить график изменения атмосферного давления:
пример графика с заметным минимумом давления


пример графика с незначительным ростом давления

Планируемые доработки:

  • добавление датчиков направления и скорости ветра

В метеостанциях для измерения скорости ветра используется трехчашечный анемометр (1), а для определения направления ветра - флюгер (2):

Также для измерения скорости ветра используются термоанемометры с нитью накала (англ. hot wire anemometer ). В качестве нагреваемой проволоки можно использовать вольфрамовую нить накала от лампочки с разбитым стеклом. В промышленно выпускаемых термоанемометрах датчик обычно располагается на телескопической трубке:

Принцип действия этого прибора заключается в том, что тепло отводится от нагревательного элемента вследствие конвекции воздушным потоком - ветром. При этом сопротивление нити накала определяется температурой нити. Закон изменения сопротивления нити накала $R_T$ от температуры $T$ имеет вид:
$R_T = R_0 \cdot (1 + {\alpha \cdot (T - T_0)})$ ,
где $R_0$ - сопротивление нити при температуре $T_0$, $\alpha$ - температурный коэффициент сопротивления (для вольфрама $\alpha = 4,5\cdot{10^{-3} {^{\circ}{C^{-1}}}}$).

С изменением скорости воздушного потока изменяется температура при неизменном токе накала (анемометр с постоянным током, англ. CCA ). Если температура нагревательного элемента поддерживается постоянной, то ток через элемента будет пропорционален скорости воздушного потока (анемометр с постоянной температурой, англ. CTA ).

Продолжение следует

Загружать прошивку желательно до подключения компонентов, чтобы убедиться в том, что плата рабочая. После сборки можно прошить ещё раз, плата должна спокойно прошиться. В проектах с мощными потребителями в цепи питания платы 5V (адресная светодиодная лента, сервоприводы, моторы и проч.) необходимо подать на схему внешнее питание 5V перед подключением Arduino к компьютеру, потому что USB не обеспечит нужный ток, если например лента его потребует. Это может привести к выгоранию защитного диода на плате Arduino. Гайд по скачиванию и загрузке прошивки можно найти под спойлером на следующей строчке.

Содержимое папок в архиве

  • libraries – библиотеки проекта. Заменить имеющиеся версии
  • firmware – прошивки для Arduino
  • schemes – схемы подключения компонентов

Дополнительно

  • Как показал эксперимент, снаружи корпуса датчик температуры показывает на 0.5 градуса меньше, чем внутри! Нужно более удачно компоновать электронику, отводить и экранировать тепло от греющихся элементов…

  • Если дисплей показывает слишком тускло/на белом фоне
    На плате драйвера дисплея (к которой подключаются провода) есть крутилка контрастности, с её помощью можно подстроить контраст на нужный. Также контрастность зависит от угла взгляда на дисплей (это же LCD) и можно настроить дисплей на чёткое отображение даже под углом “дисплей на уровне пупка, смотрим сверху”. А ещё контрастность сильно зависит от питания: от 5V дисплей показывает максимально чётко и ярко, тогда как при питании от USB через Arduino напряжение будет около 4.5V (часть падает на защитном диоде по линии USB), и дисплей показывает уже не так ярко. Вывод настраивайте крутилкой при внешнем питании от 5V!

  • Если датчик CO2 работает некорректно (инфа от Евгения Иванова)
    Ну там в папке библиотеки сенсора в examples есть скетчи для калибровки. также ее можно запустить втупую замкнув на землю разъем “HD” на 7+ секунд.
    Само собой вот прямо на улице на морозе этим заниматься не обязательно… можно просто в бутылку набрать свежего воздуха с датчиком внутри и запечатать. калибровка проводится минимум 20 минут..
    По-умолчанию датчик поставляется с включенной автокалибровкой, которая происходит каждый день, и если датчик используется в невентелируемом помещении, то эта калибровка быстро уводит значения от нормы за горизонт, потому ее нужно обязательно отключать.
    Документация .

  • Автокалибровка датчика CO2 отключена в скетче!

  • Если у вас не работает датчик BME280 , скорее всего у него отличается адрес. В проекте используется библиотека Adafruit_BME280, у которой нет отдельной функции смены адреса, поэтому адрес задаётся вручную в файле библиотеки Adafruit_BME280.h почти в самом начале файла (лежит в папке Adafruit_BME280 в вашей папке библиотек, вы должны были её туда установить ), у моего модуля был адрес 0x76. Как узнать адрес своего модуля BME280? Есть специальный скетч, называется i2c scanner. Его можно нагуглить, можно . Прошиваете данный скетч, открываете порт и получаете список адресов подключенных к шине i2c устройств. Чтобы остальные модули вам не мешали – можно их отключить и оставить только BME280. Полученный адрес указываем в библиотеке, сохраняем файл и загружаем прошивку метео-часов. Всё!

  • Если отстают часы , проблема скорее всего в питании схемы. Если при смене блока питания на более качественный проблема не уходит, повесьте конденсатор по питанию RTC модуля (прям на плату на VCC и GND паять): обязательно керамический, 0.1-1 мкФ (маркировка 103 или 104, смотрите таблицу маркировок). Также можно поставить электролит (6.3V, 47-100 мкФ)

Настройки в прошивке

#define RESET_CLOCK 0 // сброс часов на время загрузки прошивки (для модуля с несъёмной батарейкой). Не забудь поставить 0 и прошить ещё раз! #define SENS_TIME 30000 // время обновления показаний сенсоров на экране, миллисекунд #define LED_MODE 0 // тип RGB светодиода: 0 - главный катод, 1 - главный анод #define LED_BRIGHT 255 // яркость светодиода СО2 (0 - 255) #define BLUE_YELLOW 1 // жёлтый цвет вместо синего (1 да, 0 нет) но из за особенностей подключения жёлтый не такой яркий #define DISP_MODE 1 // в правом верхнем углу отображать: 0 - год, 1 - день недели, 2 - секунды #define WEEK_LANG 1 // язык дня недели: 0 - английский, 1 - русский (транслит) #define DEBUG 0 // вывод на дисплей лог инициализации датчиков при запуске #define PRESSURE 1 // 0 - график давления, 1 - график прогноза дождя (вместо давления). Не забудь поправить пределы гроафика // пределы отображения для графиков #define TEMP_MIN 15 #define TEMP_MAX 35 #define HUM_MIN 0 #define HUM_MAX 100 #define PRESS_MIN -100 #define PRESS_MAX 100 #define CO2_MIN 300 #define CO2_MAX 2000

Как большинство работающих людей, занятие собственными проектами отнимает единственно оставшееся свободное время. Поэтому уже давно не творил и «чесались руки» что-либо сделать. Данная возможность появилась как ни странно в университете. За окном сентябрь, 4 курс и надвигающийся курсовой по схемотехнике. Нам сказали, что курсовые можно будет делать в двух вариациях: бумажном и «железе».

На протяжении 5 лет бумажный курсовой в нашем университете делался по принципу «возьми старые и собери их воедино». Такой подход меня не устраивал своей рутинностью, поэтому я сразу же выбрал курсовой в «железе». В качестве сердца курсовых был предложен микроконтроллер Arduino ввиду своей легкообучаемости. После определения с типом курсового оставался ещё один вопрос: а что именно бы сделать. Так как опыта в программировании микроконтроллеров не было, то сразу же открыл гугл и начал изучать существующие проекты. Проектов много, некоторые из них довольно простые, некоторые гениальны (3D сканер, например), но подавляющее большинство не имело практического применения. А мне хотелось именно того, что не валялось бы потом на полке и не собирало там пыль. После получасового экскурса в мир Arduino, меня заинтересовало тема домашних метеостанций, да и проекты показались не очень сложными в реализации (что в основном и подкупило новичка).

Вот так была выбрана тема для курсового и со временем проблем вроде как не намечалось.

Выбор компонентов

Просматривая разные проекты я понимал, что мне вполне достаточно будет Nano или даже Pro Mini, но всё-таки выбрал Arduino Uno в надежде, что программирование для Arduino мне понравится и в дальнейшем реализую ещё какие-нибудь проекты. Паяльник до этого в руках ни разу не держал, поэтому для более легкой разработки решил также приобрести Sensor Shield v4.

Подробнее

Плата способствует быстрому подключению датчиков, модулей, серво моторов, интерфейсов Serial и I2C, а также выводит все порты контроллера формфактора Duemilanova/Uno(также может быть подключена и в серию мега, но с ограничениями и вытекающими последствиями). Поддерживает другие шилды поверх себя.


В качестве источников для метеорологических данных выбрал следующие датчики:


С датчиками определился. Но что делать с данными, поступающими от датчиков. Решил выводить на дисплей. Картинку хотелось цветную, поэтому монохромные решения отбросил сразу. После нескольких минут поиска был выбран TFT дисплей ST7735 размером 1,8 дюймов.

Подробнее

Поскольку дисплей использует 4-проводной SPI протокод для связи и имеет свой собственный пикселе-адресуемый буфер кадра, он может использоваться с любыми видами микроконтроллеров. 1.8-дюймовый дисплей имеет 128x160 цветных пикселя. Также имеется слот для карты памяти microSD, следовательно, можно легко загружать полноцветные растровые изображения из FAT16 / FAT32 файловой системы microSD карты.

Характеристики:

  • Диагональ дисплея - 1.8 дюймов, разрешение 128x160 пикселей, 18-битный цвет (262 144 цвета)
  • Контроллер со встроенной пиксельной адресацией буфера видеопамяти
  • Встроенный слот для microSD - использует более 2 цифровых линий
  • Совместим с 3.3 и 5V
  • Габариты: 34 мм х 56 мм х 6,5 м


Программирование контроллера Arduino

После того, как определились с компонентами для метеостанции, начнём программирование контроллера. Для прошивки Arduino использовалась среда разработки Arduino IDE. Также использовал библиотеки от Adafruit.

Перед тем, как перейти к скетчу, рассмотрим функционал:

  • Показания снимаются с датчиков каждые 10 секунд и обновляются на экране только те показатели, которые были изменены по сравнению с прошлым измерением
  • Реализована передача данных по COM порту

Скетч

#include // library for communication with I2C devices #include // Core library for all sensors #include // library for BMP180 #include // Core graphics library #include // Hardware-specific library #include // library for communication with SPI devices #include "dht.h" // library for DHT #define DHT22_PIN 2 // connect data pin of DHT22 to 2 digital pin #define TFT_CS 10 // connect CS pin of TFT to 10 digital pin #define TFT_RST 9 // connect RST pin of TFT to 9 digital pin // you can also connect this to the Arduino reset // in which case, set this #define pin to 0! #define TFT_DC 8 // connect DC pin of TFT to 8 digital pin Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); //initialize TFT #define TFT_SCLK 13 // connect SCLK pin of TFT to 13 digital pin #define TFT_MOSI 11 // connect MOSI pin of TFT to 11 digital pin dht DHT; Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(10085); //initialize BMP180 int bmpFlag = 0; struct { uint32_t total; uint32_t ok; uint32_t crc_error; uint32_t time_out; uint32_t connect; uint32_t ack_l; uint32_t ack_h; uint32_t unknown; } stat = { 0,0,0,0,0,0,0,0}; // struct for dht status void setup(void) { Serial.begin(9600); Serial.println("Meteo Test"); Serial.println(""); if(!bmp.begin()) // check connection for BMP180 { Serial.print("Ooops, no BMP180 detected ... Check your wiring or I2C ADDR!"); bmpFlag = 1; } tft.initR(INITR_BLACKTAB); // Initialize TFT and fill with black color tft.fillScreen(ST7735_BLACK); tft.setRotation(tft.getRotation() + 1); tft.setTextSize(1.5); delay(500); // delay in order to ensure that TFT was initialized } // last measured data float oldTemperature = 0, oldAltitude = 0, oldPressure = 0, oldDHTHumidity = 0, oldDHTTemperature; bool wasUpdate = false; void loop(void) { if(Serial.available() > 0) // we have data is Serial port { Serial.read(); // read byte from serial port and send last measured data printValue("Pressure", oldPressure, " hPa", false); printValue("Temperature", oldTemperature, " C", false); printValue("Altitude", oldAltitude, " m", false); printValue("Humidity", oldDHTHumidity, "%", false); printValue("DHT_temperature", oldDHTTemperature, " C", false); Serial.println("END_TRANSMISSION"); } sensors_event_t event; float temperature, altitude; if(bmpFlag == 0){ bmp.getEvent(&event); // get data from BMP180 if (event.pressure) { bmp.getTemperature(&temperature); float seaLevelPressure = SENSORS_PRESSURE_SEALEVELHPA; altitude = bmp.pressureToAltitude(seaLevelPressure, event.pressure, temperature); } else { Serial.println("Sensor error"); } } uint32_t start = micros(); int chk = DHT.read22(DHT22_PIN);// get data from DHT22 uint32_t stop = micros(); stat.total++; switch (chk) // check status of DHT22 { case DHTLIB_OK: stat.ok++; break; case DHTLIB_ERROR_CHECKSUM: stat.crc_error++; Serial.print("Checksum error,\t"); break; case DHTLIB_ERROR_TIMEOUT: stat.time_out++; Serial.print("Time out error,\t"); break; case DHTLIB_ERROR_CONNECT: stat.connect++; Serial.print("Connect error,\t"); break; case DHTLIB_ERROR_ACK_L: stat.ack_l++; Serial.print("Ack Low error,\t"); break; case DHTLIB_ERROR_ACK_H: stat.ack_h++; Serial.print("Ack High error,\t"); break; default: stat.unknown++; Serial.print("Unknown error,\t"); break; } if(bmpFlag != 0 || !event.pressure) // update data { tft.fillRect(0, 30, 160, 6, ST7735_BLACK); tft.setCursor(0, 30); tft.setTextColor(ST7735_RED); printValue("ERROR BMP INITIALIZATION", 0, "", true); } else { if(event.pressure != oldPressure) { tft.fillRect(0, 30, 160, 7, ST7735_BLACK); tft.setCursor(0, 30); tft.setTextColor(ST7735_RED); printValue("Pressure", event.pressure, " hPa", true); oldPressure = event.pressure; wasUpdate = true; } if(temperature != oldTemperature) { tft.fillRect(0, 38, 160, 7, ST7735_BLACK); tft.setCursor(0, 38); tft.setTextColor(ST7735_WHITE); printValue("Temperature", temperature, " C", true); oldTemperature = temperature; wasUpdate = true; } if(altitude != oldAltitude) { tft.fillRect(0, 46, 160, 7, ST7735_BLACK); tft.setCursor(0, 46); tft.setTextColor(ST7735_BLUE); printValue("Altitude", altitude, " m", true); oldAltitude = altitude; wasUpdate = true; } } if(DHT.humidity != oldDHTHumidity) { tft.fillRect(0, 54, 160, 7, ST7735_BLACK); tft.setCursor(0, 54); tft.setTextColor(ST7735_GREEN); printValue("Humidity", DHT.humidity, "%", true); oldDHTHumidity = DHT.humidity; wasUpdate = true; } if(DHT.temperature != oldDHTTemperature) { tft.fillRect(0, 80, 160, 7, ST7735_BLACK); tft.setCursor(0, 80); tft.setTextColor(ST7735_YELLOW); printValue("DHT_temperature", DHT.temperature, " C", true); oldDHTTemperature = DHT.temperature; wasUpdate = true; } if(wasUpdate) { Serial.println("END_TRANSMISSION"); } wasUpdate = false; delay(10000); } void printValue(char* title, double value, char* measure, bool tftPrint) { if(tftPrint) // print data to TFT { tft.print(title); tft.print(": "); tft.print(value); tft.println(measure); } Serial.print(title); // send data to Serial port Serial.print(": "); Serial.print(value); Serial.println(measure); }

Самое время собрать корпус

Главным условием курсового было рабочий прототип в презентабельном виде. Поэтому пришлось купить корпус и, вооружившись напильником, любым способом засунуть метеостанцию в корпус.

В местном магазине радиоэлектроники был приобретён корпус.

Корпус

(На фото корпус немного не такой. У меня крышка прозрачная)



Затем, орудуя напильником, были проделаны отверстия для вывода датчиков и подачи питания. Датчики решил вывести наружу, так как во время тестирования системы без корпуса заметил, что задняя часть экрана сильно нагревается, что скажется на температуре внутри корпуса.

Корпус с отверстиями для датчиков и питания



Так как пришлось припаивать ножки к 2 датчикам и у одного из них я спалил дорожку, то решил не испытывать судьбу и не припаивать провода к датчикам (потренируюсь на чём-нибудь другом), а для того чтобы соединение было более-менее надёжным, решил перемотать изолентой.

Система перед "запихиванием" в корпус



Так как корпус намного больше Arduino (меньше не было), пришлось придумывать подпорку, чтобы плата не ездила внутри корпуса. Также из паралона была вырезана фигура, а в ней прямоугольник для экрана с целью скрыть внутренности корпуса. Суперклея под рукой не было, поэтому пришлось садить на двусторонний скотч.

Чудо-юда рыба-кит



Прикручиваем крышку, подключаем питание и ждём.

Законченная метеостанция в корпусе



После вывода результатов на экран, выявляем неприятную ошибку измерения влажности: DHT22 усердно выдаёт цифру 99,90% (крайне редко бывает 1,00%). Начинаем разбираться в чём проблема. Первое, что делаем - смотрим вывод значений в COM порт. Вроде всё нормально. После нексольких перезаливок, разборок и сборок корпуса в голову приходит мысль поискать ответ в гугле. Как и ожидалось русский гугл ничего дельного не сказал. Окей. Начинаем искать на английском и на одном из форумов натыкаемся на ребят с похожей проблемой. Первые четыре страницы обсуждения ничего дельного не дают, а на пятой странице находим ответ на наш вопрос:
Humidity sensors can easily be affected by the wrong gasses or very long exposure to high humidity IIRC. In the datasheet there is a procedure how to «reset» the sensor, you could give it a try.

Оставался вопрос только в том, когда и как я успел навредить DHT22. Но подходило время сдавать курсовой и поэтому я оставил решение этой проблемы на потом.

Послесловие

Курсовой был сдан. Метеостанция отложена на неопределенное время до закрытия всех хвостов в университете. Однако, к метеостанции пришлось вернутся раньше, чем я думал. Так сложилось, что в середине ноября я поменял рабочее место и в новой команде я познакомился с людьми, которые интересуются платформой Arduino и им подобными. Поэтому мой интерес к данной платформе не успев остыть, разгорелся снова. Я достал свою метеостанцию, подключил к компьютеру и вспомнил, что я реализовывал передачу данных с Arduino по COM порту. И тут мне пришла в голову идея, написать программу, принимающую данные через COM порт от Arduino и передавать эти данные на народный мониторинг , но это уже совсем другая история.

Также хотелось бы иметь беспроводные датчики и всё-таки реализовать метеостанцию на Arduino Pro Mini. Поэтому мною были заказаны 4 Arduino Pro Mini с питанием 3,3В, 4 радиомодуля nRF24L01+ и ещё кое-какие дополнительные датчики, о чём я также постараюсь рассказать в следующий раз. А пока я жду посылки, в планах реализовать подключение часов реального времени для возможности сохранения времени обновления данных и самих данных на microSD карту при условии отсутствия соединения с клиентом по COM порту.

Вы можете помочь и перевести немного средств на развитие сайта



2018-06-18 в 15:08

Данная погодная станция обеспечивает постоянное получение сведений о состоянии погодных условий. Проект основан на плате микроконтроллеров Arduino, а данные выводятся на LCD экран. Ранее был проект вывода данных с датчиков на веб-страницу с помощью W5100 . Небольшой размер "железа" позволяет поместить устройство в маленьком пластиковом коробе, части которого изготовлены при помощи лазерной резки.

Датчик уровня воды и снега.
Индикатор уровня воды используется для вывода уровня воды в баке во избежании его переполнения.

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

Фоторезисторы, также известные как светозависимые резисторы (LDR), являются светочувствительными устройствами, наиболее часто используемыми для определения наличия или отсутствия света, или для измерения интенсивности света. В темноте их сопротивление очень велико, но когда датчик LDR подвергается воздействию света, сопротивление резко падает, вплоть до нескольких Ом.

LCD1602 с шиной I2C. Синий потенциометр на ЖК-дисплее I2C 1602 используется только для подсветки.

I2C использует только две линии, Serial DataLine (SDA) и Serial Clock Line (SCL), которые подключаются к резисторам. Типичные напряжения - +5 В или +3,3 В, хотя допускаются системы с другими напряжениями.

DS1302 - часики реального времени.
Часы основаны на интегрированной микросхеме DS1302, внутри которой есть часы / календарь в реальном времени и 31 байт статической ОЗУ. Формат времени можно увидеть как hh/mm/ss, а формат даты - yyyy/mm/dd. Так же можно высчитать день недели.

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

Инфракрасный приемник и пульт дистанционного управления

Эти два компонента работают вместе: ИК-приемник позволяет получать данные с пульта дистанционного управления. Уже рассказывал как собрать контроллер вытяжки с управлением от пульта телевизора. Данные зависят от того, какую кнопку вы хотите нажать. Были выбраны следующие кнопки для назначения их определенным функциям:

Клавиша 0 - позволяет увидеть время и дату

Клавиша 1 - позволяет увидеть данные с датчиков DHT11 и LM35

Клавиша 2 - позволяет увидеть в процентах уровень освещенности

Клавиша 3 - позволяет увидеть в миллиметрах уровень жидкости

Клавиша "Повтор" - прокручивает все окна с интервалом в 4 секунды

Сборка корпуса.
Рассмотрев размер устройства, мы продолжили строительство корпуса из плексигласа. Размеры сторон с их взаимными блокирующими сиденьями и отверстиями для выхода проводов датчиков были рассчитаны с помощью программного обеспечения Autocad, после чего мы занялись вырезанием, используя машину для лазерной резки. И, наконец, мы собрали все с помощью мощного клея.
Файл исходник - Скачать.

Схема устройства была сделана в программной среде fritzing ().

Разрабатывали код в среде Arduino IDE, использовали все необходимые библиотеки. И вот что у нас получилось:

Это главный экран, который пользователь может видеть, когда мы включаем плату. При включении появляется надпись «Arduino Weather Station». Вы также можете увидеть эту надпись после каждого обращения к AWS.

Экран даты и времени, к которому пользователь может получить доступ, просто нажав кнопку 0 на пульте дистанционного управления. При нажатии экран имеет задержку в 10 секунд, а затем возвращается на главный экран.

Экран, который показывает данные, полученные датчиками DHT11 и LM35 относительно влажности и температуры соответственно. Он "привязан" к кнопке 1 на пульте дистанционного управления, и когда она нажимается, экран имеет задержку в 10 секунд, а затем возвращается на главный экран.

Экран уровень освещенности. Привязан к кнопке 2 на пульте ДУ.

Этот экран показывает уровень жидкости в баке. Он подключен к кнопке 3 на пульте дистанционного управления.

Сама программа станции

//include sketch libraries #include #include //clock library #include //clock library #include //clock library #include //dht11 library #include //LCD library #include //Wire for LCD library #define lmPin A1 //LM35 attach to A1 LiquidCrystal_I2C lcd(0x27 , 16 , 2 ); // set the LCD address to 0x27 for a 16 chars and 2 line display dht DHT; //create a variable type of dht const int DHT11_PIN = 4 ; //attach dht11 to pin 4 const int waterSensor = 0 ; //set water sensor variable int waterValue = 0 ; //variable for water sensor int mmwaterValue = 0 ; int sensorPin = A3; // select the input pin for the potentiometer int luce = 0 ; //variable for the ldr int pluce = 0 ; //variable for the ldr float tem = 0 ; //variable for the temperature long lmVal = 0 ; //variable for the LM35 //ir const int irReceiverPin = 3 ; IRrecv irrecv(irReceiverPin); //Creates a variable of type IRrecv decode_results results; //define clock variable uint8_t RST_PIN = 5 ; //RST pin attach to uint8_t SDA_PIN = 6 ; //IO pin attach to uint8_t SCL_PIN = 7 ; //clk Pin attach to /* Create buffers */ char buf; char day; /* Create a DS1302 object */ DS1302 rtc(RST_PIN, SDA_PIN, SCL_PIN);//create a variable type of DS1302 void print_time() { /* Get the current time and date from the chip */ Time t = rtc.time(); /* Name the day of the week */ memset(day, 0 , sizeof (day)); switch (t.day) { case 1 : strcpy(day, "Sun" ); break ; case 2 : strcpy(day, "Mon" ); break ; case 3 : strcpy(day, "Tue" ); break ; case 4 : strcpy(day, "Wed" ); break ; case 5 : strcpy(day, "Thu" ); break ; case 6 : strcpy(day, "Fri" ); break ; case 7 : strcpy(day, "Sat" ); break ; } /* Format the time and date and insert into the temporary buffer */ snprintf(buf, sizeof (buf), "%s %04d-%02d-%02d %02d:%02d:%02d" , day, t.yr, t.mon, t.date, t.hr, t.min , t.sec); /* Print the formatted string to serial so we can see the time */ Serial .println (buf); lcd.setCursor (2 , 0 ); lcd.print (t.yr); lcd.print ("-" ); lcd.print (t.mon / 10 ); lcd.print (t.mon % 10 ); lcd.print ("-" ); lcd.print (t.date / 10 ); lcd.print (t.date % 10 ); lcd.print (" " ); lcd.print (day); lcd.setCursor (4 , 1 ); lcd.print (t.hr); lcd.print (":" ); lcd.print (t.min / 10 ); lcd.print (t.min % 10 ); lcd.print (":" ); lcd.print (t.sec / 10 ); lcd.print (t.sec % 10 ); } void setup () { //clock Serial .begin (9600 ); rtc.write_protect(false); rtc.halt(false); //ir irrecv.enableIRIn(); //enable ir receiver module lcd.init(); //initialize the lcd lcd.backlight(); //open the backlight pinMode (sensorPin, INPUT ); Time t(2017 , 12 , 03 , 10 , 15 , 00 , 1 );//initialize the time /* Set the time and date on the chip */ rtc.time(t); } void loop () { lcd.setCursor (0 , 0 ); lcd.print ("A" ); delay (50 ); lcd.setCursor (1 , 0 ); lcd.print ("r" ); delay (50 ); lcd.setCursor (2 , 0 ); lcd.print ("d" ); delay (50 ); lcd.setCursor (3 , 0 ); lcd.print ("u" ); delay (50 ); lcd.setCursor (4 , 0 ); lcd.print ("i" ); delay (50 ); lcd.setCursor (5 , 0 ); lcd.print ("n" ); delay (50 ); lcd.setCursor (6 , 0 ); lcd.print ("o" ); delay (50 ); lcd.setCursor (8 , 0 ); lcd.print ("W" ); delay (50 ); lcd.setCursor (9 , 0 ); lcd.print ("e" ); delay (50 ); lcd.setCursor (10 , 0 ); lcd.print ("a" ); delay (50 ); lcd.setCursor (11 , 0 ); lcd.print ("t" ); delay (50 ); lcd.setCursor (12 , 0 ); lcd.print ("h" ); delay (50 ); lcd.setCursor (13 , 0 ); lcd.print ("e" ); delay (50 ); lcd.setCursor (14 , 0 ); lcd.print ("r" ); delay (50 ); lcd.setCursor (4 , 1 ); lcd.print ("S" ); delay (50 ); lcd.setCursor (5 , 1 ); lcd.print ("t" ); delay (50 ); lcd.setCursor (6 , 1 ); lcd.print ("a" ); delay (50 ); lcd.setCursor (7 , 1 ); lcd.print ("t" ); delay (50 ); lcd.setCursor (8 , 1 ); lcd.print ("i" ); delay (50 ); lcd.setCursor (9 , 1 ); lcd.print ("o" ); delay (50 ); lcd.setCursor (10 , 1 ); lcd.print ("n" ); delay (50 ); if (irrecv.decode(&results)) //if the ir receiver module receiver data { if (results.value == 0xFF6897 ) //if "0" is pushed print TIME { lcd.clear (); //clear the LCD print_time(); lcd.clear (); //clear the LCD } if (results.value == 0xFF30CF ) //if "1" is pushed print TEMPERATURE and HUMIDITY { lcd.clear (); //clear the LCD //READ DATA of the DHT // DISPLAY DATA lcd.setCursor (0 , 0 ); lcd.print ("Tem:" ); lmVal = analogRead (lmPin);//read the value of A1 lcd.print (tem);//print tem lcd. lcd.print ("C " ); // Serial.println(" C"); lcd.setCursor (0 , 1 ); lcd.print ("Hum:" ); //Serial.print("Hum:"); lcd. lcd.print (" % " ); //Serial.println(" %"); delay (10000 ); //wait for 3000 ms lcd.clear (); //clear the LCD irrecv.resume(); // Receive the next value } if (results.value == 0xFF18E7 ) //if "2" is pushed print the DARKNESS { lcd.clear (); //clear the LCD lcd.setCursor (4 , 0 ); lcd.print ("Darkness:" ); luce = pluce = lcd.setCursor (6 , 1 ); lcd. lcd. delay (10000 ); //delay 10000 ms lcd.clear (); //clear the LCD delay (200 ); //wait for a while irrecv.resume(); // Receive the next value } if (results.value == 0xFF7A85 ) //if "3" is pushed print the SNOW or WATER LEVEL { lcd.clear (); //clear the LCD lcd.setCursor (0 , 0 ); lcd. lcd.setCursor (6 , 1 ); mmwaterValue = lcd. delay (10000 ); //delay 10000ms lcd.clear (); //clear the LCD delay (200 ); irrecv.resume(); // Receive the next value } if (results.value == 0xFF9867 ) //if "PRESENTATION" is pushed print TIME, TEM and HUM, DARKNESS and S or W LEVEL one time { lcd.clear (); //clear the LCD print_time(); lcd.clear (); //clear the LCD delay (200 ); //wait for a while //READ DATA of the DHT int chk = DHT.read11(DHT11_PIN); // DISPLAY DATA lcd.setCursor (0 , 0 ); lcd.print ("Tem:" ); lmVal = analogRead (lmPin);//read the value of A0 tem = (lmVal * 0.0048828125 * 100 );//5/1024=0.0048828125;1000/10=100 lcd.print (tem);//print tem lcd.print (char (223 ));//print the unit" ? " lcd.print ("C " ); // Serial.println(" C"); lcd.setCursor (0 , 1 ); lcd.print ("Hum:" ); //Serial.print("Hum:"); lcd.print (DHT.humidity, 1 ); //print the humidity on lcd //Serial.print(DHT.humidity,1); lcd.print (" % " ); //Serial.println(" %"); delay (4000 ); //wait for 3000 ms lcd.clear (); //clear the LCD delay (200 ); //wait for a while lcd.setCursor (4 , 0 ); //place the cursor on 4 column, 1 row lcd.print ("Darkness:" ); luce = analogRead (sensorPin); //read the ldr pluce = map (luce, 0 , 1023 , 0 , 100 ); //the value of the sensor is converted into values from 0 to 100 lcd.setCursor (6 , 1 ); //place the cursor on the middle of the LCD lcd.print (pluce); //print the percentual lcd.print ("%" ); //print the symbol delay (4000 ); //delay 10000 ms lcd.clear (); //clear the LCD delay (200 ); //wait for a while lcd.setCursor (0 , 0 ); //place the cursor on 0 column, 1 row lcd.print ("Fluid level(mm):" ); //print "Fluid level(mm):" int waterValue = analogRead (waterSensor); // get water sensor value lcd.setCursor (6 , 1 ); //place cursor at 6 column,2 row mmwaterValue = map (waterValue, 0 , 1023 , 0 , 40 ); lcd.print (mmwaterValue); //value displayed on lcd delay (4000 ); //delay 10000ms lcd.clear (); //clear the LCD delay (200 ); irrecv.resume(); // Receive the next value } } }

Проект очень прост для повторения, думаем, сборка не должна вызвать сложностей.

Не пропустите обновления! Подписывайтесь на нашу группу