dht22 отправлять данные в базу данных и показывать на веб-сервере
- Войдите на сайт для отправки комментариев
Пнд, 25/01/2021 - 13:08
Привет! У меня есть код, который отправляет данные dht22 в базу данных mysql в определенное время с помощью ds3231:
#include <SPI.h> #include <Ethernet.h> #include "DHT.h" #include <TimeLib.h> #include <TimeAlarms.h> #include <Wire.h> #include <DS1307RTC.h> #define DHTPIN 7 #define DHTTYPE DHT22 DHT dht(DHTPIN, DHTTYPE); byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //Newer Ethernet shields have a MAC address printed on a sticker on the shield IPAddress server(192, 168, 7, 1); //IPv4 address EthernetClient client; void setup() { Serial.begin(9600); // wait for Arduino Serial Monitor while (!Serial) ; // get and set the time from the RTC setSyncProvider(RTC.get); if (timeStatus() != timeSet) Serial.println("Unable to sync with the RTC"); else Serial.println("RTC has set the system time"); // to test your project, you can set the time manually //setTime(8,29,0,1,1,11); // set time to Saturday 8:29:00am Jan 1 2011 // create the alarms, to trigger functions at specific times Alarm.alarmRepeat(10, 25, 0, MorningAlarm); Alarm.alarmRepeat(10, 25, 30, EveningAlarm); Ethernet.begin(mac); dht.begin(); } void loop() { digitalClockDisplay(); // wait one second between each clock display in serial monitor Alarm.delay(1000); } void AlaramFunc() { int idSensor = 1; float hum = dht.readHumidity(); float temp = dht.readTemperature(); float fah = dht.readTemperature(true); float heat_index = dht.computeHeatIndex(fah, hum); float heat_indexC = dht.convertFtoC(heat_index); if (client.connect(server, 80)) { Serial.println("connected"); client.print("GET /data.php?"); client.print("temperature="); client.print(temp); client.print("&humidity="); client.print(hum); client.print("&heat_index="); client.print(heat_indexC); client.print("&idSensor="); client.print(idSensor); client.println(" HTTP/1.1"); client.println("Host: 192.168.7.1"); client.println("Connection: close"); client.println(); Serial.print("GET /data.php?"); Serial.print("temperature="); Serial.print(temp); Serial.print("&humidity="); Serial.print(hum); Serial.print("&heat_index="); Serial.print(heat_indexC); Serial.print("&idSensor="); Serial.print(idSensor); Serial.println(" HTTP/1.1"); client.stop(); //Closing the connection } else { //if you didn't get a connection to the server: Serial.println("connection failed"); } } void MorningAlarm() { AlaramFunc(); } void EveningAlarm() { AlaramFunc(); } void digitalClockDisplay() { // digital clock display of the time Serial.print(hour()); printDigits(minute()); printDigits(second()); Serial.println(); } void printDigits(int digits) { Serial.print(":"); if (digits < 10) Serial.print('0'); Serial.print(digits); }
Я пытаюсь объединить свой код с кодом из этого примера, чтобы также показывать текущую температуру и влажность. Но код не работает полностью. Он показывает данные на веб-сервере, но не может подключиться (connection failed на serial monitor) для отправки данных в БД. Что нужно исправить?
#include <SPI.h> #include <Ethernet.h> #include "DHT.h" #include <TimeLib.h> #include <TimeAlarms.h> #include <Wire.h> #include <DS1307RTC.h> #define DHTPIN 7 #define DHTTYPE DHT22 DHT dht(DHTPIN, DHTTYPE); byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //Newer Ethernet shields have a MAC address printed on a sticker on the shield IPAddress server(192, 168, 7, 1); //IPv4 address EthernetClient client; IPAddress ip(192, 168, 1, 99); EthernetServer server1(80); void setup() { Serial.begin(9600); // wait for Arduino Serial Monitor while (!Serial) ; // get and set the time from the RTC setSyncProvider(RTC.get); if (timeStatus() != timeSet) Serial.println("Unable to sync with the RTC"); else Serial.println("RTC has set the system time"); // to test your project, you can set the time manually //setTime(8,29,0,1,1,11); // set time to Saturday 8:29:00am Jan 1 2011 // create the alarms, to trigger functions at specific times Alarm.alarmRepeat(15, 27, 0, MorningAlarm); Alarm.alarmRepeat(15, 28, 0, EveningAlarm); Ethernet.begin(mac, ip); dht.begin(); server1.begin(); } void loop() { digitalClockDisplay(); // wait one second between each clock display in serial monitor Alarm.delay(1000); float h = dht.readHumidity( ); float t = dht.readTemperature( ); EthernetClient client = server1.available(); if (client) { boolean currentLineIsBlank = true; while (client.connected ( ) ) { if (client.available ( ) ) { char character = client.read ( ); Serial.write(character); if (character == '\n' && currentLineIsBlank) { client.println ("HTTP/1.1 200 OK"); client.println ("Content-Type: text/html"); client.println ("Connection: close"); client.println ("Refresh: 5"); client.println ( ); client.println ("<!DOCTYPE HTML>"); client.println ("<html>"); client.print ("<Title>Arduino Ethernet Webserver </Title>"); client.print ("<h1>Arduino Ethernet Shield Webserver </h1>"); client.print ("<h4>Temperature in C: "); client.print (t);client.print("C"); client.print ("</h4><h4>Humidity: "); client.print (h);client.print("%"); client.println ("<br />"); client.println ("</html>"); break; } if ( character == '\n') { currentLineIsBlank = true; } else if (character != '\r') { currentLineIsBlank = false; } } } delay(1); client.stop(); } } void AlaramFunc() { int idSensor = 1; float hum = dht.readHumidity(); float temp = dht.readTemperature(); float fah = dht.readTemperature(true); float heat_index = dht.computeHeatIndex(fah, hum); float heat_indexC = dht.convertFtoC(heat_index); if (client.connect(server, 80)) { Serial.println("connected"); client.print("GET /data.php?"); client.print("temperature="); client.print(temp); client.print("&humidity="); client.print(hum); client.print("&heat_index="); client.print(heat_indexC); client.print("&idSensor="); client.print(idSensor); client.println(" HTTP/1.1"); client.println("Host: 192.168.7.1"); client.println("Connection: close"); client.println(); Serial.print("GET /data.php?"); Serial.print("temperature="); Serial.print(temp); Serial.print("&humidity="); Serial.print(hum); Serial.print("&heat_index="); Serial.print(heat_indexC); Serial.print("&idSensor="); Serial.print(idSensor); Serial.println(" HTTP/1.1"); client.stop(); //Closing the connection } else { //if you didn't get a connection to the server: Serial.println("connection failed"); } } void MorningAlarm() { AlaramFunc(); } void EveningAlarm() { AlaramFunc(); } void digitalClockDisplay() { // digital clock display of the time Serial.print(hour()); printDigits(minute()); printDigits(second()); Serial.println(); } void printDigits(int digits) { Serial.print(":"); if (digits < 10) Serial.print('0'); Serial.print(digits); }
код не читал, но в целом к задаче вы подходите неверно. зачем дублировать и посылать данные ардуиной через сеть дважды - сначала на в БД, а потом на сервер. Общение с сетью для ардуины и так сложно...
Достаточно отсылать данные в Mysql, а веб-сервер пусть берет их из базы сам, без участия ардуины.
Не хотелось бы переполнять базу большим количеством записей. Сейчас как у меня в коде в день добавляются только два значения, а так надо будет например передавать данные датчика каждые несколько секунд.
Не хотелось бы переполнять базу большим количеством записей. Сейчас как у меня в коде в день добавляются только два значения, а так надо будет например передавать данные датчика каждые несколько секунд.
а нафига тогда вообще БД. если не для хранения записей?
Или вы хотите, чтобы сервер у вас в реальном времени подключался к ардуине и получал данные? - имхо, это неверный подход, быть HTTP-сервером ардуине еще труднее. чем просто слать по сети
Поверьте, куда приятнее и удобнее оперировать не "голыми" данными, а данными в СУБД.
Не хотелось бы переполнять базу большим количеством записей. Сейчас как у меня в коде в день добавляются только два значения, а так надо будет например передавать данные датчика каждые несколько секунд.
Зачем так часто передавать данные на web-сервер? Сохранили в промежуточной переменной прошлое измерение и смотрите - "а сейчас поменялось может что?" и если "ой, действительно поменялось" - шлете эти данные в БД. Если у Вас там не турбонагрев с турбоохлаждением, то данные в БД раз в несколько минут/десятков минут будут "падать", а то и часов (если температура стабильна). А вот вычитывать данные из СУБД web-сервером можно и каждую минуту, ничего страшного. :)
Метод "передача по изменению" имеет неприятный дефект - она не позволяет понять - работает ли устройство снятия параметров окружающей среды в текущий момент.
можно комбинировать. Передавать данные в базу каждые 5 минут (полчаса / 6 часов...) или чаще, если данные изменились более чем на градус...
другой вопрос, что с данными, неравномерно распределенными по времени - неудобно работать...
Это легко решается отправкой "раз в "определенный" интервал времени" данных что всё ОК (к примеру, раз в 15 минут/1 час или как Вам нужно), можно и отправлять в выше указанное время текущие параметры. Но лично я бы не стал так делать, проще слать отдельные данные в отдельную таблицу о состоянии устройства (или датчиков устройства). Как только в нужный интервал web-сервер не получил данные - АЛЯРМ! Что-то случилось.
другой вопрос, что с данными, неравномерно распределенными по времени - неудобно работать...
Это тоже. Если делать выборку в базе по диапазону времени, то концы графика могут оказаться неопределенными, если таймштампы значений метрики не находятся вблизи границ запрашиваемого периода.
Это легко решается отправкой "раз в "определенный" интервал времени" данных что всё ОК (к примеру, раз в 15 минут/1 час или как Вам нужно),
Лишняя метрика, больше затрат на сбор/администрирование. Продуктивней основную сразу собирать периодически.
Вы имеете ввиду слать, к примеру, каждые 5 минут данные вне зависимости от того изменились они или нет? Верно я понял?
Я к тому все выше писал, что как ТС писал "каждые несколько секунд" - это при каждом опросе датчика получается. Это очень часто и не нужно такого, если только действительно в турборежиме что-то греется/охлаждается. Но в таком случае нужно что-то более интерактивное, чем web-интерфейс.
1/5/10/N мин/сек - как того требует скорость реагирования на критические значения метрики.
Если у пользователя имеются экономические или технологические обоснования применять периодичность в "несколько секунд" - она и должна быть использована. Абстрактной "наилучшей" периодичности нет.
Это же не народный мониторинг, где надо слать не чаще раз в пять минут, для себя установил интервал минута, после полгода накопления почистил базу из-за ненужности данных, критерий - срок хранения, а MYSQL легко держит десятки миллионов записей
мой заоконный даччик шлет данные раз в минуту, а принимающая сторона уже решает, складывать их куданить или отбрасывать.
мой заоконный даччик шлет данные раз в минуту, а принимающая сторона уже решает, складывать их куданить или отбрасывать.
добавлю свои 5 коп - у меня датчик шлет данные каждую минуту, контроллер печки управляет по ним обогревом. А в БД данные сливаются раз 10 мин, ибо чаще незачем
а я, если температура не изменилась, а я мерию в целых, поэтому система достаточно инерционная, данные тупо отбрасываю. Если ничего не изменилось, то и решение принимать незачем.