bclose

Arduino y el modo Sleep

Extendiendo la duración de la baterías

Arduino y el modo Sleep

 

 

    • Buscamos extender el tiempo de uso de un Arduino Nano con baterías.
    • Para ello vamos a ver el modo Sleep.
    • Veremos un programa sencillo que nos permita reducir al máximo el consumo de nuestro circuito.
 

Material requerido.

Imagen de Arduino UNO Arduino Uno o similar.

 

ProtoboardconexionesUna Protoboard mas  cables.
Multimetro sencilloUn multímetro digital.

 

Reduciendo el consumo de Arduino

 

Como vimos en el capítulo previo, Arduino está diseñado más para ser fácil de usar que para consumir poco, sencillamente porque la eficiencia nunca entró en las especificaciones de diseño, hasta muy recientemente.

En la última sesión apuntamos algunas ideas para reducir los consumos pero lo primero que vimos es que un Arduino UNO tiende a consumir uso 45 mA en vacío, mientras que un Nano apena llega a los 15 mA

Ni que decir tiene que sería absurdo usar un Arduino UNO a baterías precisamente porque los circuitos internos de control del USB y especialmente del derrochador regulador de corriente que usa a su entrada, hacen que su consumo sea mucho mayor de lo que nos gustaría y por eso el Arduino Nano aparece como una opción clara para estas ocasiones.

No he tenido ocasión de probar los Arduino Micro, que tiene fama de eficientes, pero espero recibir unos pocos en unos días y ya os daré un reporte sobre ellos (Ya tenían que haber llegado, pero el correo internacional está fatal)

Así que de momento en esta sesión nos centraremos en otra forma de reducir sensiblemente el consumo de nuestro Arduino: El modo Sleep.

El asunto es tan drástico como parece, porque no queremos tener encendido nuestro Duino como un árbol de navidad mientras no hace nada. Lo lógico es apagarlo, o por lo menos, hibernarlo, para que el consumo se reduzca al mínimo posible.

No hemos inventado nada. Los osos y muchos otros animales como serpientes y anfibios suelen invernar en los climas fríos, entrando en un estado de animación suspendida que evita consumir una energía preciosa para llegar a la primavera, en un momento en el que no hay disponible alimento.

Y eso es todo, creo que veréis que es más fácil de lo que parece.

 

Arduino y el modo Sleep

SI echáis una ojeada por internet con este tema encontrareis mucha información acerca del asunto y con mucha frecuencia, os hablaran de que hay que aprender a programar el chip interno de Arduino, el AVR, y os hablaran de no sé qué extravagancias que hay que hacer para ponerlo a dormir.

La Liberia estándar de Arduino, por ahora no permite acceso a las funciones que hacen dormir al MCU (Micontrolador) y hay que usar la librería AVR directamente, pero para eso están las librerías, que almas generosas ponen a disposición de la comunidad.

Recordad las reglas anti paletos. Hay que asustar a los nuevos y convencerles de que esto es muuuuy complicado y que hay que ser ingeniero para ello. Pero no. Es mucho más simple si usas la librería adecuada.

Así que lo primero que os voy a recomendar es que si eres un usuario promedio y hasta justito no se te ocurra estudiar la librería AVR, es mucho más fácil usar una librería que nos haga el trabajo sucio.

Y el caso del modo Sleep de Arduino no es una excepción. Usa la librería LowPower, es ligera y sencilla de usar,  y verás como ella se encarga.

Una vez que descarguéis e instaléis la librería Low-Power-master, os propongo un sencillo ejemplo. Vamos a usar el mismo esquema de la sesión previa para medir el consumo de nuestro Arduino Nano:

Esquema protoboard

 

El programa de control

 

Con el montaje descrito arriba vamos a hacer un programa, sencillo que muestre como dormir nuestro Arduino un tiempo, y después cuando despierte, encendemos dos segundos el LED incluido, y de ese modo que podamos hacer una lectura estable del consumo.

Con un poco de suerte veremos que hay dos consumos diferentes. Cuando está dormido y cuando está despierto y de ese modo podremos comparar ambos.

Lo primero es incluir la librería y definir el pin del LED

#include "LowPower.h"
int LED = 13 ;

void setup()
{    pinMode(13, OUTPUT);    }

Después en el loop, dormimos el Nano un cierto tiempo, en este caso 8 segundos,  y cuando despierta, encendemos el led durante 2 segundos, al cabo de los cuales, volvemos a dormir nuestro Duino:

void loop()
   { LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); 

     digitalWrite(LED, HIGH);
     delay(1000);
     digitalWrite(LED, LOW);
   }

La línea clave, por supuesto, es esta:

    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);

Como veis, simplemente pedimos a la librería que duerma a Arduino 8 segundos y mantenga apagados los convertidores analógico a digital, y el circuito BOD (O Brown Out Detection). Vamos con todo esto.

Si no queréis complicaros más la vida, copiando esta línea, ya dispondréis de un buen ahorro de energía porque duerme a vuestro Arduino 8 segs y después hace lo que le pidamos al despertar.

¿Por qué 8 segundos? Bueno, una de las cosas más complicadas de dormir algo, es decidir cómo despertamos a la bella durmiente, y mucho cuidado aquí, porque si te equivocas puedes dejar tu Arduino por secula seculorum, así que mucho ojo con las pruebas.

 
  • Esto no puede ocurrir con la línea de arriba y por eso lo hacemos como primer ejemplo, así que tranquilos.
  • Si enredando con otros ejemplos no conseguís despertar a vuestro Arduino, hay que vaciarle la flash de programa y la forma más sencilla es reinstalar reprogramarlo con el blinking led o cualquier otro programa que no incluya instrucciones de dormirlo

Hay tres maneras de despertar un Arduino del modo Sleep:

 
  • Interrupciones hardware
  • Timers y WDT que es un timer un tanto peculiar (Y del que ya hablaremos).
  • UART o puerta serie

En este caso estamos usando el Watch Dog Timer y por ahora no quiero entrar detalles, pero nos basta con saber, que es una interrupción periódica que se dispara, si un cierto contador llega a 0.

EL WatchDog Timer acepta diferentes periodos de disparo, de entre una tabla:

SLEEP_15MS
SLEEP_30MS
SLEEP_60MS
SLEEP_120MS
SLEEP_250MS    
SLEEP_500MS    
SLEEP_1S 
SLEEP_2S 
SLEEP_4S 
SLEEP_8S 
SLEEP_FOREVER

Como veis, 8 segundos es el máximo valor que podemos usar, pero nada nos impide hacer un bucle de digamos 15 periodos de 4 segundos para hacer un minuto:

for (int i = 0 ;  i  <  16 ; i++)
             LowPower.powerDown(SLEEP_4S, ADC_OFF, BOD_OFF);

Esto genera un lapso de 4 x 15 segundos = 60, en los que el WDT despierta el micro lo justo para hacer un incremento de la variable i, y volver a dormirse. Y no hay ninguna razón para no hacer lo mismo 4 x 15 x 60 = 1 hora si es lo que queremos.

 
  • De nuevo, mucho cuidado con la opción SLEEP_FOREVER, porque ella solo se sale con una interrupción hardware o COMM y si la usáis alocadamente vais a tener un lío. Tu Arduino dormirá sin que seas capaz de despertarlo.
  • No uséis esto si no sabéis claramente lo que estáis haciendo.

Esta sencilla instrucción es la de menor consumo de energía, pero hay otros modos que pueden mantener encendidos ciertos circuitos del procesador interno del UNO y del Nano y si los necesitáis puede ser útiles:

idle
adcNoiseReduction   
powerDown
powerSave
powerStandby   
powerExtStandby
standby

Aquí os dejo la lista de modos y que hace cada uno, aunque tengo que reconocer que no veo claro muchas cosas, pero en fin quizás vosotros sí que lo veáis.

descripcion de modulos

Si no queréis complicaciones usad la línea de arriba, que es la de mayor ahorro  y listo.

LowPower.powerDown(SLEEP_4S, ADC_OFF, BOD_OFF);

Le pasamos dos parámetros más además del tiempo de despertar, que son:

 
  • ADC_OFF: Apaga los convertidores Analógico a digital (Aunque no se me ocurre para que podemos querer dejarlos encendidos si no tenemos procesador principal)
  • BOD_OFF: Apaga el circuito de Brown Out Detection, que es un circuito para detector niveles peligrosamente bajos de tensión.
  • Si no fuera por este detector BOD, cuando las pilas se fueran agotando la tensión podría descender de un cierto nivel y dañar los circuitos. Apagarlo ayuda a reducir consumo, pero ciertamente corres otros peligros. . 

Vale ¿Y qué consumo podemos esperar de semejante apaño? De nuevo hay que medir para saberlo:

No está mal, bajamos de 15 mA a 4.8 al activar el modo Sleep. Y Fíjate en que no he encontrado el modo de apagar el LED testigo de tensión en el Nano, que quieras que no, consume de continuo un par de mA de los 4.8 que consume el Nano dormido.

Si no recuerdo mal, un LED típico tiene una caída de tensión unos 15 mV, que a 5V son 3mA de consumo. Así que si con una cuchilla os aseguráis de cortar una de las pistas que van al LED piloto, probablemente tendrás un consumo de unos 2 mA dormido, lo que no está nada mal.

 
  • Cuidado, este no es trabajo para manazas. Teneis que aseguraros de cortais solo una de las pistas del LED y nada mas. 

Si tu Arduino lee un par de sensores en digamos 1 segundo a 15 mA de consumo, y lo hace dos veces por hora, podemos esperar un consumo medio de poco más de 2 mAh, pon 3 mAh, Con una batería de 1200 mA, podrás alimentar tu circuito 1.200 / 3 = 400 horas que son 16 días a palmos.

 

Pero elegir las baterías y sobre todo combinarlas de un modo eficiente, es un tema con su propia interés y por eso , en el la próxima sesión hablaremos como sacarlas el máximo partido, y por ahora vale la pena dejar el tema aquí.

 

Resumen de la sesión

 

 

    • Presentamos los motivos por los que queremos maximizar la duracion de las baterias
    • Vimos como reducir al maximo el consumo de Arduino, mediante el modo Sleep.
    • Aprendimos entrar y salir del modo Sleep. 

 

 

 

 

 

(25) Comments

    • Oblicuo

    Hola de nuevo admin,

    Segun lo que me comentas.. y como ya tengo comprado el arduino UNO, ¿hay alguna manera de desactivar el regulador de corriente?. Lo voy a alimentar por USB mediante power-bank con lo que no me hace falta que el regulador esté activo..

    Gracias!

    • Oblicuo

    Hola Admin,

    Estupenda información. Me resulta interesante ya que he comprado un Arduino UNO para controlar un riego automatico casero, y no dispongo de electricidad. Por lo que usare pilas para alimentar el arduino, o bien una power bank.

    En el sigiente parrafo de tu articulo:

    ‘Ni que decir tiene que sería absurdo usar un Arduino UNO a baterías precisamente porque los circuitos internos de control del USB y especialmente del derrochador regulador de corriente que usa a su entrada, hacen que su consumo sea mucho mayor de lo que nos gustaría y por eso el Arduino Nano aparece como una opción clara para estas ocasiones’

    Me surge una duda: ¿quiere decir que el Arduino UNO tiene un regulador de corriente tras la toma USB?. Yo pensaba que el regulador solo se encontraba para el pin VIN… ¿esto es igual para todos los modelos de Arduino?

    Gracias

    • Hola Oblicuo, Todos los arduinos incluido el nano y el UNO, incluyen un regulador de tension para que les puedas conectar hasta 12V. SI usas el conector USB pasan los 5V directamente al circuito, lo mismo que si colocas un power bank conectado a los pines 5V y GND

      Ahora bien el regulador sigue estando alimentado aun en este ultimo caso y desperdiciara algo de energia que a baterias es muy valiosa y por eso es preferible usar un Nano que es el modelo que menos consume o un micro pro que aun consume menos y no incluye regulador ni USB en absoluto

  • Hola Juan,
    Gracias por la explicación. No puedo utilizar interrupción de hardware ya que es una lectura con un tiempo programado. Ademas si se me diera la posibilidad buscaría algún tipo de sonda pasiva que no necesite alimentación, ya que nuestro caballo de batalla en la energía en la cueva y bajo el agua. El reloj RTC lo tengo para grabar la hora y día de la medición. Entiendo que para largos periodos entre lectura que para nosotros van de 1 minuto a 1 hora dependiendo de la estación, mientras superemos los 8 segundos los despertares del arduino para comprobar el bucle “for” no me los quita nadie. La conclusión es que suspensión total durante mas de 8 segundos solo es posible con instrucciones de hardware, con timers necesitamos pequeños despertares para el bucle.

    Gracias

  • Hola Juan,
    Tengo algunas dudas sobre este tutorial que no me han quedado claras, a ver si me puedes aportar luz:

    1. Entiendo que la ventaja de usar aquí el time WDT es por el tema que comentas en el tutorial del watchdog del error inesperado, sabiendo que se rearma y sigue grabando por ejemplo en la SD de un datalogger ¿no?.
    2. Si usamos una interrupción por timer que no sea la del watchdog ¿se podría conseguir mas de 8 segundos sin hacer el bucle for?. ¿Si es así hasta cuanto tiempo podríamos llegar?. Pero perderíamos la seguridad del watchdog ante fallos inesperados ¿no?.
    3. He buscado y he intentado hacer este ejercicio del tutorial usando una interrupción por timer que no sea el timer watchdog, he usado la librería TimeOne.h y de momento no he conseguido nada ni he visto información. ¿Algún ejemplo?.

    Gracias y saludos
    José Lorenzo

    • Hola Jose,

      EN efecto la labor del WDT es asegurarnos de que si nuestro equuipo se cuelga por cualquier razon, hay un circuito hardware que resetea el equipo y lo reinicia.

      Estas WDT son compatibles con otras interrupciones de tipo timers y puedes usaralas a la vez. Tenemos una pequeña introduccion a los timers con timerone incluyendo algun pequeño ejemplo aqui:
      http://www.prometec.net/timers/

      Por ultimo no estoy muy seguro de cual es el maximo tiempo que podemos programa en una interrupcion timer, pero no creo que sea muy superior a los pocos segundos del WDT. Para hacer cosas programadas cada tantos minutos u horas por ejemplo, necesitas disponer un reloj RTC y comprobar en el loop si ha transcurrido el tiempo prefijado. Tambien es muy frecuente usar interrupciones hardware que despiertan al micro cunado se cumple una condicion externa y disparas la ejecucion de una funcion callback

    • ISRAELALVARADO

    amigo otra vez yo, oye y si le pongo 1 minuto cuanto dura despierto puedo configurar cuanto dura despierto o solo el apagado. saludos. excelente trabajo

    • Hola Israel, no estoy seguro de entenderte del todo, pero el Arduino dura despierto lo que tarde en llevar a cabo las instrucciones que vaya a ejecutar.

  • Gracias por la claridad del tutorial que me va a ser de mucha utilidad.

    Estoy trabajando en el diseño de dispositivos para un sistema de gestión de energía doméstico y el control del consumo es por supuesto fundamental así que el uso de la función powerDown de la libreria en modo SLEEP_FOREVER con reactivación por interrupciones es prácticamente un imperativo.

    Como mi siguiente paso es el diseño del circuito en PCB manteniendo solo el chip ATMega2560 de la plataforma Arduino Mega2560 que estoy usando (y que va a ser algo nuevo para mí) me ha entrado una duda conceptual relativa al estado de los circuitos de cada procesador que mencionas y que muestras en la tabla. Mi duda es si hay alguna diferencia en el estado de activación por defecto de estos circuitos en ambos entornos (Arduino y AVR) que pueda resultar en que el comportamiento de la librería una vez compilada con el sketch pueda ser diferente al cargarlo en el chip. En otras palabras mi duda es si la estructura de SW (bootloader + sketch + librerias) es absolutamente la misma en ambos entornos.

    • Hola Mauricio, no puedo hablar por expreiencia propia porque mis montajes nunca han alcanzado el nivel ed serie que pueda montar en una PCB propia, pero hasta donde entiendo, arduino es simplemnte un bootloader en los chips soportados que de alguna manera lanza el programa que compilamos desde el IDE y por ello ambas plataformas deben ser absolutamente iguales porque desde el procesador no se ve la diferencia

      Pero por si acaso, quiza haya leyendo esto alguuien cone xperiencia previa en el tema que nos ayude a a clarar la situacion

  • Gracias por la respuesta, efectivamente el proyecto es muy bonito. En cuanto al circuito que controle la alimentación debe de consumir muy poco, sino estaríamos en las mismas, el tiempo debe de activación debe de coincidir con el tiempo entre muestras que consideremos oportuno. Sacrificaríamos el muestreo inteligente por uno lineal. El tiempo que esta encendido hasta el apagado seria el tiempo de encendido arduino mas el tiempo para realizar una muestra. Se me ocurre un timer con un 555 y un transistor a la salida ¿que opinas? .El tema es que he mirado y el 555 consume entre 3 y 6 mA, por tanto casi igual que el arduino durmiendo. No se, a lo mejor me interesa buscar algún integrado especifico de timer que gaste menos que el 555. Intentamos evitar rehacer los diseños de los dispositivos, ya los tenemos construidos y no nos caben mas baterías, habría que hacerlos de nuevo y no tenemos claro que nos pillen ya las lluvias de octubre…. gracias

  • Felicitaciones por la Pagina !

    mi pregunta es como es el proceso para despertar el arduino a traves de una interrupcion por ejemplo la activacion de un sensor ?

    muchas gracias

  • Buenas tardes,
    Como siempre unos tutoriales fantásticos. Estamos realizando un proyecto de instalación de unos sensores en una cueva. Necesito instalarlos unos 3 o 4 meses y volver a recuperarlos cuando acaba la temporada de lluvias que baja el nivel y podemos entrar. Uso un nano, un reloj RTC y una tarjeta micro SD, 2 baterías de ion de litio en seria de 5.500 mA. El muestreo de datos no es lineal y cuando saltan algunas alarmas intensifica el muestro cada 10 minutos, otras veces cada hora, depende de las circunstancias. El tema es que me hablaron de dormir el arduino con la librería Narcoleptic que pienso que es muy parecida a la librería Lowpower que aquí se trata. No tengo mas espacio para baterías y los cálculos me dicen que si no desconecto el arduino y lo vuelvo a conectar cuando quiera medir, no tengo suficiente energía para esos cuatro meses. La idea seria encenderlo (no dormirlo) cada vez que quiera medir. ¿Hay alguna forma de hacerlo? ¿desde el rtc se podría encender y apagar?. Seria algo así como activar algún pequeño dispositivo que lo encendiera…¿Alguna idea?. SAludos y gracias

    • Buenos dias jose l,orenzo, que preciosidad de proyecto jajajajaj.
      no parece complicado apagar y encender tu arduino. Basta con un circuito que controle su alimentacion pero la cuestio es , ¿como decides scuando hay que encender?
      Otra cuestion adicional seria usar baterias de mayor capacidad que parece mas sencillo y entonces dispones de interrup,ciones para despertar tu arduino

  • Hola, lo he probado con un Arduino UNO y funciona perfecto. Pero con un MEGA ADK no me compila… en la web de la librería parece que soporta Arduino MEGA pero no veo nada de ADK. ¿Es posible que no esté soportado el ADK? ¿Conoces alguna librería similar que pueda usar?
    Gracias!

    • Pues no sé qué decirte, yo he probado a compilarlo con esa placa y me compila bien.

    • Jesus

    Hola:

    genial post, sin duda es lo que se debe aprender desde que se inicia con arduino pues uno confunde delay con sleep (por eso busqúe este tema). Te quería comentar que arriba pones for (int i = 0 ; i < 16 ; i++) pero esto hará 16 ciclos y no 15, se te pasó eso.

    Además, quería preguntarte si tienes algun tutorial en donde enseñes el uso del voltímetro para arduino: medir consumo del circuitos, baterias, etc.; soy estudiante de sistemas y ya tengo conocimientos básicos de arduino (he probado varios sensores y módulos) pero en temas de electrónica -en donde si haces mal una conexión puedes estropear el equipo- es indispensable el uso del voltímetro.

    Finalmente, no me queda claro un ejemplo del uso de una interrupción para salir del SLEEP_FOREVER salvo que arduino esté trabajando con otro micontrolador: ¿cómo podría hacer por ejemplo que arduino duerma hasta que reciba una comunicación serial o una petición http (usando un módulo de ethernet conectado al arduino)? A lo mejor no es el uso ideal pero quería saber si tenía sentido usar sleep o solo queda dejar al arduino escuchando con tal vez pequeños intervalos de sleep de algunos segundos entre lectura.

    De nuevo, muchas gracias por este tutorial. Intentaré conseguirme y aprender a usar un voltímetro para ver temas de consumo y autonomía, saludos.

    • Hola de nuevo Jesus.
      Jajajaj siempre os digo que no os fieis de mi y que comprobeis lo que pongo porque la experiencia me demuestra que me equivoco a menudo.

      Hay un tuto basico en la seccion de electronica sobre el uso del voltimetro que creo que podra servir

      Si usa un ARduino MEGA, las tres puertas de COMM disparan una interrupcion hard en cuanto entre cualquier comunicacion por el pin de recibir y lo mismo pasa en el UNO en su unica puerta COMM, esta interrupcion es interceptada por el driver de la puerta serie que puede ademas guardar una memoria de los ultimos n caracteres recibidos a la espera de que tu los leas y liberes la memoria.

      Hablo de memoria, pero creo recordar que una de las condiciones de salida del modo sleep es precisamente recibir algo por la puerta serie, peroe sto compruebalo por si acaso

  • Afecta en algo combinar esta libreria con la que utiliza el Tyni RTC? Lo que quiero hacer es dejar en modo sleep el arduino hasta cierta hora

    • Pues no sabria que decirte Daniel, pero haz la prueba sin miedo y ya nos contaras que tal va todo

    • Alejandro

    Entiendo. Supongo que despertarlo por interrupción será la solución más optima. Sobre todo en proyectos que únicamente despiertan para tareas puntuales y que además necesitan gran duración.

    Gracias y un saludo!

    • Claro y la mas razonable, lo que pasa que usar el watch dog es comodo si no hay demasiado problema

  • Gracias Admin una vez más por compartir tu conocimiento. A todo esto me surge una duda. Al entrar en el modo sleep muchas veces en muy breves periodos de tiempo teniendo que encender y desconectar los convertidores ¿Esto no se puede volver contraproducente en la finalidad de la técnica de ahorrar energía? Es decir, si yo apago mi arduino cada 8 segundos para despertarlo realizar una operación y volverlo a dormir, en estos arranques y apagados tan sucesivos no se produce un incremento en el consumo de energía mayor que si simplemente lo dejo corriendo?

    Un saludo y Gracias de Antemano!

    • Hola Alejandro, Desde luego va a consumir mas que si estuviera perpetuamente dormido y habria que medir para estar seguro de que ahorramos energia.

      De todos modos veras en los proximos capitulo que lo ideal es dormir arduino ad infinitum y despertarlo por interrupcion

Give a Reply

WordPress Anti-Spam by WP-SpamShield