Виды датчиков
Для измерения параметров среды часто применяют три вида сенсоров:
- DHT11;
- DHT22;
- SHT1x.
Плюс первого — дешевизна, скорость работы и стабильность сигнала. Из минусов отметим сравнительно слабую программную реализацию библиотеки, высокую погрешность выполняемых измерений и не всегда подходящий диапазон рабочих температур. DHT22 выгодно отличается благодаря:
- малым погрешностям;
- высокой дальности сигнала;
- поддержке дробных значений.
Как и первый сенсор, DHT22 не работает без подгруженной библиотеки. Кроме того, для профессиональных задач его чувствительность и скорость реакции может стать недостаточной.
Датчики линейки SHT1x быстро срабатывают, имеют весьма низкую погрешность, экономичны и умеют «засыпать» при долгой неактивности. Из недостатков выделим:
- два цифровых интерфейса;
- невозможность работы без подключения программной библиотеки и диапазон от 0 до 50 градусов — как в других образцах. Его хватает не всегда.
По стоимости все три варианта примерно одинаковы. Для «домашних» установок чаще берут DHT11-22 за их сравнительную простоту в эксплуатации и настройке.
Радиодатчики
Там, где не дотянуться 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
Достаточно просто, не правда ли?
Скетч
Прошейте контроллер скетчем через Arduino IDE.
- weather-station-display.ino
-
// библиотека для работы I²C #include <Wire.h> // библиотека для работы с метеосенсором #include <TroykaMeteoSensor.h> // Подключаем библиотеку для работы с дисплеем #include <QuadDisplay2.h> // создаём объект для работы с метеосенсором TroykaMeteoSensor meteoSensor; // создаём объект класса QuadDisplay и передаём номер пина CS QuadDisplay qd(10); // создаем объект класса long для хранения счетчиков unsigned long respite_Time = ; unsigned long respite_Meteo = ; // создаем объект для регулировки времени показа значений на экране int slowdown_qd = 1000; void setup() { // инициализация дисплея qd.begin(); // инициализируем метеосенсор meteoSensor.begin(); } void loop() { // запускаем бесконечный счетчик. Его содержимое будет обрабатываться каждые 1000 миллисекунд if (millis() - respite_Time > slowdown_qd) { // запускаем функции вывода температуры и влажности по очереди if (millis() - respite_Meteo < 2 * slowdown_qd) { showTemperatureC(); } else if (millis() - respite_Meteo < 3 * slowdown_qd ) { showHumidity(); } // гасим экран и обнуляем цикл else if (millis() - respite_Meteo < 4 * slowdown_qd ) { qd.displayDigits(QD_NONE, QD_NONE, QD_NONE, QD_NONE); respite_Meteo = millis(); } respite_Time = millis(); } } // функция работы датчика температуры void showTemperatureC() { // считываем данные с датчика int stateSensor = meteoSensor.read(); // проверяем состояние данных switch (stateSensor) { // выводим показания температуры на дисплей case SHT_OK qd.displayTemperatureC(meteoSensor.getTemperatureC()); break; // выводим сообщение "Errd", если ошибка данных или сенсор не подключён case SHT_ERROR_DATA qd.displayDigits(QD_E, QD_r, QD_r, QD_d); // выводим сообщение "ErrC", если ошибка контрольной суммы case SHT_ERROR_CHECKSUM qd.displayDigits(QD_E, QD_r, QD_r, QD_C); break; } } // функция работы датчика влажности void showHumidity() { // считываем данные с датчика int stateSensor = meteoSensor.read(); // проверяем состояние данных switch (stateSensor) { // выводим показания влажности на дисплей case SHT_OK qd.displayHumidity(meteoSensor.getHumidity()); break; // выводим сообщение "Errd", если ошибка данных или сенсор не подключён case SHT_ERROR_DATA qd.displayDigits(QD_E, QD_r, QD_r, QD_d); // выводим сообщение "ErrC", если ошибка контрольной суммы case SHT_ERROR_CHECKSUM qd.displayDigits(QD_E, QD_r, QD_r, QD_C); break; } }
Часто задаваемые вопросы
Как установить библиотеку
У вас предыдущая версия модуля. Она снята с производства пару лет назад. С этим скетчем, библиотекой и схемой сборки модуль работать не будет.
Общий принцип работы
Измеряющая данные окружающей среды метеостанция на Ардуино состоит из нескольких основных компонентов:
- собственно плата управления Arduino (например, Uno). На нее поступает информация со внешних датчиков, контроллер выполняет вычисления и выводит информацию на экран;
- электронный дисплей — служит для отображения поступивших с контроллера данных в понятной человекочитаемой форме;
- сенсор влажности температуры. В подобных схемах популярны датчики DHT11 и DHT22. Они регистрируют данные среды и отдают их контроллеру;
- макетная плата — основа для сборки всех компонентов. На ней фиксируются все элементы метеостанции, по ней же прокладываются электрические соединения;
- соединительные провода — с «оголенными» концами под пайку или оснащенные штекерами.
Кроме того, в плату понадобится залить соответствующее программное обеспечение — скетч. Его содержимое зависит от набора элементов и выполняемых задач, примеры скетчей мы также рассмотрим ниже.
Подключение SX1278 к Raspberry Pi
Для начала подключим к малинке радиомодуль.
Raspberry Pi |
SX1278 |
3.3V |
3.3V |
GROUND |
GROUND |
GPIO10 |
MOSI |
GPIO9 |
MISO |
GPIO11 |
SCK |
GPIO8 |
NSS/ENABLE |
GPIO4 |
DIO0 |
GPIO22 |
RST |
Соединяем пины Raspberry Pi и SX1278 как на картинке:
По поводу использования LoRa-модулей хочу обратить внимание на несколько моментов:
Перед подачей питания на модуль LoRa обязательно убедитесь, что к нему подключена антенна, иначе есть риск, что модуль сгорит!
На качество сигнала помимо антенны влияют правильные настройки, весьма важно, чтобы частоты приёмника и передатчика совпадали, а диапазон был свободен от шума (например игрушечных радиоуправляемых машинок)
Исходный код
Код автономной части
- meteo_sensor.ino
-
#include <Arduino.h> #include <SHT1x.h> #include <LowPower_Teensy3.h> #include <ampline.h> // Таймаут между посылками (не более 65535) #define TIMEOUT 60000 // Количество попыток отправки посылки #define ATTEMPTS 3 // Информационный пин передатчика #define RF_PIN 5 // Пины датчика температуры и влажности #define GND1_PIN 10 #define VCC1_PIN 11 #define GND2_PIN 7 #define VCC2_PIN 8 #define DATA_PIN 12 #define CLK_PIN 9 AmperkaLine rf(RF_PIN); SHT1x sht1x(CLK_PIN, DATA_PIN); void loop(void); // Функция усыпления платы. Каждые TIMEOUT секунд // будет вызываться функция loop_func. TEENSY3_LP LP = TEENSY3_LP(); sleep_block_t* LP_config; void sleep_mode(void) { LP_config = (sleep_block_t*)calloc(1,sizeof(sleep_block_t)); // Просыпаться будем по таймеру LP_config->modules = (LPTMR_WAKE); // Задаём таймаут для таймера LP_config->lptmr_timeout = TIMEOUT; // По истечении таймаута будет вызываться функция loop LP_config->callback = loop; LP.Hibernate(LP_config); } // Функция включения периферии void periferial_start(void) { // Включаем линию передачи данных pinMode(RF_PIN, OUTPUT); // Включаем питания и земли датчиков температуры и влажности pinMode(GND1_PIN, OUTPUT); pinMode(GND2_PIN, OUTPUT); pinMode(VCC1_PIN, OUTPUT); pinMode(VCC2_PIN, OUTPUT); digitalWrite(GND1_PIN, LOW); digitalWrite(GND2_PIN, LOW); digitalWrite(VCC1_PIN, HIGH); digitalWrite(VCC2_PIN, HIGH); // Включаем светодиод для индикации передачи pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, HIGH); // Выбираем в качестве опорного напряжения внутренний // источник (=1.2 В) analogReference(INTERNAL); } // Функция выключения периферии void periferial_stop(void) { // Выключаем линию передачи данных pinMode(RF_PIN, INPUT); // Выключаем датчик температуры и влажности pinMode(GND1_PIN, INPUT); pinMode(GND2_PIN, INPUT); pinMode(VCC1_PIN, INPUT); pinMode(VCC2_PIN, INPUT); pinMode(18, INPUT_PULLUP); pinMode(19, INPUT_PULLUP); // Выключаем светодиод digitalWrite(LED_BUILTIN, LOW); } void setup(void) { // Ничего не инициализируем, сразу засыпаем sleep_mode(); } // Эта функция выполняется раз в TIMEOUT секунд void loop(void) { unsigned long msg; byte temp, humidity, voltage; // Включаем периферию periferial_start(); // Подождём, пока включится датчик температуры и влажности delay(30); // Получаем входные данные с сенсоров temp = (byte)(sht1x.readTemperatureC() + 40.)*2; humidity = (byte)sht1x.readHumidity(); voltage = analogRead(A0)4; // Составляем из данных посылку msg = ; msg |= voltage; msg <<= 8; msg |= humidity; msg <<= 8; msg |= temp; // Отправляем несколько раз посылку for(int i = ; i < ATTEMPTS; i++) rf.send(msg); // Выключаем периферию periferial_stop(); // После выхода из функции плата снова уснёт }
Код платы, работающей в помещении
- receiver.ino
-
#include <Arduino.h> #include <SPI.h> #include <Ethernet.h> #include <ampline.h> byte mac = { 0x90, 0xA7, 0xDA, 0x0F, 0xBC, 0x75 }; char server = "narodmon.ru"; EthernetClient client; const int rfpin = 7; AmperkaLine rf(rfpin); void setup(void) { pinMode(rfpin, INPUT); pinMode(6, OUTPUT); Serial.begin(9600); Serial.println("Started."); } void loop(void) { static unsigned long pushtimeout = ; static float temp, humidity, voltage; unsigned long msg; int res; if((res = rf.receive(&msg)) == ) { temp = ((float)(msg&0xFF))2. - 40.; msg >>= 8; humidity = (float)(msg&0xFF); msg >>= 8; voltage = (float)(msg&0xFF) 256. * 1.2 * 10 * 1.1; digitalWrite(6, HIGH); Serial.print("Temp: "); Serial.print(temp); Serial.print(", humidity: "); Serial.print(humidity); Serial.print(", voltage: "); Serial.println(voltage); digitalWrite(6, LOW); } else Serial.println('E'); if(millis() - pushtimeout > 60000*5) { pushtimeout = millis(); Serial.println("Starting Ethernet..."); if (Ethernet.begin(mac) == ) { Serial.println("Failed to configure Ethernet using DHCP"); while(1) { } } delay(1000); Serial.println("connecting..."); if (client.connect(server, 8283)) { Serial.println("connected"); client.println("#90-A7-DA-0F-BC-75#Sensor#55.751775#37.616856#0.0"); client.print("#90A7DA0FBC7501#"); client.print(temp, DEC); client.println("#In"); client.print("#90A7DA0FBC7502#"); client.print(humidity, DEC); client.println("#Humidity"); client.print("#90A7DA0FBC7503#"); client.print(voltage, DEC); client.println("#Voltage"); client.println("##"); } else Serial.println("connection failed"); { unsigned long tm = millis(); while(millis() - tm < 5000) { if (client.available()) { char c = client.read(); Serial.print(c); } } } client.stop(); } }
Схема на датчике DHT11
Выбор этого средства измерения температуры/влажности обусловлен его популярностью, дешевизной и надежностью — такой набор характеристик делает датчик отличным вариантом для домашнего проекта. DHT11 состоит из:
- определяющего влажность резистора;
- измеряющего температуру термистора.
Информация с выходов датчика идет на контроллер, в нашем случае это Ардуино.
Сенсор имеет следующие характеристики:
- рабочее напряжение — 3–5 В;
- питание — от источника в 2.5 мА;
- диапазон измерения влажности окружающей среды — 20–80% с погрешностью в 5%;
- диапазон измеряемых температур — 0–50 °С с погрешностью в 2%;
- частота измерений — раз в секунду;
- габариты — 15 на 15.15 на 5.5 мм.
На корпусе имеются четыре выхода, благодаря чему можно подключать сенсор к различным измерительным приборам. В домашней схеме будут использоваться лишь три:
- DATA;
- VCC;
- GND.
В продаже встречаются и датчики DHT11 по отдельности, и в составе готового модуля. Рекомендуется найти последний вариант — он удобнее
В разных модулях внешний вид и конфигурация выходов могут различаться, но принцип везде одинаков, следует лишь обращать внимание на распиновку
Методика взаимодействия
Датчик транслирует цифровой сигнал с закодированными в нем значениями влажности и температуры. Оба параметра передаются одновременно.
Связь происходит по следующему принципу:
- микроконтроллер отправляет сенсору запрос проверки состояния;
- DHT11 меняет битовую кодировку и отдает на Arduino результат;
- если формат запроса-ответа согласован с обеих сторон, на управляющую плату поступает пятибайтовый отчет о влажности и температуре.
Состав отчета:
- первые два байта — уровень температуры;
- вторые два — влажность;
- пятый байт — нужная для предотвращения ошибки измерений и передачи контрольная сумма.
Программная часть
Чтобы собранная метеостанция на базе Ардуино заработала, понадобится подходящий скетч.
Скетч можно скачать здесь: https://cloud.mail.ru/public/JDX7/HJ94PKwoe
Принципиальная схема
Так будет выглядеть схема сборки станции:
После сборки, прошивки и запуска на экране станет отображаться влажность и температура. Дисплей покажет:
- тепловой индекс — HiX;
- температуру воздуха — Т (temperature, в градусах);
- влажность — H (Humidity, в процентах).
Используется I2C-дисплей 1602.
Недостатки
Приведенная конструкция имеет один минус — при взаимодействии с экраном цифры округляются до целых. Для домашних вычислений это некритично, но при необходимости получить более точные величины придется заменить датчик на более продвинутый DHT22. Его поддержка в скетче есть по умолчанию.
Теперь рассмотрим образец метеостанции под Ардуино на основе DHT22 и с дополнительной функцией — измерением давления.
Схема самодельной метеостанции
Схема очень проста и по сути состоит из 4 основных компонентов. Это МК, датчик атмосферного давления + температуры, датчик влажности и USB – UART преобразователь.
Сразу скажу, что все компоненты покупал на всем известном электронном аукционе, причём покупал сразу в виде готовых модулей. Поясню почему готовыми модулями, во первых – цена датчика (или микросхемы) отдельно и цена модуля ничем практически не отличается, во вторых – готовый модуль уже имеет всю необходимую обвязку, такую как подтягивающие резисторы, стабилизаторы и прочее, в третьих – это намного упрощает конструкцию, а соответственно и её реализацию. Теперь немного о каждом модуле по отдельности.
Создание базы данных
Начнем с самого начала, а именно с проектирования и создания базы данных.
Базы данных это свой мир и изучать его можно долго, поэтому бегло коснёмся только тех вещей, которые нам непосредственно необходимы.
Все SQL скрипты находятся в каталоге
С чего начинается проектирование БД? С логического и физического представления.
Логическое представление или схема базы данных:
- таблица с данными DHT датчика температуры и влажности
- таблица с данными BMP датчика давления и температуры
- указанные таблицы не имеют связей между собой, точнее связи не нужны.
Физическая схема опирается на конкретную СУБД и типы данных. Проще разбирать на конкретном примере. SQL скрипт раскрывает логическую и физическую схемы.
В каждой таблице должно быть поле типа
Имя поля может отличаться в разных БД, но смысл один — это уникальный идентификатор, ключ записи. На будущее, если вы видите базу данных в таблицах которой нет подобного счётчика, знайте, эту БД проектировал человек весьма далёкий от программирования, скорее всего гуманитарий.
Данные от однотипных датчиков храним в одной таблице, для датчиков другого типа создаём еще таблицу. Это чуть усложняет базу данных и PHP обвязку к ней, но это упрощает расширение или модификацию всей системы в дальнейшем.
В нашем проекте две таблицы. В таблице хранятся данные от датчика(ов) типа DHT (температура, влажность), в таблице хранятся данные от датчика(ов) типа BMP (температура, давление). Если вы в будущем захотите иметь, например, датчик газов или детектор движения, то создаёте дополнительные таблицы, не поленитесь. Если подключаете ещё один датчик типа DHT11 или DHT22, то создавать дополнительную таблицу не нужно, используете таблицу . Надеюсь принцип ясен: отдельная физическая сущность — отдельная таблица.
Если в таблице будут храниться данные от несколько однотипных датчиков, то как же их различить? Для этого в каждой таблице вводится поле
Фактически это который мы прописывали в файле для каждого экземпляра удаленного датчика-клиента и в для датчика, который подключен непосредственно к серверу — центральному блоку.
В промышленных системах должна быть ещё одна таблица — соответствия и его словесного, человекочитаемого описания. Например, датчик с = 2 это «Температура, влажность в квартире» и т.д. Но в нашем проекте не будем усложнять, просто помните, что :
- датчик с , он же , равным 11 — это есть домашний датчик на сервере — центральном блоке,
- датчик с , он же , равным 20 — это первый (в нашем проекте и единственный) заоконный датчик-клиент.
Далее. В таблицах хранятся следующие данные:
- ipRemote — IP адрес метеостанции (сервера) с которого пришли данные, полезно для отладки и мониторинга,
- dateCreate — дата время создания записи,
- millis — полезно для отладки, это время в миллисекундах с момента начала выполнения скетча на Arduino,
- temperature — температура,
- humidity — влажность,
- voltage — напряжение питания,
- pressure — давление,
- errors — количество ошибок (не используется). Задумывалось для хранения количества ошибок при передаче и т.п., чтобы можно было удаленно оценить состояние всей системы.
Как видим таблицы и очень похожи, отличие только в полях pressure и humidity, и возникает желание свалить всё в одну кучу (таблицу). Но делать так не велит первая нормальная форма, множество начинающих программистов пытались её обойти, но ни у одного не получилось, и мы не будем. Это как не замечать закон всемирного тяготения, до поры до времени вполне может получиться.
Таблица полезна при отладке — это журнал ошибок и прочих системных сообщений.
Создание БД и её пользователя с правами описано в
Это делается один раз, имя БД и имя пользователя можете придумать свои. И что точно необходимо сделать — это задать свой пароль.
Метеостанция на Ардуино с блютуз
Для этого проекта нам потребуется:
- плата Arduino Uno / Arduino Nano / Arduino Mega;
- Bluetooth модуль HC-05/HC-06;
- датчик LM35 или DHT11;
- смартфон с ОС Andrioid;
- макетная плата;
- провода «папа-папа», «папа-мама».
Схема блютуз метеостанции на Ардуино своими руками
В данном проекте мы представим два варианта скетча для метеостанции — с датчиком DHT11 и с датчиком температуры LM35. Приложение на смартфоне подходит к двум вариантам. После прошивки модуля, соберите домашнюю метеостанцию, как на схеме выше и загрузите скетч. Оба скетча с приложением для смартфона и всеми необходимыми библиотеками можно скачать одним архивом здесь.
Скетч для метеостанции на Ардуино с DHT11
#include <SoftwareSerial.h> // подключение библиотеки SoftwareSerial.h SoftwareSerial mySerial(2, 3); // указываем пины rx и tx соответственно #include "DHT.h" // подключаем библиотеку для датчика DHT dht(8, DHT11); // сообщаем на каком порту будет датчик String stringT = String("*"); String stringH = String("%"); void setup() { Serial.begin(9600); // запуск аппаратного последовательного порта mySerial.begin(9600); // запуск программного последовательного порта dht.begin(); // запуск датчика DHT11 } void loop() { float h = dht.readHumidity(); // считываем значение температуры float t = dht.readTemperature(); // считываем значение влажности Serial.println(t + stringT); // отправляем значение температуры на монитор Serial.println(h + stringH); // отправляем значение влажности на монитор Serial.println(""); mySerial.println(t + stringT); // отправляем значение температуры на телефон mySerial.println(h + stringH); // отправляем значение влажности на телефон delay(10000); // ставим задержку на 10 секунд }
Пояснения к коду:
- массивы и нужны в этом скетче, чтобы приложение на телефоне считывало данные с нужным символом в соответствующей строке;
- блютуз модуль HC-05/06 работает на частоте 9600 бит/сек — .
Приложение для метеостанция на смартфоне Андроид
После загрузки скетча, скачайте и установите на своем телефоне приложение dht11.apk — снимки экрана размещены на картинке выше. Выполните сопряжение смартфона и блютуз модуля, согласно этой статьи — Подключение блютуз модуля и запустите приложение. Далее вам необходимо подключиться к блютуз метеостанции, нажав на кнопку «Подключиться» и дождаться обновления данных с датчика DHT11.
Сборка метеостанции с дисплеем 1602 и DHT11
Для этого проекта нам потребуется:
- плата Arduino UNO (NANO);
- жидкокристаллический дисплей 1602 с I2C;
- цифровой датчик DHT11 или DHT22;
- провода «папа-мама», «папа-папа»;
- макетная плата (при необходимости).
К Arduino Nano и Uno все датчики и дисплей подключаются по одной схеме — распиновка и подключение уже рассматривались на нашем сайте, поэтому не будем подробно останавливаться на этом моменте. Если у вас есть вопросы, то посмотрите следующие записи: Подключение DHT11 к Ардуино и Подключение LCD 1602 к Ардуино. Соберите метеостанцию на Ардуино с дисплеем 1602 и dht11, как на схеме ниже.
HTTP GET и JSON
Вопрос, который нужно решить в первую очередь — это каким образом будет происходить передача данных от веб-сервера к Андроид-приложению.
Придумывать тут ничего не нужно, всё уже придумано за нас — это HTTP GET и JSON.
В нашем случае простой GET запрос к веб-серверу можно составить и отладить вручную, пока Андроид приложение ещё не готово.
В Java и в Android есть готовые библиотеки для обработки данных в формате JSON. JSON текстовый формат, читается человеком, что полезно для отладки.
Для того, чтобы сформировать текущие данные от датчиков метеостанции создадим на веб-сервере новый PHP скрипт last-data-to-json.php.
Вызов скрипта :
где , как мы помним, это секретный ключ доступа к БД.
Пример ответа в формате JSON :
Необходимо напомнить, что у нас 3 датчика. Их ID и тип (DHT или BMP) жёстко закодированы по всему коду метеостанции. Такой способ хардкордного кодирования идеологически неверен, но для наколенного прототипа (где необходимо быстрое и простое решение) это разумный компромисс.
Скрипт берет из БД самые последние данные от этих разнотипных датчиков и упаковывает в формат JSON. Выборка данных из БД «с конца» просходит таким способом :
Код:
Копируем этот код и вставляем в IDE
#include <LCD_1602_RUS.h> // подключаем библиотеку для датчика
LCD_1602_RUS lcd(0x27, 20, 4); // определяем адрес дисплея и его размер
#include <DHT.h> // подключаем библиотеку для датчика
DHT dht(2, DHT11); // сообщаем на каком порту будет датчик
void setup()
{
lcd.init(); // Инициализация дисплея
lcd.backlight(); // Подключение подсветки
lcd.clear(); // Чистим дисплей
dht.begin(); // запускаем датчик DHT11
}
void loop()
{
float h = dht.readHumidity(); // считываем температуру (t)
float t = dht.readTemperature(); // и влажность (h)
lcd.setCursor(0, 0); // Устанавливаем курср на нулевую символ и нулевой строки
lcd.print(«Влажн. :»); // выводим надпись «Влажн.:»
lcd.print(h,1); // выводим значение влажности с одним символом после запятой
lcd.print(» %»); // выволим знак процента
lcd.setCursor(0, 1); // Устанавливаем курср на нулевой символ первой строки
lcd.print(«Темпер.:»); // выводим надпись «Темпер.:»
lcd.print(t,1); // выводим значение влажности с одним символом после запятой
lcd.print(«\337C»); // выволим знак градуса (337 символ в талице) и «С»
delay(2000); // ждём 2000 микросикенд (2 секунды)
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
#include <LCD_1602_RUS.h> // подключаем библиотеку для датчика LCD_1602_RUS lcd(0x27,20,4);// определяем адрес дисплея и его размер #include <DHT.h> // подключаем библиотеку для датчика DHT dht(2,DHT11);// сообщаем на каком порту будет датчик voidsetup() { lcd.init();// Инициализация дисплея lcd.backlight();// Подключение подсветки lcd.clear();// Чистим дисплей dht.begin();// запускаем датчик DHT11 } voidloop() { floath=dht.readHumidity();// считываем температуру (t) floatt=dht.readTemperature();// и влажность (h) lcd.setCursor(,);// Устанавливаем курср на нулевую символ и нулевой строки lcd.print(«Влажн. :»);// выводим надпись «Влажн.:» lcd.print(h,1);// выводим значение влажности с одним символом после запятой lcd.print(» %»);// выволим знак процента lcd.setCursor(,1);// Устанавливаем курср на нулевой символ первой строки lcd.print(«Темпер.:»);// выводим надпись «Темпер.:» lcd.print(t,1);// выводим значение влажности с одним символом после запятой lcd.print(«\337C»);// выволим знак градуса (337 символ в талице) и «С» delay(2000);// ждём 2000 микросикенд (2 секунды) } |
Копируем его в поле для кода IDE:
и жмём загрузить:
Кнопка «загрузить»
Загрузка завершена
Ждём несколько секунд и наша метеостанция работает:
Метеостанция работает
Создание базы данных
Начнем с самого начала, а именно с проектирования и создания базы данных.
Базы данных это свой мир и изучать его можно долго, поэтому бегло коснёмся только тех вещей, которые нам непосредственно необходимы.
Все SQL скрипты находятся в каталоге
С чего начинается проектирование БД? С логического и физического представления.
Логическое представление или схема базы данных:
- таблица с данными DHT датчика температуры и влажности
- таблица с данными BMP датчика давления и температуры
- указанные таблицы не имеют связей между собой, точнее связи не нужны.
Физическая схема опирается на конкретную СУБД и типы данных. Проще разбирать на конкретном примере. SQL скрипт раскрывает логическую и физическую схемы.
В каждой таблице должно быть поле типа
Имя поля может отличаться в разных БД, но смысл один — это уникальный идентификатор, ключ записи. На будущее, если вы видите базу данных в таблицах которой нет подобного счётчика, знайте, эту БД проектировал человек весьма далёкий от программирования, скорее всего гуманитарий.
Данные от однотипных датчиков храним в одной таблице, для датчиков другого типа создаём еще таблицу. Это чуть усложняет базу данных и PHP обвязку к ней, но это упрощает расширение или модификацию всей системы в дальнейшем.
В нашем проекте две таблицы. В таблице хранятся данные от датчика(ов) типа DHT (температура, влажность), в таблице хранятся данные от датчика(ов) типа BMP (температура, давление). Если вы в будущем захотите иметь, например, датчик газов или детектор движения, то создаёте дополнительные таблицы, не поленитесь. Если подключаете ещё один датчик типа DHT11 или DHT22, то создавать дополнительную таблицу не нужно, используете таблицу . Надеюсь принцип ясен: отдельная физическая сущность — отдельная таблица.
Если в таблице будут храниться данные от несколько однотипных датчиков, то как же их различить? Для этого в каждой таблице вводится поле
Фактически это который мы прописывали в файле для каждого экземпляра удаленного датчика-клиента и в для датчика, который подключен непосредственно к серверу — центральному блоку.
В промышленных системах должна быть ещё одна таблица — соответствия и его словесного, человекочитаемого описания. Например, датчик с = 2 это «Температура, влажность в квартире» и т.д. Но в нашем проекте не будем усложнять, просто помните, что :
- датчик с , он же , равным 11 — это есть домашний датчик на сервере — центральном блоке,
- датчик с , он же , равным 20 — это первый (в нашем проекте и единственный) заоконный датчик-клиент.
Далее. В таблицах хранятся следующие данные:
- ipRemote — IP адрес метеостанции (сервера) с которого пришли данные, полезно для отладки и мониторинга,
- dateCreate — дата время создания записи,
- millis — полезно для отладки, это время в миллисекундах с момента начала выполнения скетча на Arduino,
- temperature — температура,
- humidity — влажность,
- voltage — напряжение питания,
- pressure — давление,
- errors — количество ошибок (не используется). Задумывалось для хранения количества ошибок при передаче и т.п., чтобы можно было удаленно оценить состояние всей системы.
Как видим таблицы и очень похожи, отличие только в полях pressure и humidity, и возникает желание свалить всё в одну кучу (таблицу). Но делать так не велит первая нормальная форма, множество начинающих программистов пытались её обойти, но ни у одного не получилось, и мы не будем. Это как не замечать закон всемирного тяготения, до поры до времени вполне может получиться.
Таблица полезна при отладке — это журнал ошибок и прочих системных сообщений.
Создание БД и её пользователя с правами описано в
Это делается один раз, имя БД и имя пользователя можете придумать свои. И что точно необходимо сделать — это задать свой пароль.
Домашняя метеостанция на Ардуино своими руками
Мы рассматривали подключение Ethernet HR911105A к Arduino и возможность включения светодиодов дистанционно. Сегодня мы воспользуемся данной сборкой, добавив к схеме цифровой датчик температуры и влажности DTH11 с трех пиновым разъемом стандарта 2.54 мм. Для проекта нам понадобится плата Arduino, датчик DTH11, Ethernet порт HR911105A 15/10 (12 разъемов), макетная плата и роутер.
Следуйте инструкции и вы сможете сделать свою «Домашнюю метеостанцию на Arduino UNO», получая данные о температуре и влажности на компьютере или смартфоне по локальной сети. Вы можете дописать скетч, чтобы при достижении определенной температуры включались светодиоды. Также вас может заинтересовать проект метеостанции на Arduino с Android смартфоном и блютуз модулем.
Скетч
- 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, чтобы построить графики }
Характеристики и подключение датчиков DHT11 и DHT22
Датчик состоит из двух частей – емкостного датчика температуры и гигрометра. Первый используется для измерения температуры, второй – для влажности воздуха. Находящийся внутри чип может выполнять аналого-цифровые преобразования и выдавать цифровой сигнал, который считывается посредством микроконтроллера.
В большинстве случаев DHT11 или DHT22 доступен в двух вариантах: как отдельный датчик в виде пластикового корпуса с металлическими контактами или как готовый модуль с датчиком и припаянными элементами обвязки. Второй вариант гораздо проще использовать в реальных проектах и крайне рекомендуется для начинающих.
Датчик DHT11
- Потребляемый ток – 2,5 мА (максимальное значение при преобразовании данных);
- Измеряет влажность в диапазоне от 20% до 80%. Погрешность может составлять до 5%;
- Применяется при измерении температуры в интервале от 0 до 50 градусов (точность – 2%)
- Габаритные размеры: 15,5 мм длина; 12 мм широта; 5,5 мм высота;
- Питание – от 3 до 5 Вольт;
- Одно измерение в единицу времени (секунду). То есть, частота составляет 1 Гц;
- 4 коннектора. Между соседними расстояние в 0,1 ”.
Датчик DHT22
- Питание – от 3 до 5 Вольт;
- Максимальный ток при преобразовании – 2,5 мА;
- Способен измерять влажность в интервале от 0% до 100%. Точность измерений колеблется от 2% до 5%;
- Минимальная измеряемая температура – минус 40, максимальная – 125 градусов по Цельсию (точность измерений – 0,5);
- Устройство способно совершать одно измерение за 2 секунд. Частота – до 0,5 ГЦ;
- Габаритные размеры: 15,1 мм длина; 25 мм широта; 5,5 мм высота;
- Присутствует 4 коннектора. Расстояние между соседними – 0,1 ‘;
Очевидно, что при использовании в ардуино датчика температуры и влажности DHT11 устройство выдаст менее точные значения, чем DHT22. У аналога больший диапазон измеряемых значений, но и цена соответствующая. Датчик температуры и влажности DHT22, как и его аналог, имеет один цифровой выход, соответственно снимать показания можно не чаще, чем один раз в 1-2 секунды.