Putting the Arduino Yun to sleep

 

Hans and Matilda thought back to the Golem and how he slept between each activity, that could also work for their Yún.

  

The key things were:

 

  • Turning the Linino power off
  • Turning the Linino power back on
  • Low power on the ATMega side
  • Waking back up.
  • Timers and servo.

 

Poweroff is not enough

 

The Linino O/S uses BusyBox for a lot of the tasks of it's shell. One of these is the "poweroff" command. http://www.busybox.net/BusyBox.html#poweroff

Running this with the multimeter in the loop to check the current we see that running poweroff makes no difference to the current draw, the Yún still takes 200mA.

 

/*
  Running shell commands using Process class.
  based on http://arduino.cc/en/Tutorial/ShellCommands
*/

#include <Process.h>

int ledPin = 13;                 // LED connected to pin 13

void setup() {
  pinMode(ledPin, OUTPUT);      // sets the digital pin as output

  pinMode(A5, OUTPUT);
  digitalWrite(A5, HIGH);    // sets the Linino on

  Bridge.begin();    // Initialize the Bridge

  Process p;
  p.runShellCommandAsynchronously("poweroff"); // Run in background so process returns

  digitalWrite(ledPin, HIGH);   // sets the LED on
}

void loop() {
}









 

Test points and wired control

 

A discussion on the Arduino forum lead to a part of the schematic that controlled the 3.3v regulator. The RT8010 regulator has a two test points TP51 and TP52 (bridged by a 0ohm resistor). The author kindly points out where those test points are located as there's no silk screen indicating which are which. As per the example the corner I/O pin was used, A5.

YunPower-sch.png

YunResetWire.jpg

Retrospectively they remembered that the A5 pin is shared with the I2C bus on the Uno, luckily this is not the case for the Yún.

The software control for this is pretty straight forward too, it can be controlled as a digital pin. You'd want to wait until any writing to disk was complete before powering off so that will need to be factored into the software. Using that control the consumption drops to 30mA.

 

int ledPin = 13;                 // LED connected to pin 13

void setup()
{
  pinMode(ledPin, OUTPUT);      // sets the digital pin as output
  pinMode(A5, OUTPUT);
}

void loop()
{
  digitalWrite(A5, LOW);   // sets the Linino off
  digitalWrite(ledPin, HIGH);   // sets the LED on
  delay(8000);                  // waits for a 8 seconds
  digitalWrite(A5, HIGH);    // sets the Linino on
  digitalWrite(ledPin, LOW);    // sets the LED off
  delay(8000);                  // waits for 8 seconds
}








 

 

You are getting sleepy, very sleepy

But it's possible to even better than that. The commands to put the Arduino to sleep are pretty straightforward even so Hans took the approach of using a library. RocketScream had produced one that made life pretty simple so the code example was extended to incorporate that.

 

//Library from http://www.rocketscream.com/blog/2011/07/04/lightweight-low-power-arduino-library/#sthash.PhJ0PF9f.dpuf
#include "LowPower.h"

int ledPin = 13;                 // LED connected to pin 13

void setup()
{
  pinMode(ledPin, OUTPUT);      // sets the digital pin as output
  pinMode(A5, OUTPUT);
  delay(25000);                 // Nice long delay to help with reprogramming    
}

void loop()
{
  digitalWrite(A5, HIGH);    // sets the Linino on
  digitalWrite(ledPin, LOW);    // sets the LED off
  delay(8000);

  digitalWrite(A5, LOW);   // sets the Linino off
  digitalWrite(ledPin, HIGH);   // sets the LED on

  delay(8000);                  // waits for a second
  digitalWrite(ledPin, LOW);   // both lights off, power and P13

  //Sleep
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
}








 

The multimeter uses a different socket for currents over 200mA so a cable swap and photo was taken to get a more accurate reading of the lowest current. For the powerDown the Watchdog timer is used and hence Timer0 which is used for Millis() is turned off and Timer1, used by the Servo() library is also off. This will affect the flashing/colour cycling of the LED and servo so that needs to be factored in the the code.

 

This brings the power down to 2.5mA, approx 80th of the original power required or 33 days of runtime from the battery. Obviously the bursts of activity will bring this down but a week's run time seems achievable.

 

 

IMAG1385[1].jpg

It may also be possible to reduce even more power by permanently turning off those peripherals such as the ADC which are not used although because of the devices used in the project most of the peripherals are used and there may be more effective ways to save power such as minimising the time that the Linino part is powered up.

 

Next: Enchanted Objects Design Challenge - The townsfolk get Rickrolled

 

Reference

 

BusyBox - The Swiss Army Knife of Embedded Linux

Arduino Yun - put linux environment to sleep or halt

Arduino, Zigbee and Embedded Development: Sleeping Arduino - Part 1

http://www.rocketscream.com/blog/2011/07/04/lightweight-low-power-arduino-library/

Advanced Arduino: direct use of ATmega counter/timers

<avr/power.h>: Power Reduction Management

Sparkfun Adventures in Low Power Land