You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have a code in an ESP32-C3 in ARDUINO-IDE where I read humidity in a plant and then I send it to google sheets so that I can store it and analyze it there. However, I have a problem. If the span of time between messages to google sheets is araound 1 miniute, then there is no problem, but if I put 10 minutes or bigger then it will stop sending data to google sheets.
I read that it could be because the token is not renovating correctly but I do not know how to solve it.
Also, the code uses almost all the memory of the esp32, i do not know if it is related. I does not explain why it works with 1 min, but not 10 or longer.
Thank you.
ERROR:
Append spreadsheet values...
WARN.mRunUntil: Terminating because the ssl engine closed.
ERROR.mConnectSSL: Failed to initlalize the SSL layer.
ERROR.mConnectSSL: Validation time is unknown.
unknown error
// ID del Proyecto de Google
#define PROJECT_ID "**"
// Correo electrónico del cliente de la Cuenta de Servicio
#define CLIENT_EMAIL "**"
// Clave privada de la Cuenta de Servicio
const char PRIVATE_KEY[] PROGMEM = "-----BEGIN PRIVATE KEY-----**\n-----END PRIVATE KEY-----\n";
// El ID de la hoja de cálculo donde se publicarán los datos
const char spreadsheetId[] = "**";
int valorHumedad, humedad;
int referencia = 65;
int Amplitud = 10;
int referencia_superior = referencia + Amplitud;
int referencia_inferior = referencia - Amplitud;
int motorEstado = 0; // Variable para almacenar el estado de la bomba de agua
unsigned long lastTime = 0;
const unsigned long interval = 1000; // 1 segundo
unsigned long lastUpdate = 0;
const unsigned long updateInterval = 1800000; // 30 minutos
// Servidor NTP para solicitar la hora
const char* ntpServer = "pool.ntp.org";
// Función que obtiene la hora actual
String getTime() {
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
return "Fallo al obtener la hora";
}
char timeStringBuff[50];
strftime(timeStringBuff, sizeof(timeStringBuff), "%Y-%m-%d %H:%M:%S", &timeinfo);
return String(timeStringBuff);
}
void handleRoot(AsyncWebServerRequest *request) {
String html = "";
html += "";
html += "<style>";
html += "body { font-family: Arial, sans-serif; text-align: center; margin: 0; padding: 20px; }";
html += "h1 { font-size: 28px; margin-bottom: 20px; }";
html += "p { font-size: 22px; margin-bottom: 20px; }";
html += "form { margin: 20px 0; }";
html += "input[type='submit'] { font-size: 22px; padding: 15px 30px; margin: 5px; }";
html += "</style>";
html += "";
html += "
Control ESP32
";
html += "
Referencia actual: " + String(referencia) + "
";
html += "";
html += "";
html += "";
html += "";
html += "";
html += "";
html += "";
html += "";
html += "";
request->send(200, "text/html", html);
}
void handleSetReferencia(AsyncWebServerRequest *request) {
String html = "";
html += "";
html += "<style>";
html += "body { font-family: Arial, sans-serif; text-align: center; margin: 0; padding: 20px; }";
html += "h1 { font-size: 28px; margin-bottom: 20px; }";
html += "a { font-size: 22px; text-decoration: none; color: #0000EE; }";
html += "</style>";
html += "";
if (request->hasParam("action", true)) {
String action = request->getParam("action", true)->value();
if (action == "increase") {
referencia += 10;
} else if (action == "decrease") {
referencia -= 10;
}
html += "
Referencia actualizada!
";
} else {
html += "
Error: ¡Acción no proporcionada!
";
}
html += "Volver";
html += "";
request->send(200, "text/html", html);
}
void enviarDatosGoogleSheets(int humedad, int motorEstado, int referencia_superior, int referencia_inferior, int referencia) {
FirebaseJson response;
Serial.println("\nAñadiendo valores a la hoja de cálculo...");
Serial.println("----------------------------");
FirebaseJson valueRange;
String currentTime = getTime();
valueRange.add("majorDimension", "COLUMNS");
valueRange.set("values/[0]/[0]", currentTime); // Enviar la fecha y hora combinadas
valueRange.set("values/[1]/[0]", humedad);
valueRange.set("values/[2]/[0]", motorEstado);
valueRange.set("values/[3]/[0]", referencia);
valueRange.set("values/[4]/[0]", referencia_inferior);
valueRange.set("values/[5]/[0]", referencia_superior);
// Añadir valores a la hoja de cálculo
bool success = GSheet.values.append(&response, spreadsheetId, "Hoja1!A1", &valueRange);
if (success) {
response.toString(Serial, true);
valueRange.clear();
} else {
Serial.println(GSheet.errorReason());
}
Serial.println();
Serial.println(ESP.getFreeHeap());
}
void reconnectWiFi() {
if (WiFi.status() != WL_CONNECTED) {
Serial.print("Reconectando a Wi-Fi");
WiFi.disconnect();
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(1000);
}
Serial.println();
Serial.print("Reconectado con IP: ");
Serial.println(WiFi.localIP());
Serial.println();
}
}
void reconnectGoogleSheet() {
if (!GSheet.ready()) {
Serial.println("Reconectando a Google Sheets...");
ESP.restart();
}
}
void tokenStatusCallback(TokenInfo info) {
if (info.status == token_status_error) {
Serial.printf("Información del token: tipo = %s, estado = %s\n", GSheet.getTokenType(info).c_str(), GSheet.getTokenStatus(info).c_str());
Serial.printf("Error del token: %s\n", GSheet.getTokenError(info).c_str());
} else {
Serial.printf("Información del token: tipo = %s, estado = %s\n", GSheet.getTokenType(info).c_str(), GSheet.getTokenStatus(info).c_str());
}
}
void setup() {
Serial.begin(9600);
pinMode(7, OUTPUT); // Configurar el pin de salida para el motor
// Para UTC+2 (horario de verano en España):
configTime(7200, 0, ntpServer);
GSheet.printf("Cliente ESP Google Sheet v%s\n\n", ESP_GOOGLE_SHEET_CLIENT_VERSION);
// Conectar a Wi-Fi
WiFi.setAutoReconnect(true);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Conectando a Wi-Fi");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(1000);
}
Serial.println();
Serial.print("Conectado con IP: "); Serial.println(WiFi.localIP());
Serial.println();
// Configurar el callback para la generación del token de acceso de Google API
GSheet.setTokenCallback(tokenStatusCallback);
// Configurar el tiempo de refresco del token de acceso antes de expirar
GSheet.setPrerefreshSeconds(10 * 60);
// Iniciar la generación del token de acceso para la autenticación de Google API
GSheet.begin(CLIENT_EMAIL, PROJECT_ID, PRIVATE_KEY);
// Iniciar el servidor web
server.on("/", HTTP_GET, handleRoot);
server.on("/setReferencia", HTTP_POST, handleSetReferencia);
server.begin();
}
void loop() {
int referencia_superior = referencia + Amplitud;
int referencia_inferior = referencia - Amplitud;
// Llamar a ready() repetidamente en el bucle para verificar la autenticación y el procesamiento
bool ready = GSheet.ready();
reconnectWiFi();
reconnectGoogleSheet();
valorHumedad = analogRead(4); // Leer el valor del sensor de humedad
humedad = map(valorHumedad, 0, 4095, 0, 100); // Mapear el valor del sensor a un porcentaje
// Control por histéresis
if (humedad < referencia_inferior) {
while (humedad < referencia_superior) {
// Enviar datos a Google Sheets
enviarDatosGoogleSheets(humedad, motorEstado, referencia_superior, referencia_inferior, referencia);
digitalWrite(7, HIGH); // Encender el pin de salida
motorEstado = 1; // Actualizar el estado del motor
realizarDelayConHandleClient(1); // Tiempo de muestreo 1 seg si el motor está en ON
valorHumedad = analogRead(4); // Lectura de la humedad
humedad = map(valorHumedad, 0, 4095, 0, 100);
// Para depuración: imprimir valores
Serial.println("Ajustando humedad");
Serial.print("Humedad: "); Serial.println(humedad);
Serial.println("Encendiendo bomba de agua: humedad baja");
}
digitalWrite(7, LOW); // Apagar el pin de salida
motorEstado = 0; // Actualizar el estado del motor
Serial.println("Apagando salida: humedad alcanzada");
// Enviar datos a Google Sheets
enviarDatosGoogleSheets(humedad, motorEstado, referencia_superior, referencia_inferior, referencia);
realizarDelayConHandleClient(60); // 1800 segundos (media hora) de delay comprobando el servidor
} else {
digitalWrite(7, LOW); // Apagar el pin de salida
motorEstado = 0; // Actualizar el estado del motor
Serial.println("Humedad correcta");
Serial.print("Valor humedad = "); Serial.println(humedad); // Imprimir valor de humedad en el monitor serie
// Enviar datos a Google Sheets
enviarDatosGoogleSheets(humedad, motorEstado, referencia_superior, referencia_inferior, referencia);
realizarDelayConHandleClient(60); // 1800 segundos (media hora) de delay comprobando el servidor
}
}
void realizarDelayConHandleClient(int segundos) {
int contador = 0;
while (contador < segundos * 10) { // Multiplicamos por 10 para tener iteraciones de 0.1 segundos
delay(100); // Reducimos el delay a 100 ms
contador++;
yield(); // Permitir que el sistema haga sus tareas de mantenimiento
}
}
The text was updated successfully, but these errors were encountered:
I have a code in an ESP32-C3 in ARDUINO-IDE where I read humidity in a plant and then I send it to google sheets so that I can store it and analyze it there. However, I have a problem. If the span of time between messages to google sheets is araound 1 miniute, then there is no problem, but if I put 10 minutes or bigger then it will stop sending data to google sheets.
I read that it could be because the token is not renovating correctly but I do not know how to solve it.
Also, the code uses almost all the memory of the esp32, i do not know if it is related. I does not explain why it works with 1 min, but not 10 or longer.
Thank you.
ERROR:
Append spreadsheet values...
CODE:
#include <Arduino.h>
#include "time.h"
#include <ESP_Google_Sheet_Client.h>
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <AsyncTCP.h>
#include <ArduinoJson.h>
AsyncWebServer server(80);
#define WIFI_SSID ""
#define WIFI_PASSWORD ""
// ID del Proyecto de Google
#define PROJECT_ID "**"
// Correo electrónico del cliente de la Cuenta de Servicio
#define CLIENT_EMAIL "**"
// Clave privada de la Cuenta de Servicio
const char PRIVATE_KEY[] PROGMEM = "-----BEGIN PRIVATE KEY-----**\n-----END PRIVATE KEY-----\n";
// El ID de la hoja de cálculo donde se publicarán los datos
const char spreadsheetId[] = "**";
int valorHumedad, humedad;
int referencia = 65;
int Amplitud = 10;
int referencia_superior = referencia + Amplitud;
int referencia_inferior = referencia - Amplitud;
int motorEstado = 0; // Variable para almacenar el estado de la bomba de agua
unsigned long lastTime = 0;
const unsigned long interval = 1000; // 1 segundo
unsigned long lastUpdate = 0;
const unsigned long updateInterval = 1800000; // 30 minutos
// Servidor NTP para solicitar la hora
const char* ntpServer = "pool.ntp.org";
// Función que obtiene la hora actual
String getTime() {
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
return "Fallo al obtener la hora";
}
char timeStringBuff[50];
strftime(timeStringBuff, sizeof(timeStringBuff), "%Y-%m-%d %H:%M:%S", &timeinfo);
return String(timeStringBuff);
}
void handleRoot(AsyncWebServerRequest *request) {
String html = "";
html += "";
html += "<style>";
html += "body { font-family: Arial, sans-serif; text-align: center; margin: 0; padding: 20px; }";
html += "h1 { font-size: 28px; margin-bottom: 20px; }";
html += "p { font-size: 22px; margin-bottom: 20px; }";
html += "form { margin: 20px 0; }";
html += "input[type='submit'] { font-size: 22px; padding: 15px 30px; margin: 5px; }";
html += "</style>";
html += "";
html += "
Control ESP32
";html += "
Referencia actual: " + String(referencia) + "
";html += "";
html += "";
html += "";
html += "";
html += "";
html += "";
html += "";
html += "";
html += "";
request->send(200, "text/html", html);
}
void handleSetReferencia(AsyncWebServerRequest *request) {
String html = "";
html += "";
html += "<style>";
html += "body { font-family: Arial, sans-serif; text-align: center; margin: 0; padding: 20px; }";
html += "h1 { font-size: 28px; margin-bottom: 20px; }";
html += "a { font-size: 22px; text-decoration: none; color: #0000EE; }";
html += "</style>";
html += "";
if (request->hasParam("action", true)) {
String action = request->getParam("action", true)->value();
if (action == "increase") {
referencia += 10;
} else if (action == "decrease") {
referencia -= 10;
}
html += "
Referencia actualizada!
";} else {
html += "
Error: ¡Acción no proporcionada!
";}
html += "Volver";
html += "";
request->send(200, "text/html", html);
}
void enviarDatosGoogleSheets(int humedad, int motorEstado, int referencia_superior, int referencia_inferior, int referencia) {
FirebaseJson response;
Serial.println("\nAñadiendo valores a la hoja de cálculo...");
Serial.println("----------------------------");
FirebaseJson valueRange;
String currentTime = getTime();
valueRange.add("majorDimension", "COLUMNS");
valueRange.set("values/[0]/[0]", currentTime); // Enviar la fecha y hora combinadas
valueRange.set("values/[1]/[0]", humedad);
valueRange.set("values/[2]/[0]", motorEstado);
valueRange.set("values/[3]/[0]", referencia);
valueRange.set("values/[4]/[0]", referencia_inferior);
valueRange.set("values/[5]/[0]", referencia_superior);
// Añadir valores a la hoja de cálculo
bool success = GSheet.values.append(&response, spreadsheetId, "Hoja1!A1", &valueRange);
if (success) {
response.toString(Serial, true);
valueRange.clear();
} else {
Serial.println(GSheet.errorReason());
}
Serial.println();
Serial.println(ESP.getFreeHeap());
}
void reconnectWiFi() {
if (WiFi.status() != WL_CONNECTED) {
Serial.print("Reconectando a Wi-Fi");
WiFi.disconnect();
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(1000);
}
Serial.println();
Serial.print("Reconectado con IP: ");
Serial.println(WiFi.localIP());
Serial.println();
}
}
void reconnectGoogleSheet() {
if (!GSheet.ready()) {
Serial.println("Reconectando a Google Sheets...");
ESP.restart();
}
}
void tokenStatusCallback(TokenInfo info) {
if (info.status == token_status_error) {
Serial.printf("Información del token: tipo = %s, estado = %s\n", GSheet.getTokenType(info).c_str(), GSheet.getTokenStatus(info).c_str());
Serial.printf("Error del token: %s\n", GSheet.getTokenError(info).c_str());
} else {
Serial.printf("Información del token: tipo = %s, estado = %s\n", GSheet.getTokenType(info).c_str(), GSheet.getTokenStatus(info).c_str());
}
}
void setup() {
Serial.begin(9600);
pinMode(7, OUTPUT); // Configurar el pin de salida para el motor
// Para UTC+2 (horario de verano en España):
configTime(7200, 0, ntpServer);
GSheet.printf("Cliente ESP Google Sheet v%s\n\n", ESP_GOOGLE_SHEET_CLIENT_VERSION);
// Conectar a Wi-Fi
WiFi.setAutoReconnect(true);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Conectando a Wi-Fi");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(1000);
}
Serial.println();
Serial.print("Conectado con IP: "); Serial.println(WiFi.localIP());
Serial.println();
// Configurar el callback para la generación del token de acceso de Google API
GSheet.setTokenCallback(tokenStatusCallback);
// Configurar el tiempo de refresco del token de acceso antes de expirar
GSheet.setPrerefreshSeconds(10 * 60);
// Iniciar la generación del token de acceso para la autenticación de Google API
GSheet.begin(CLIENT_EMAIL, PROJECT_ID, PRIVATE_KEY);
// Iniciar el servidor web
server.on("/", HTTP_GET, handleRoot);
server.on("/setReferencia", HTTP_POST, handleSetReferencia);
server.begin();
}
void loop() {
int referencia_superior = referencia + Amplitud;
int referencia_inferior = referencia - Amplitud;
// Llamar a ready() repetidamente en el bucle para verificar la autenticación y el procesamiento
bool ready = GSheet.ready();
reconnectWiFi();
reconnectGoogleSheet();
valorHumedad = analogRead(4); // Leer el valor del sensor de humedad
humedad = map(valorHumedad, 0, 4095, 0, 100); // Mapear el valor del sensor a un porcentaje
// Control por histéresis
if (humedad < referencia_inferior) {
while (humedad < referencia_superior) {
// Enviar datos a Google Sheets
enviarDatosGoogleSheets(humedad, motorEstado, referencia_superior, referencia_inferior, referencia);
} else {
digitalWrite(7, LOW); // Apagar el pin de salida
motorEstado = 0; // Actualizar el estado del motor
}
}
void realizarDelayConHandleClient(int segundos) {
int contador = 0;
while (contador < segundos * 10) { // Multiplicamos por 10 para tener iteraciones de 0.1 segundos
delay(100); // Reducimos el delay a 100 ms
contador++;
yield(); // Permitir que el sistema haga sus tareas de mantenimiento
}
}
The text was updated successfully, but these errors were encountered: