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.
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.
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
Top Comments