3

In the process of trying to make a small system that will last a while on 4 AA batteries, I've reduced my Arduino project to a barebones system that when asleep draws a tiny amount of current from the batteries.

However, to achieve this, I found it would be necessary to cut power to the two attached peripheral devices (connected to an ATMega328P-PU). One of them is an I2C device, and the other is a serial device, and both are attached to the hardware serial/I2C pins as appropriate.

In terms of powering the peripherals, the bases of two transistors are connected to two of the digital pins, and power to them is controlled from code via these transistors. Both devices are 5V, and when the system is running the total current draw is around 200mA.

Basically this setup works, however I'm getting "random" system hanging and essentially an unreliable project. Sometimes when I power it up it will work as normal, but then hang and not sleep. Other times, it will sleep, but then freeze after waking or just get stuck during waking (which I can tell because the serial device powers up first and does nothing, but the I2C device remains off).

My best guess is the root of the cause is either something to do with the serial communication being interrupted by sleeping the MPU (I'm using the maximum power saving sleep, which is woken by an external interrupt on pin 2), or possibly some sort of power problem (sudden current draw from battery?) that occurs when the peripherals are powered on in code (though I don't know how I should test this).

So far, I've tried calling Serial.end() before sleeping the MPU, and Serial.being(9600) on waking, and have scattered delay(1000)s throughout to ensure everything has enough time to get running, but the problem still remains.

Does anyone have any pointers on things I could change/test, or an alternative approach I could take to make the same power savings?

EDIT: Some more details

The transitors used are TIP 120's. The connections are essentially an exact copy of the image here: https://ctheds.files.wordpress.com/2007/10/tip120.jpg, except the resistors used are 560 Ohms (just what I had to hand, no other reason, didn't think it would change anything).

The I2C peripheral is a 20x4 LCD (which I believe is HD44780 compliant). The serial device is an GT511C3 fingerprint sensor. I don't believe either of them have any automatic power saving features, though I haven't looked for such things in the documentation explicitly.

The exact code I use to call sleep is

set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sleep_mode();

which I'm lead to believe is the lowest power mode, and aside from this problem works well for my system.

  • Please show us how you connected the peripherals with the transistors? Which transistors did you use? What peripherals do you use, as some have power saving features themselves? Also, please post the code where it hangs. Power spikes/dips seems like a possible explanation. You could use the watchdog timer to reset the arduino when it hangs, but that isn't really a fix for original problem. – Gerben Jan 28 '15 at 18:50
  • What sleep mode do you use? In some recent experiments, I found out that ATmega USART (serial comm) was not compatible with ANY sleep mode except the IDLE mode. – jfpoilpret Jan 28 '15 at 21:53
  • Also you might consider replacing your transistors with MOSFETs, which shall reduce consumption further. – jfpoilpret Jan 28 '15 at 21:54
  • Does it work as intended if you remove the transistors, but use the sleep mode? I mean, maybe the sleepmode is the problem itself – Allan Nørgaard Jan 29 '15 at 14:01
  • 1
    Be aware that running the AVR straight from the battery works, but might require to speed down the clock (16MHz requires a minimum of 3.7v according to the spec) I had a couple of similar problems in my project and 'solved' them with a rather brutal approach (holadimake.wordpress.com/2015/01/24/…). – Stephan Noller Mar 5 '15 at 6:37
1

Using an NPN transistor to control power to a peripheral may be problematic.

An NPN transitor would presumably be used as a low-side switch interrupting the peripheral's ground line, however, even when turned on this will have a non-trivial voltage drop.

Most logic level definitions are asymmetric, ie, the maximimum legal voltage for a logic "0" is relatively low. If you insert the voltage drop of a bipolar transistor into a peripheral's ground line, then it may be borderline unable to drive a fully legal '0' to the ATmega, which is reference to the lower true ground and would see the peripheral's ground difference added to its output voltage.

A better approach would be to use either a high-side switch (as there is typically more room between the minimum legal '1' and the supply) or else to use an FET switch which would have a much lower voltage drop.

Also keep in mind that most IC's are not specified to tolerate lasting I/O voltages much outside of the range of their power suppliers, and in fact their protection diodes may mean that application of such voltages effectively powers them through the I/O pin. So before turning off power to a peripheral, you probably want the ATmega software to assert all shared I/O lines towards the side of the peripheral supply which is not being disconnected, ie, for a low side switch drive everything high and for a high side switch drive everything low.

Finally, the process of power cycling could potentially confuse peripheral interface engines and it is possible that some error flags set in this process might never be cleared. So you may want to clear the flags of and generally re-initialize your USART, I2C, etc on resume.

  • Sadly, this is a long dead project, and the bits to put it back together are a bit scattered... Nevertheless, I am most interested by your take on things. These are problems I hadn't considered (or even realised existed, coming from a largely software background). Thanks very much! I hope that if I get around to trying something like this again in the future it will succeed! – J.B May 22 '16 at 19:14
0

I hear great things about the cosa core for Arduino. It's a fantastic alternative Arduino core and exposes the power management capabilities of the micro-controller that are not exposed by the standard Arduino core.

You might find it is too different for your experience but then again it is excellent and worth a look.

https://github.com/mikaelpatel/Cosa

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.