Arduino (IoT): Simple Tutorial Medición de Corriente Sleep Mode AVR

Arduino Honduras Santiapps Marcio Valenzuela

Tutorial Medición de Corriente Sleep Mode AVR

En  un tutorial anterior vimos como medir la corriente consumida por la MCU.  El mismo método puede ser utilizado para medir el consumo de corriente de un proyecto completo, al insertar el medidor entre la fuente de poder.  Antes de llegar a ese ejemplo, el cual nos ayudara a medir el consumo energético de un proyecto para poder hacer cálculos de autonomía (por ejemplo cuanta energía tendríamos que producir y almacenar para un proyecto solar por ejemplo), vamos a ver como podemos ahorrar energía poniendo nuestra Arduino a dormir.

Requisitos:

  1. Computadora (mac)
  2. Arduino UNO
  3. Medidor de Voltaje/Corriente
  4. Battery Pack
  5. Breadboard
  6. Arduino IDE (https://www.arduino.cc/en/Main/Software)

El proyecto de nuestra Arduino es asi:


Esta vez cargaremos un sketch asi:


#include <avr/sleep.h>

/* Sleep Demo Serial
* -----------------
* Example code to demonstrate the sleep functions in an Arduino.
*
* use a resistor between RX and pin2. By default RX is pulled up to 5V
* therefore, we can use a sequence of Serial data forcing RX to 0, what
* will make pin2 go LOW activating INT0 external interrupt, bringing
* the MCU back to life
*
* there is also a time counter that will put the MCU to sleep after 10 secs
*
* NOTE: when coming back from POWER-DOWN mode, it takes a bit
* until the system is functional at 100%!! (typically <1sec)
*
* Copyright (C) 2006 MacSimski 2006-12-30
* Copyright (C) 2007 D. Cuartielles 2007-07-08 - Mexico DF
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

int wakePin = 2; // pin used for waking up
int sleepStatus = 0; // variable to store a request for sleep
int count = 0; // counter

void wakeUpNow() // here the interrupt is handled after wakeup
{
// execute code here after wake-up before returning to the loop() function
// timers and code using timers (serial.print and more...) will not work here.
// we don't really need to execute any special functions here, since we
// just want the thing to wake up
}

void setup()
{
pinMode(wakePin, INPUT);

Serial.begin(9600);

/* Now it is time to enable an interrupt. In the function call
* attachInterrupt(A, B, C)
* A can be either 0 or 1 for interrupts on pin 2 or 3.
*
* B Name of a function you want to execute while in interrupt A.
*
* C Trigger mode of the interrupt pin. can be:
* LOW a low level trigger
* CHANGE a change in level trigger
* RISING a rising edge of a level trigger
* FALLING a falling edge of a level trigger
*
* In all but the IDLE sleep modes only LOW can be used.
*/

attachInterrupt(0, wakeUpNow, LOW); // use interrupt 0 (pin 2) and run function
// wakeUpNow when pin 2 gets LOW
}

void sleepNow() // here we put the arduino to sleep
{
/* Now is the time to set the sleep mode. In the Atmega8 datasheet
* http://www.atmel.com/dyn/resources/prod_documents/doc2486.pdf on page 35
* there is a list of sleep modes which explains which clocks and
* wake up sources are available in which sleep mode.
*
* In the avr/sleep.h file, the call names of these sleep modes are to be found:
*
* The 5 different modes are:
* SLEEP_MODE_IDLE -the least power savings
* SLEEP_MODE_ADC
* SLEEP_MODE_PWR_SAVE
* SLEEP_MODE_STANDBY
* SLEEP_MODE_PWR_DOWN -the most power savings
*
* For now, we want as much power savings as possible, so we
* choose the according
* sleep mode: SLEEP_MODE_PWR_DOWN
*
*/
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here

sleep_enable(); // enables the sleep bit in the mcucr register
// so sleep is possible. just a safety pin

/* Now it is time to enable an interrupt. We do it here so an
* accidentally pushed interrupt button doesn't interrupt
* our running program. if you want to be able to run
* interrupt code besides the sleep function, place it in
* setup() for example.
*
* In the function call attachInterrupt(A, B, C)
* A can be either 0 or 1 for interrupts on pin 2 or 3.
*
* B Name of a function you want to execute at interrupt for A.
*
* C Trigger mode of the interrupt pin. can be:
* LOW a low level triggers
* CHANGE a change in level triggers
* RISING a rising edge of a level triggers
* FALLING a falling edge of a level triggers
*
* In all but the IDLE sleep modes only LOW can be used.
*/

attachInterrupt(0,wakeUpNow, LOW); // use interrupt 0 (pin 2) and run function
// wakeUpNow when pin 2 gets LOW

sleep_mode(); // here the device is actually put to sleep!!
// THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP

sleep_disable(); // first thing after waking from sleep:
// disable sleep...
detachInterrupt(0); // disables interrupt 0 on pin 2 so the
// wakeUpNow code will not be executed
// during normal running time.

}

void loop()
{
// display information about the counter
Serial.print("Awake for ");
Serial.print(count);
Serial.println("sec");
count++;
delay(1000); // waits for a second

// compute the serial input
if (Serial.available()) {
int val = Serial.read();
if (val == 'S') {
Serial.println("Serial: Entering Sleep mode");
delay(100); // this delay is needed, the sleep
//function will provoke a Serial error otherwise!!
count = 0;
sleepNow(); // sleep function called here
}
if (val == 'A') {
Serial.println("Hola Caracola"); // classic dummy message
}
}

// check if it should go to sleep because of time
if (count >= 10) {
Serial.println("Timer: Entering Sleep mode");
delay(100); // this delay is needed, the sleep
//function will provoke a Serial error otherwise!!
count = 0;
sleepNow(); // sleep function called here
}
}

El código produce este resultado en el Serial Monitor:

Arduino IoT Simple Tutorial Medicion de Corriente AVR Sleep Mode by Santiapps Marcio Valenzuela
Arduino IoT Simple Tutorial Medicion de Corriente AVR Sleep Mode
Como podemos ver el codigo hace que la Arduino duerma luego de 10 segundos.  Es importante entender esto para que a la hora de medir la corriente sepamos que el consumo deberá bajar luego de 10 segundos para ver el ahorro.

Este código esta tomado del sitio Arduino.cc y es importante usar el Resistor 220Ohms entre el pin2 y el pin0(Rx). Subamos el código a la Arduino y luego hagamos las conexiones como hicimos anteriormente para medir la corriente.  La idea es medir la corriente mientras la Arduino esta despierta vs cuando esta dormida.

El resultado final esta aqui, sin embargo es igual a la anterior:


Pero luego de 10 segundos:


Como vemos el consumo baja de 46.5mA a 33.3mA.  Esto representa un ahorro del 28%.

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s