2 Sensores + ESP8266 + SQL

Buenas noches

Mi problema: deja de enviar info a la base de datos AYUDA PORFA, he leído sobre función restart, pero no se como usarla en el código… Recomendaciones por favor, ya ando seco de ideas

Estoy haciendo un sistema IOT para dos sensores DS18B20, después de mucho probar logré construir mi propio frankestein (así llamo a mis códigos, sé poco de programación y lo que hago es buscar otros y adaptarlos a mi necesidad).

El ESP8266 con los dos sensores recogen la información, luego a través del WIFI la envían a una base de datos mysql, donde posteriormente la puedo visualizar en una página web.

Dejo este código que funciona actualmente, bueno, casi funciona

#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,xxx,xxx);   // MySQL SERVER
char user[] = "USER"; // 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[] = "Red wi fi"; // SSID NAME
char pass[] = "clave de red"; // 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 pograma después de forma aleatoria posterior a 300 datos, deja de funcionar

Bueno, yo no veo nada que esté especialmente mal.

Pero conectas la wifi cada 3 segundos antes de conectar con la base de datos.
Yo lo que haria sería:
Una función para conectar el wifi, que la llamas desde el setup:

void conectarWifi(){
  WiFi.begin(ssid, pass);
  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() );
  
}

void setup() {
  Serial.begin(115200);
  conectarWifi();

}

Y en la funcion saveTempData se llama a la funcion conectar, solo si no está conectado:

void saveTempData() {
            // wi fi
            if(WiFi.status() != WL_CONNECTED) conectarWifi();
            sensors.begin();
            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);
 }

Si el problema es que despues de 300 llamadas te has quedado sin memoria, por alguna causa, lo puedes depurar imprimiendo la memoria libre desde el loop:

void loop() {
  saveTempData();
  Serial.print(F("Memoria libre: "));
  Serial.print(ESP.getFreeHeap() / 1024);
  Serial.println("KB");
}

Si ves que el valor de la memoria baja en cada envio de datos es que algo no está bien en la liberación de la memoria dinamica, creo que relacionado con la llamada a la conexion de la wifi.
En el esp8266 la conexion con la wifi está basada en una tarea de rtos que tu no ves y puede que te esté dejando sin memoria de llamarla tantas veces, bueno esto es una conjetura pero creo que va por ahí el fallo…

Si quieres hacer un reset para volver a empezar, digamos a 200 envios, el loop sería algo así:

void loop() {
  for(int n=0;n<200;n++){
    saveTempData();
    }
  ESP.restart();
}

Pero yo intentaría averiguar la causa…

Saludos.

Muchas gracias por tus aportes, voy a probar inmediatamente tus propuestas y te cuento después como resultó

Buenas tardes, realicé los cambios sugeridos más un par de cosas menos relevantes y el resultado es que llegó a 10.874 datos insertados en la base de datos aproximadamente cada 8 segundos y se detuvo nuevamente al punto muerto, que es:

DB - Connecting...
Connected to server version 5.6.41-84.1
Query: INSERT INTO mibasededatos.temperaturas (valor1, valor2, tiempo) VALUES (19.56, 19.69, NOW() + INTERVAL 1 HOUR)
Datos Almacenados!
Memoria libre: 48KB
DB - Connecting...
Connected to server version 5.6.41-84.1
Query: INSERT INTO mibasededatos.temperaturas (valor1, valor2, tiempo) VALUES (19.56, 19.69, NOW() + INTERVAL 1 HOUR)
Datos Almacenados!
Memoria libre: 48KB
DB - Connecting...
Connected to server version 5.6.41-84.1
Query:

no estuvo mal, es la primera vez que llego a tantos datos insertados, sin embargo depende aún de un reseteo manual y ya había probado de algunas formas con el ESP.restart(); y aún con este comando el programa se detiene en el mismo punto

Les cuento que he visto no sé cuantos tutoriales de arduino y leído no sé cuanta información y hasta ya hago algunos cambios y entiendo mucho mejor (al menos este código), sin embargo he intentado de muchas maneras modificar esta parte del código pero no he logrado compilarlo, coloco el original primero.

void saveTempData() {
      Serial.println("DB - Connecting...");
      if (conn.connect(server_addr, 3306, user, password)) {
        delay(500);
        sensors.requestTemperatures();
        Serial.print("Query: ");
        dtostrf(sensors.getTempCByIndex(0), 4, 2, temperatura1);
        dtostrf(sensors.getTempCByIndex(1), 4, 2, temperatura2);
        sprintf(query, INSERT_DATA, temperatura1, temperatura2);
        MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);//nuevo sitio
        cur_mem->execute(query);
        Serial.println(query);
        delete cur_mem;
        conn.close();
        Serial.println("Datos Almacenados!");
        delay(3000);
        }
        else {
          Serial.println("No se conectó a DB");
          }
 }

La idea es colocar un if en esta parte

cur_mem->execute(query);

Pero lo he intentado de muchas formas y nada que compila, mi idea “en teoría” es colocar una condición que haga ejecutar el código query “if”, y si no funciona cierre y reinicie el proceso “else”…

Pro nada que doy con el chiste