Hi all,
I'm setting up a new low power project based on Arduino Leonardo and I find some problem putting Arduino in sleep mode. I'm using the lowest consumption sleep mode, SLEEP_MODE_PWR_DOWN, from sleep.h library and I measure the current draw from supply drops down to about 1.6mA only after about 15 seconds I execute the sleepNow() function. Before sleepNow(), the currunt is about 35 mA, that I suppose is a normal value. The board wakes up regularly, the problem is only this strange delay for the sleep mode become effective.
Thanks for any suggestion.
How long does that code take to execute? What is the value of 'tsens'? I suggest you put some Serial.print statements in that code so that you can see how long it takes.
btw 1.6mA is far more current than an atmega32u4 should take in power down mode, so I suspect that something else is still getting powered.
Tsens is 2, at the moment I'm using only 2 sensors. The whole setup runs in about 740 mS, 2.5seconds if I consider the software delay()s. 1-wire bus is quite slow.
The current comsumption in sleep mode really looks too high considering I've removed the 5V regulator and power green led on board. And is not a matter of bus or SD card because 1.69 mA drops down to 1.49 if I remove SD card and 1 wire bus sensors, only a 200uA difference.
Anyway nothing on this card can draw current except real time clock chip who needs only few uAmps.
I've found something more.
The current comsumption is high until the interrupt signal from real time clock stays at low level.
The interrupt change level any 32 seconds and so the current draw last for 16 seconds.
What I can't understand is why this happens. The attachInterrupt() function is set as FALLING, the interrupt code runs once any 32 seconds but the sleep mode drains current until pin 0 remain low.
Any idea?
alebit:
I've found something more.
The current comsumption is high until the interrupt signal from real time clock stays at low level.
The interrupt change level any 32 seconds and so the current draw last for 16 seconds.
What I can't understand is why this happens. The attachInterrupt() function is set as FALLING, the interrupt code runs once any 32 seconds but the sleep mode drains current until pin 0 remain low.
Any idea?
The only interrupt mode you are supposed to use for INT0 or INT1 to wake up from power down mode is LOW. If you want to wake up on a transition, you need to use a pin change interrupt.
i not see your sleepNow function listing may be you do something on it before going in sleep . times start from sleep_mode(); instruction . you may decay also power requirements adding
// disable ADC
ADCSRA = 0;
if you net need ad converters and adding
// turn off brown-out enable in software
MCUCR = _BV (BODS) | _BV (BODSE);
MCUCR = _BV (BODS);
to disable brown-out fuse.
or finally descreasing clock speed from 16mhz to 8 or less but take care of serial port speed if you need
void sleepNow() // here we put the arduino to sleep
{
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
sleep_enable();
sleep_mode();
sleep_disable();
}
in power down sleep mode all the cloks should be disabled.
and I've disabled brown-out by fuses.
The problem is not how much current it drains, my question is: why it doesn't really go in sleep mode until the digital input 0 stay low?
Sorry dc42 I didn't see your second post, I've read it just now.
I use interrupt on pin 0 of Arduino Leonardo, this mean INT2 on atmega32U4 and for what I know it's possible to have an interrupt on falling edge of signal ( External Interrupt Control Register A – EICRA). Isn't true?
You can set up an interrupt on a falling edge of INT0 or INT1, but if you want to use one of these interrupts to wake up the device from power-down mode, then it has to be a LOW interrupt. This is because the chip uses the clock to sample the interrupt input and detect a rising or falling edge. See page 72 of the atmega328p datasheet.
I really don't understand well this issue, how can the clock sample the interrupt pin if while the mcu is sleeping in power down mode all the clocks are off ? I suppose the wake-up is asyncronous.
Anyway my problem is not to wake-up the mcu, it wakes up regularly, the problem is that if I keep low the interrupt pin, mcu continues to drain current, even if it's in sleep mode. The wake-up signal comes out from the 1/32 Hz square wave output of a real time clock, and the square wave wake-up the mcu but stays low for 16 seconds. A solution could be to put a monostable ( 1/2 74HC123) between real time clock and mcu, but I would like to know why mcu drains this current, just to find a better solution.
Thanks for any suggesting.
alebit:
I really don't understand well this issue, how can the clock sample the interrupt pin if while the mcu is sleeping in power down mode all the clocks are off ? I suppose the wake-up is asyncronous.
The wake up from a LOW interrupt, or a pin-change interrupt, is asynchronous.
alebit:
Anyway my problem is not to wake-up the mcu, it wakes up regularly, the problem is that if I keep low the interrupt pin, mcu continues to drain current, even if it's in sleep mode.
As you are using the mcu in a way that is not supported to (i.e. you have the interrupt mode set to FALLING when putting it into sleep mode), it is not surprising that the chip is not behaving properly. You need to change the code to use a pin change interrupt. Also check that all unused pins are grounded, or connected to +5V, or have the internal pullup resistor enabled; and that for any analog input pins you are using with the ADC, you have disabled the digital input buffer.
Thanks a lot for all this suggestions, I'll put in practice the whole. Just tell me one more info: where is written that the interrupt mode set to falling is'n allowed in sleep mode? In your previous post you tell about page 72 of atmega328 datasheets, but I can't find such indication there.
It doesn't actually say it "isn't allowed", but it does say that it can't be used to wake up the device from sleep mode, because it needs an i/o clock:
The External Interrupts are triggered by the INT0 and INT1 pins or any of the PCINT23...0 pins.
Observe that, if enabled, the interrupts will trigger even if the INT0 and INT1 or PCINT23...0 pins
are configured as outputs. This feature provides a way of generating a software interrupt. The
pin change interrupt PCI2 will trigger if any enabled PCINT[23:16] pin toggles. The pin change
interrupt PCI1 will trigger if any enabled PCINT[14:8] pin toggles. The pin change interrupt PCI0
will trigger if any enabled PCINT[7:0] pin toggles. The PCMSK2, PCMSK1 and PCMSK0 Registers
control which pins contribute to the pin change interrupts. Pin change interrupts on
PCINT23...0 are detected asynchronously. This implies that these interrupts can be used for
waking the part also from sleep modes other than Idle mode.
The INT0 and INT1 interrupts can be triggered by a falling or rising edge or a low level. This is
set up as indicated in the specification for the External Interrupt Control Register A – EICRA.
When the INT0 or INT1 interrupts are enabled and are configured as level triggered, the interrupts
will trigger as long as the pin is held low. Note that recognition of falling or rising edge
interrupts on INT0 or INT1 requires the presence of an I/O clock, described in ”Clock Systems
and their Distribution” on page 27. Low level interrupt on INT0 and INT1 is detected asynchronously.
This implies that this interrupt can be used for waking the part also from sleep modes
other than Idle mode. The I/O clock is halted in all sleep modes except Idle mode.
Note: Note that if a level triggered interrupt is used for wake-up from Power-down, the required level
must be held long enough for the MCU to complete the wake-up to trigger the level interrupt. If the
level disappears before the end of the Start-up Time, the MCU will still wake up, but no interrupt
will be generated. The start-up time is defined by the SUT and CKSEL Fuses as described in
”System Clock and Clock Options” on page 27.