En este momento ya tenemos el ESP8266 soldado en la placa y pinchado en la protoboard, es el momento de probar el modo deep-sleep.
¿Cómo funciona?
El micro arranca normalmente conectándolo a la alimentación o pulsando el botón de reset, ejecuta la función setup() y cuando la acaba ejecuta la función loop(), ¿que tenemos que hacer?, sencillo. En el momento en el que queramos podremos utilizar la función ESP.deepSleep(x)
, dónde x es el tiempo en microsegundos que va a estar dormido y el micro se pondrá automáticamente en ese modo. La función deepsleep admite un segundo parámetro que es el modo en el que va a despertar la radio, nosotros, como no utilizaremos la Wifi ponemos el modo WAKE_RF_DISABLED
. Eso implica que en el siguiente reinicio la WiFi no va a estar disponible y no va a haber forma de habilitarla. En el caso en el que necesitemos la Wifi simplemente haremos un ciclo de deep sleep corto en el que cambiaremos el parámetro (ya lo veremos).
Por lo que he visto con esta función hay algún lío, por lo que utilizaremos realmente:
system_deep_sleep_set_option(WAKE_RF_DISABLED);
system_deep_sleep(segundos*1000*1000);
Funcionalmente es lo mismo, primero seleccionamos el modo para que se inicie sin WiFi y después activamos el modo de deep sleep. Desde ese momento el ESP empezará a consumir unos 20 uA y, una vez transcurrido el tiempo pondrá el GPIO16 a nivel bajo. ¿Que es lo que pasará?, NADA.
Para que pase algo tenemos que conectar el GPIO16 con el reset, cuando eso ocurra sencillamente el ESP recibirá un nivel bajo en el pin de reset y se reiniciará el programa de nuevo. Ojo!!!! es exactamente lo mismo que pulsar el botón de reset, de hecho si mientras el ESP está en deep sleep pulsamos físicamente el botón de reset ocurrirá lo mismo.
(Como en posts anteriores no quiero reinventar la rueda y hacer un tratado sobre los modos de sleep, están muy bien documentados aqui)
Pero ¿cómo me acuerdo en que punto estaba del programa?
La primera tentación siempre es utilizar la memoria EEPROM, que en el ESP está emulada sobre la nvRAM mediante una librería. Pero hay que tener mucho cuidado, el número máximo de escrituras antes de que deje de funcionar es de unas 10.000 (hay diversas opiniones al respecto) por lo que si hacemos un ciclo de 2 segundos en el cual escribimos la información que queremos transmitir al siguiente ciclo solo tendremos 20.000 segundos hasta que la memoria del ESP se averíe, eso le dará una vida útil a nuestro circuito de unas 6 horas.
Afortunadamente el ESP8266 cuenta con 512 bytes de memoria RTC que se guarda incluso aunque el micro esté en modo deep sleep, es en esta memoria en la que almacenaremos los datos que tengan que sobrevivir a un deep sleep.
¿como lo hacemos?, sencillo, los guardamos en una variable que guardamos siempre antes del deep sleep en la memoria RTC, lo primero que hace nuestro programa es copiarlos de la memoria RTC a la variable, con lo que los tendremos disponibles.
¿Cómo lo hacemos? lo hacemos así.
Sí, pero ¿que pasa en el primer arranque o en un reinicio?
Si vamos a cargar una variable desde la memoria RTC la primera vez que arranquemos el ESP o si se le desconecta la alimentación no sabremos lo que carga, como esa variable es la que determina que vamos a hacer es muy recomendable saber si el ESP viene de un seep sleep o se ha iniciado porque se ha alimentado de nuevo. He hecho esta función:
boolean bootFromDeepSleep (){
if (ESP.getResetReason()=="Deep-Sleep Wake"){returntrue;}
returnfalse;
}
Sencillamente, al principio del setup valoraremos el resultado de la función, si devuelve true podemos cargar de la memoria RTC con seguridad y continuar con la ejecución, en cualquier otro caso vamos a hacer otra cosa.
Y la cosa que haremos es cargar los mismos valores de la EEPROM (nvRam en el ESP), para evitar tener que cargar unos valores por defecto para el primer arranque lo que haremos es que en la variable guardada los primeros valores sean conocidos, si los valores que se cargan no son los que esperamos la EEPROM se inicializará con unos valores por defecto, lo cual resolverá el problema. También tendremos que guardar la configuración de la memoria RTC en la EEPROM cada cierto tiempo, de esta forma tendremos los contadores menos actualizados, pero no desactualizados del todo. hay que tener la precaución de que el numero de ciclos de escritura en la EEPROM no supere la vida útil del equipo.
¿En que punto estamos?
Ahora mismo tenemos un ESP8266 en una placa de prototipos durmiendo la mayor parte del tiempo y despertando con unas variables definidas en el ciclo anterior. El ESP despierta sin WiFi para tener el mínimo consumo.
Si el dispositivo se ha desconectado de la alimentación, Lo detecta y recoge unos valores de la EEPROM en lugar de iniciarse con valores desconocidos.
Periódicamente guardamos en la EEPROM los valores actualizados, asumiendo que si guardamos cada x ciclos nos podemos encontrar una desactualización de los valores.
Además antes de cargar esos valores de la EEPROM comprobamos si son consistente, si no lo son reiniciamos a los valores por defecto y empezamos de cero (mejor eso que nada).
Hola,
es posible que no te haga falta saberlo, simplemente haz el wake up, haz todo lo que tengas que hacer (leer sensores, guardar valores) y después de obtener la lectura ponlo en sleep de nuevo durante el tiempo que necesites.
Como norma general el mismo código tarda el mismo tiempo, pero con la lectura de sensores puede depender de otras cosas, por ejemplo, en un sensor de ultrasonidos el tiempo necesario para las lecturas depende de la distancia, eso si no lo sofisticas más. Nosotros, por ejemplo, si la primera lectura es igual a la última ya no hacemos más, pero si es diferente hacemos algunas lecturas para sacar un median, eso hace que el tiempo despierto pueda ser diferente entre lecturas.
Para acabar, si lo que te motiva el conocer el tiempo que está despierto es «controlar» el tiempo real (en cada ciclo reinicia el contador de millis) es posible que no puedas hacerlo con precisión. Si aún así quieres acercarte una buena opción sería guardar el valor de millis() en la RTC (o ir incrementando una variable en cada ciclo) justo antes de entrar en deep sleep. Es decir tienes una variable que vas conservando entre ciclos, antes de entrar en deep sleep la incrementas con los millis y con el tiempo que pones el micro en deep sleep.