This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm whether you accept or reject these cookies being set.

A cookie will be stored in your browser regardless of choice to prevent you being asked this question again. You will be able to change your cookie settings at any time using the link in the footer.

  • 1 voto(s) - 4 Media
  • 1
  • 2
  • 3
  • 4
  • 5
ESP8266 callback + deepSleep
#1
Buenas tardes a todos,

llevo un par de días atascado con este problema y no veo solución, incluso he seguido el github de @grafisoft, pero a mí no me funciona Github IOT

Estoy intentando implementar en un ESP8266 la función deepSleep junto con un Callback para recibir un mensaje de MQTT. Este callback lleva el nuevo valor que obtendrá el nodo para el deepSleep.

El funcionamiento sería el siguiente:

Nodo despierto -> lee callback -> realiza mediciones -> envía mediciones -> sleep(valor callback)

Sin emabrgo, la función callback no la realiza:

Nodo despierto -> realiza mediciones -> envía mediciones -> sleep(valor porDefecto)

Como dato curioso, si modifico el deepSleep por delay, si consigue entrar en la función Callback.

Dejo aquí el código que estoy empleando a ver si alguien consigue saber que puedo estar haciendo mal.

Gracias de antemano.

Código:
#include <ESP8266WiFi.h>  //WIFI ESP8266
#include <PubSubClient.h>  // MQTT

// Update these with values suitable for your network.
const char* ssid = "linksys";
const char* password = "";
const char* mqtt_server = "192.168.1.3";

//----------------------- CONFIG PARAMETERS------------------------
//Con este parametro se construye todos los topics para el protocolo MQTT.
// Nombre del nodo.
String NodeName = "Testing";
String TopicMQTT; //Variable para construir el Topic de MQTT.
//El tiempo de sueño se especifica en el fichero funciones.h (sleeptime).
//-----------------------------------------------------------------

WiFiClient espClient;
PubSubClient client(espClient);

const int sleeptime = 60 * 10e5; // En segundos //20 * 60 * 1000000;
int rate = 100000;


//----------------------- WIFI CONNECTION ------------------------
void setup_wifi() {
 delay(10);
 // We start by connecting to a WiFi network
 Serial.println();
 Serial.print("Connecting to ");
 Serial.println(ssid);

 WiFi.begin(ssid, password);

 while (WiFi.status() != WL_CONNECTED) {
   delay(500);
   Serial.print(".");
 }

 Serial.println("");
 Serial.println("WiFi connected");
 Serial.println("IP address: ");
 Serial.println(WiFi.localIP());
}
//-----------------------------------------------------------------

//----------------------- WIFI RE-CONNECTION ------------------------
void reconnect() {
 // Loop until we're reconnected
 while (!client.connected()) {
   Serial.print("Attempting MQTT connection...");
   // Attempt to connect
   if (client.connect("ESP8266Client")) {
     Serial.println("connected");
     // Once connected, publish an announcement...
     client.publish("arboles/naranjo/info", "Conectado");
     // ... and resubscribe
     //client.subscribe("arboles/configuracion/rate");
     client.subscribe("arboles/configuracion/rate");
     //client.subscribe("despacho/luz");
   } else {
     Serial.print("failed, rc=");
     Serial.print(client.state());
     Serial.println(" try again in 5 seconds");
     // Wait 5 seconds before retrying
     delay(5000);
   }
 }
}
//-----------------------------------------------------------------

//----------------------- CALLBACK ------------------------
void callback(char* topic, byte* payload, unsigned int length) {
 Serial.print("Message arrived [");
 Serial.print(topic);
 Serial.print("] ");
 for (int i = 0; i < length; i++) {
   Serial.print((char)payload[i]);
 }
 Serial.println();
 Serial.print("El valor entero es: ");
 payload[length] = '\0';
 rate = atoi((char*)payload); //Char to int
 rate = rate * 1000;
 Serial.println(rate);
 //EEPROM.put(rate_address, rate);
}
//-----------------------------------------------------------------


void setup() {
 pinMode(LED_BUILTIN, OUTPUT);
 digitalWrite(LED_BUILTIN, LOW);
 Serial.begin(9600); //Velocidad del UART.
 setup_wifi();
 //Configuracion conexion a MQTT.
 client.setServer(mqtt_server, 1883);
 client.setCallback(callback);
}

void loop() {

  //Conexión con el broker MQTT.
 if (!client.connected()) {
   reconnect();
 }
 client.loop();

 //delay(1000);
 // Tiempo de deepSleep especificado en 'sleeptime'.
 //ESP.deepSleep(rate);
 ESP.deepSleep(sleeptime); //, WAKE_RF_DEFAULT);
}
  Responder
#2
Esta mañana he estado probando también a poner el nodo en LightSleep

Código:
// Required for LIGHT_SLEEP_T delay mode
extern "C" {
#include "user_interface.h"
}

Código:
void sleep_function()
{
/* LIGHT SLEEP */
//WiFi.disconnect(); // DO NOT DISCONNECT WIFI IF YOU WANT TO LOWER YOUR POWER DURING LIGHT_SLEEP_T DELLAY !
//Serial.println(WiFi.status());  
digitalWrite(LED_BUILTIN, HIGH);
wifi_set_sleep_type(LIGHT_SLEEP_T);
delay(6000*300-800); // loop every 3 minutes

/* DEEP SLEEP */
//ESP.deepSleep(9e8);
}

Pero aunque si se "duerme" correctamente, tampoco consigue entrar de nuevo en la función Callback.
  Responder
#3
Quizas no le de tiempo a recibir el topic del MQTT al que esta subscrito y por eso no te pilla el valor. Guardas el valor en mqtt con modo persistente? (para que siempre este el dato en el servidor y no se borre una vez entregado). Si el valor ha sido entregado una vez, ya no lo vuelve a enviar de forma automatica.
-> Mi CNC de escritorio CNCDesktop 500 -> https://www.spainlabs.com/foros/tema-Fresadora-Desktop-CNC-500
-> Laboratorio de Fabricación Digital Maker www.lowpower.io 
--> Twitter: https://twitter.com/Grafisoft_ES  | IG: https://www.instagram.com/lowpowerio/
  Responder
#4
Posiblemente pueda ser que no le da tiempo a recibir el mensaje. No sé muy bien como funciona el evento del callback, pero ahora mismo estoy inyectando un mensaje cada 0.1segundos y no lo recibe. Sin embargo, por la terminal si puedo leerlo:

Código:
pi@raspberrypi:~ $ mosquitto_sub -t "arboles/configuracion/melocotonero/rate/#" -v
arboles/configuracion/melocotonero/rate 62
arboles/configuracion/melocotonero/rate 3000
arboles/configuracion/melocotonero/rate 3000
arboles/configuracion/melocotonero/rate 3000
arboles/configuracion/melocotonero/rate 3000
arboles/configuracion/melocotonero/rate 3000

Entonces no sé cuanto tiempo necesita el micro para procesar un callback, aunque entiendo también que si recibe un callback no debería entrar en sleep. Más bien es como una interrupción, si recibe un mensaje en el tópico, para el proceso que esté realizando, ejecuta las acciones y vuelve a donde estaba. Obviamente si está en sleep no hará caso.

Ahora mismo estoy probando con QoS = 1 y retention = true en el nodo de nodered.

[Imagen: Screen-Shot-2019-12-24-at-15-01-17.png]

[Imagen: Screen-Shot-2019-12-24-at-15-01-26.png]

[Imagen: Screen-Shot-2019-12-24-at-15-01-39.png]

Sin embargo, nunca recibe ningun mensaje en el tópico: 
Código:
 client.subscribe("arboles/configuracion/melocotonero/rate");

Ni tan si quiera hace un amago de entrar en la función callback.
Código:
Connecting to linksys
......
WiFi connected
IP address:
192.168.1.50
Attempting MQTT connection...connected
Temperatura = 612.80
Humedad = -6216.69
Bateria = 100
Go to sleep
INFO: Closing the Wifi connection
Waiting for shutdown before sleeping
tx�CGH,@>h�␐␡�
Connecting to linksys
......
WiFi connected
IP address:
192.168.1.50
Attempting MQTT connection...connected
Temperatura = 612.80
Humedad = -6216.69
Bateria = 100
Go to sleep
INFO: Closing the Wifi connection
Waiting for shutdown before sleeping
�H�l�h���␄xH�!��
Connecting to linksys
......
WiFi connected
IP address:
192.168.1.50
Attempting MQTT connection...connected
Temperatura = 612.80
Humedad = -6216.69
Bateria = 100
Go to sleep
INFO: Closing the Wifi connection
Waiting for shutdown before sleeping
Ȥl���l$��$:h��
Connecting to linksys
......
WiFi connected
IP address:
192.168.1.50
Attempting MQTT connection...connected
Temperatura = 612.80
Humedad = -6216.69
Bateria = 100
Go to sleep
INFO: Closing the Wifi connection
Waiting for shutdown before sleeping
Ȥl���l$�␇␚:h��
Connecting to linksys
......
WiFi connected
IP address:
192.168.1.50
Attempting MQTT connection...connected
Temperatura = 612.80
Humedad = -6216.69
Bateria = 100
Go to sleep
INFO: Closing the Wifi connection
Waiting for shutdown before sleeping
␎HpY�CGH�@>h�␐␡�

Otra posibilidad sería la existencia de algún servicio o request, que cuando se despertase el nodo pidiera al servidor el valor de una variable. Pero no he encontrado nada respecto a esta funcionalidad por la web.

En caso de que no exista esa función, ¿cómo puedo forzar al nodo a que espere a recibir algún callback? Porque supongo que añadir un gran delay no servirá.

Otra duda que me viene es que cuando yo desde la terminal me conecto al tópico, siempre me devuelve un valor que tengo guardado en el servidor nodered. Pero en el nodomcu ese mensaje tampoco aparece.

He estado revisando y la gente solo se suscribe al tópico en la función reconnect.

Código:
void reconnect() {
 // Loop until we're reconnected
 while (!client.connected()) {
   Serial.print("Attempting MQTT connection...");
   // Attempt to connect
   if (client.connect("ESP8266Client")) {
     Serial.println("connected");
     // Once connected, publish an announcement...
     client.publish("arboles/melocotonero/info", "Conectado");
     // ... and resubscribe
     //client.subscribe("arboles/configuracion/rate");
     client.subscribe("arboles/configuracion/melocotonero/rate");
     //client.subscribe("despacho/luz");
   } else {
     Serial.print("failed, rc=");
     Serial.print(client.state());
     Serial.println(" try again in 5 seconds");
     // Wait 5 seconds before retrying
     delay(5000);
   }
 }
}

Yo incluso la he añadido en el setup pero tampoco ha funcionado.

A ver si podemos dar con alguna estrategia para poder entrar en el callback.

Gracias de nuevo y feliz Navidad!
  Responder
#5
No he probado nunca el tema de subcribir con el esp, pero en algun lado tendras la info del topic subscrito, o igual no la estas guardando.

Prueba añadir algun delay de varios segundos antes de irte a dormir.
-> Mi CNC de escritorio CNCDesktop 500 -> https://www.spainlabs.com/foros/tema-Fresadora-Desktop-CNC-500
-> Laboratorio de Fabricación Digital Maker www.lowpower.io 
--> Twitter: https://twitter.com/Grafisoft_ES  | IG: https://www.instagram.com/lowpowerio/
  Responder
#6
(24-12-2019, 05:25 PM)grafisoft escribió: No he probado nunca el tema de subcribir con el esp, pero en algun lado tendras la info del topic subscrito, o igual no la estas guardando.
Vaya... pensaba que sí al verlo en tu Github. ¿A qué te refieres con la info del topic suscrito?

(24-12-2019, 05:25 PM)grafisoft escribió: Prueba añadir algun delay de varios segundos antes de irte a dormir.
Acabo de probar con varios valores entre 5 y 10 segundos y no reacciona. De todas formas no sé si ahí afectan en el comportamiento para leer, ya que creo que comprueba los callback en la función "client.loop()"
  Responder
#7
Lo he podido solucionar haciendo un loop temporal en la conexión.

Código:
//TRANSFER CODE FROM LOOP TO HERE
uint32_t loopStart = millis();
while (millis() - loopStart < 15000) {
if (!client.connected()) {
reconnect();
} else client.loop();
} //END OF LOOP CODE

La solución la saqué de una consulta abierta en el git de la librería: https://github.com/knolleary/pubsubclient/issues/634
  Responder
#8
Lo que hace el codigo ese es estar continuamente comprobando dursnte un tiempo.
-> Mi CNC de escritorio CNCDesktop 500 -> https://www.spainlabs.com/foros/tema-Fresadora-Desktop-CNC-500
-> Laboratorio de Fabricación Digital Maker www.lowpower.io 
--> Twitter: https://twitter.com/Grafisoft_ES  | IG: https://www.instagram.com/lowpowerio/
  Responder
#9
Exacto, pero sobre todo fuerza a reentrar en la función callback que está en el client loop
  Responder
#10
Si, de la otra forma pasa una vez y fin.

Me alegra que hayas encontrado la solución Sonrisa
-> Mi CNC de escritorio CNCDesktop 500 -> https://www.spainlabs.com/foros/tema-Fresadora-Desktop-CNC-500
-> Laboratorio de Fabricación Digital Maker www.lowpower.io 
--> Twitter: https://twitter.com/Grafisoft_ES  | IG: https://www.instagram.com/lowpowerio/
  Responder


Posibles temas similares…
Tema Autor Respuestas Vistas Último mensaje
  ESP8266 queda inaccesible juandavid8a 4 2,671 16-02-2023, 07:40 AM
Último mensaje: ruben2023
  CONSULTA Clones ESP32 y ESP8266 Anje 5 1,758 15-11-2020, 11:14 AM
Último mensaje: grafisoft
  [SOLUCIONADO]Raspberry Pi no ve mensaje ESP8266 silth 9 2,301 24-04-2020, 07:30 PM
Último mensaje: grafisoft
  [SpainLabsIoT2018] Caso real: Nodos ESP8266 grafisoft 78 26,394 09-04-2020, 03:33 PM
Último mensaje: grafisoft
  APORTE [SpainLabsIoT2018] ESP8266 NodeMCU - Ajustando su consumo (hack) grafisoft 10 8,963 24-04-2019, 04:49 PM
Último mensaje: grafisoft