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 мин, ибо чаще незачем
а я, если температура не изменилась, а я мерию в целых, поэтому система достаточно инерционная, данные тупо отбрасываю. Если ничего не изменилось, то и решение принимать незачем.