Ayuda, 2 Sensores + ESP8266 + SQL

Proyectos hechos por una persona o muy pequeño grupo a modo personal, no proyectos industriales.
mecavito
Mensajes: 18
Registrado: 23 Dic 2019, 15:10
Agradecido: 1 vez
Agradecimiento recibido: 4 veces

Ayuda, 2 Sensores + ESP8266 + SQL

Mensaje sin leer por mecavito »

Buen día

He estado haciendo un proyecto para poder ver desde una página web las temperaturas de dos sensores desde cualquier parte, se muy poco sobre programación y comprenderán mi titánica idea de modificar cualquier código...

El sistema se compone de:
1 módulo ESP8266
2 Sensores DS18B20
1 Elevador de potencia (ya que si conectas más de 1 sensor directamente desde la salida ESP, surgen mediciones erradas)

Los problemas encontrados durante el desarrollo han sido varios (debido a mi desconocimiento), el más relevantes son:
Cuando usé el primer sketch funcional, si la red WIFi se reiniciaba o simplemente se cambiaba la IP dinámica, no ingresaba más info a la base de datos

Solución temporal: este lo solucioné con el siguiente código, que es el que llevo por el momento.

Código: Seleccionar todo

#include <TimeLib.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <WiFiClient.h>

#include <MySQL_Connection.h>
#include <MySQL_Cursor.h>

#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 2// DS18B20 Data Pin
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

// MySQL
IPAddress server_addr(xxx,xxx,xx,xx);   // MySQL SERVER
char user[] = "USERNAME"; // MySQL USERNAME
char password[] = "Passw"; // MySQL PASSWORD
char INSERT_DATA[] = "INSERT INTO database.tabla (valor1, valor2, tiempo) VALUES (%s, %s, NOW() + INTERVAL 1 HOUR)";
char query[128];
char temperatura1[10];
char temperatura2[10];

// WiFi
char ssid[] = "Nombre de red WIFI"; // SSID NAME
char pass[] = "Clave de red WIFI"; // SSID PASSWORD

WiFiClient client;
MySQL_Connection conn((Client *)&client);

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, pass);
  sensors.begin();
}

void saveTempData() {
            // wi fi
            WiFi.begin(ssid, pass);
            sensors.begin();
          
            while ( WiFi.status() != WL_CONNECTED ) {
              delay ( 500 );
              Serial.print ( "." );
            }
            Serial.println ( "" );
            Serial.print ( "Connected to " );
            Serial.println ( ssid );
            Serial.print ( "IP address: " );
            Serial.println ( WiFi.localIP() );
            Serial.println("DB - Connecting...");
            while (conn.connect(server_addr, 3306, user, password) != true) {
              delay(500);
              Serial.print ( "." );
            }
            // Sensores 
            sensors.requestTemperatures();
            MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);
            Serial.print("Temp 1: ");
            Serial.println(sensors.getTempCByIndex(0));
            Serial.print("Temp 2: ");
            Serial.println(sensors.getTempCByIndex(1));
            Serial.print("Query: ");
            dtostrf(sensors.getTempCByIndex(0), 2, 2, temperatura1);
            dtostrf(sensors.getTempCByIndex(1), 2, 2, temperatura2);
            sprintf(query, INSERT_DATA, temperatura1, temperatura2);
            cur_mem->execute(query);
            Serial.println(query);
            delete cur_mem;
            Serial.println("Data stored!");
            delay(3000);
 }

void loop() {
  saveTempData();
}
El problema con este código es que después de un número aleatorio de veces (siempre superior a 200), deja de ingresar info a la base de datos y las últimas líneas siempre son:
Connected
IP address: XXX.XXX.X.X
DB - Connecting...
Connected to server version 5.6.41-84.1
Temp 1: 19.81
Temp 2: 19.75
Query: INSERT INTO basededatos.tabla (valor1, valor2, tiempo) VALUES (19.81, 19.75, NOW() + INTERVAL 1 HOUR)
Data stored!

Connected
IP address: XXX.XXX.X.X
DB - Connecting...
Connected to server version 5.6.41-84.1
Temp 1: 19.81
Temp 2: 19.75
Query:
Investigué y parece que debo usar alguna de las dos opciones que siguen:
1. Usar Mode Sleep Mode, o Light Sleep Mode (sin embargo para ciclos cortos de recolección de info no lo veo viable)
2. Resetear con ESP.reset(); para que por ejemplo reinicie cada 4 horas o algo así

Mi problema es que no sé como usar este código, como dije mi conocimiento es mínimo

Por último, favor recomendarme un curso arduino on line, me cansé de hacer Frankenstein's (copiar y pegar partes de código para lograr que me funcionen mis proyectos) pero entendiendo muy poco la lógica de los mismos
Última edición por mecavito el 23 Dic 2019, 17:09, editado 1 vez en total.
Estos usuarios agradecieron al autor mecavito por el mensaje:
Naguissa
Valoración: 33%
Avatar de Usuario
Naguissa
Administrador del Sitio
Mensajes: 484
Registrado: 04 Jul 2016, 11:17
Agradecido: 102 veces
Agradecimiento recibido: 134 veces

Re: Ayuda, 2 Sensores + ESP8266 + SQL

Mensaje sin leer por Naguissa »

Hola y bienvenido,

Nunca he usado los cursores mySQL, pero viendo el código entiendo que falla a la hora de montar la query. Por los datos que das no debería, pues el insert ocupa 101 carácteres y el buffer es de 128, pero yo aumentaría el tamaño por si es eso:

char query[128];

a

char query[200];



¿Es ese todo el código? Porque veo que no hay ningún delay, con lo que debería estar contínuamente enviando datos... esto también podría causar algún problema con el servidor rechazando las conexiones.



Sobre tutoriales, la verdad es que yo aprendí C desde muy pequeño y nunca he seguido un tutorial, con lo que no puedo orientarte en ésto. Aunque por Youtube suele haber tutoriales muy bien hechos sobre cualquier cosa....


¡Saludos!
mecavito
Mensajes: 18
Registrado: 23 Dic 2019, 15:10
Agradecido: 1 vez
Agradecimiento recibido: 4 veces

Re: Ayuda, 2 Sensores + ESP8266 + SQL

Mensaje sin leer por mecavito »

Buenos días Naguissa, muchas gracias por responder

Ok, voy a probar con tu recomendación
Respondiendo a tu pregunta del código, si es todo el código, y donde debería colocarle el delay?

Por otro lado ví que usaste el código ESP.reset(); en un poryecto tuyo; para este programa como puedo usarlo digamos haciendo un reset cada 3 horas por ejemplo.

Gracias por todo su conocimiento me ha ayudado demasiado, ya que he visto muchos de sus proyectos
Estos usuarios agradecieron al autor mecavito por el mensaje:
Naguissa
Valoración: 33%
Avatar de Usuario
Naguissa
Administrador del Sitio
Mensajes: 484
Registrado: 04 Jul 2016, 11:17
Agradecido: 102 veces
Agradecimiento recibido: 134 veces

Re: Ayuda, 2 Sensores + ESP8266 + SQL

Mensaje sin leer por Naguissa »

mecavito escribió: 23 Dic 2019, 17:15 Buenos días Naguissa, muchas gracias por responder

Ok, voy a probar con tu recomendación
Respondiendo a tu pregunta del código, si es todo el código, y donde debería colocarle el delay?
Primero de todo, vamos a ver cómo funcionan los programas Arduino. Es muy sencillo, al arrancar el microcontrolador se ejecuta la función setup una vez y luego se ejecuta la función loop contínucamente, de manera que al finalizarla vuelve a ejecutarse.

En tu programa lo que pasa es que está contínuamente ejecutándola, y con ello llamando a saveTempData.

Para evitar ésto lo que puedes hacer es poner una llamada a la función delay. Has de pasarle los milisegundos que quieres que espere, por ejemplo delay(60000) para esperar un minuto.

mecavito escribió: 23 Dic 2019, 17:15 Por otro lado ví que usaste el código ESP.reset(); en un poryecto tuyo; para este programa como puedo usarlo digamos haciendo un reset cada 3 horas por ejemplo.

Gracias por todo su conocimiento me ha ayudado demasiado, ya que he visto muchos de sus proyectos
Para hacer ésto lo mejor es mirar cuanto tiempo lleva el microcontrolador ejecutándose desde que se inició, y si es mayor al deseado, resetear. Para ello puedes usar la función millis:

Código: Seleccionar todo

void loop() {
    saveTempData();
    if (millis() > 3600000 * 3) { // 3h
        ESP.reset();
    }
}
mecavito
Mensajes: 18
Registrado: 23 Dic 2019, 15:10
Agradecido: 1 vez
Agradecimiento recibido: 4 veces

Re: Ayuda, 2 Sensores + ESP8266 + SQL

Mensaje sin leer por mecavito »

Muchas gracias por responder tan rápido y eficiente.

Voy a probar todas tus recomendaciones y hago pruebas, ya mañana sabré como me fué y escribiré mis resultados.
Estos usuarios agradecieron al autor mecavito por el mensaje:
Naguissa
Valoración: 33%
mecavito
Mensajes: 18
Registrado: 23 Dic 2019, 15:10
Agradecido: 1 vez
Agradecimiento recibido: 4 veces

Re: Ayuda, 2 Sensores + ESP8266 + SQL

Mensaje sin leer por mecavito »

Hola, ya ejecuté varias veces el código y el mismo problema, se queda en
Connected
IP address: XXX.XXX.X.X
DB - Connecting...
Connected to server version 5.6.41-84.1
Temp 1: 19.81
Temp 2: 19.75
Query:
Incluso modifiqué el reset así

Código: Seleccionar todo

void loop() {
    if (millis() > 3600000 * 3) { // 3h
        ESP.reset();
    }
    saveTempData();
}
Para ver si mejoraba y se sigue quedando en el "Query:"

También tengo haciendo el loop cada 60 segundos aproximadamente y también se queda en Query:, incluso apenas un par de minutos de haber iniciado

Me estoy rompiendo la cabeza leyendo y buscando más opciones pero no las veo claramente :cry:
Avatar de Usuario
Naguissa
Administrador del Sitio
Mensajes: 484
Registrado: 04 Jul 2016, 11:17
Agradecido: 102 veces
Agradecimiento recibido: 134 veces

Re: Ayuda, 2 Sensores + ESP8266 + SQL

Mensaje sin leer por Naguissa »

Vale, ya he encontrado el problema. Está en estas líneas:

Código: Seleccionar todo

            dtostrf(sensors.getTempCByIndex(0), 2, 2, temperatura1);
            dtostrf(sensors.getTempCByIndex(1), 2, 2, temperatura2);

No conocía ese comando, así que he buscado info sobre él: dtostrf

En concreto, ésto:

Código: Seleccionar todo

char* dtostrf(float number, int tamanyo, int decimales, char* buffer);
/*                    |         |             |               \_ buffer donde almacenaremos la cadena
                      |         |             \_ Precisión (nº decimales)
                      |         \_Tamaño del número en carácteres
                      \_ Número a convertir
*/

Como has definido las temperaturas como 10 carácteres de longitud:

Código: Seleccionar todo

char temperatura1[10];
char temperatura2[10];
Usaría la misma longitud como parámetro de la función, quedando en:

Código: Seleccionar todo

            dtostrf(sensors.getTempCByIndex(0), 10, 2, temperatura1);
            dtostrf(sensors.getTempCByIndex(1), 10, 2, temperatura2);


Tal y como lo tienes definido no cabe en los buffers.
mecavito
Mensajes: 18
Registrado: 23 Dic 2019, 15:10
Agradecido: 1 vez
Agradecimiento recibido: 4 veces

Re: Ayuda, 2 Sensores + ESP8266 + SQL

Mensaje sin leer por mecavito »

Feliz Navidad....

Realicé todas las modificaciones recomendadas y otras adicionales, lamentablemente el programa llega al mismo punto de siempre.
Connected
IP address: XXX.XXX.X.X
DB - Connecting...
Connected to server version 5.6.41-84.1
Temp 1: 22.78
Temp 2: 21.83
Query:
Y deja de funcionar...

¿Será que debo pensar en un sketch diferente?
mecavito
Mensajes: 18
Registrado: 23 Dic 2019, 15:10
Agradecido: 1 vez
Agradecimiento recibido: 4 veces

Re: Ayuda, 2 Sensores + ESP8266 + SQL

Mensaje sin leer por mecavito »

He realizado otras pruebas adicionales, cambiando el punto WiFi a otro, hasta el momento he logrado casi 900 datos sin ningún problema, así que lo que debo hacer es colocar una instrucción que haga iniciar o reiniciar el proceso en caso que no inserte el query, con el fin de garantizar la inyección en la base de datos ya que es allí donde hay problema si la red falla; estoy pensando como escribir el código para hacerlo

Mucha lectura hoy 25 de diciembre.... ya dejó de ser un proyecto y se convirtió en un !reto¡ 8-)
Avatar de Usuario
Naguissa
Administrador del Sitio
Mensajes: 484
Registrado: 04 Jul 2016, 11:17
Agradecido: 102 veces
Agradecimiento recibido: 134 veces

Re: Ayuda, 2 Sensores + ESP8266 + SQL

Mensaje sin leer por Naguissa »

Añade, antes del Serial.println(query), un print de las variables:

Código: Seleccionar todo

Serial.println(temperatura1);
Serial.println(temperatura2);
Creo que esas variables pueden estar mal y por ello la query no puede 'montarse' correctamente....
  • Similar Topics
    Respuestas
    Vistas
    Último mensaje