Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESP32 google sheets error (Failed to initlalize the SSL layer.) #103

Open
cesarruiz730 opened this issue Jun 16, 2024 · 0 comments
Open
Labels
question Further information is requested

Comments

@cesarruiz730
Copy link

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

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);

  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
}
}

@cesarruiz730 cesarruiz730 added the question Further information is requested label Jun 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

1 participant