Our measurements may not likely be the same based on several factors. Firstly, you're using a different chip. Secondly, I don't know what your setup looks like to determine what's wrong. It could be a software issue or hardware issue, such as something wrong with the wiring.
Are you asking how to accurately measure current of the chip using a multi-meter or with the 1M Ohmz method Nick showed?
fungus:
So I'm as confused as ever. Going into sleep mode definitely uses less power (I can measure the difference!) but consumption doesn't seem to be anywhere near as low as it should be.
Did you read my reply #18 ?
Yep. I've done it with/without the programmer, it made no real difference.
fungus:
So I'm as confused as ever. Going into sleep mode definitely uses less power (I can measure the difference!) but consumption doesn't seem to be anywhere near as low as it should be.
Did you read my reply #18 ?
Yep. I've done it with/without the programmer, it made no real difference.
You've misunderstood my reply, I didn't say anything about the programmer. What have you done to ensure that none of the I/O pins is a floating input?
kentc:
I don't know what your setup looks like to determine what's wrong. It could be a software issue or hardware issue, such as something wrong with the wiring.
There are no wires, just a chip.
kentc:
Are you asking how to accurately measure current of the chip using a multi-meter or with the 1M Ohmz method Nick showed?
dc42:
You've misunderstood my reply, I didn't say anything about the programmer. What have you done to ensure that none of the I/O pins is a floating input?
I set them to input with pullup resistors. I also set DIDR0 to all 1s for good measure.
Here's the complete sketch I'm using at the moment:
#include <Arduino.h>
#include <avr/power.h>
#include <avr/sleep.h>
#include <avr/wdt.h>
#include <avr/cpufunc.h>
#include <util/delay.h>
/*================================================================
Go to sleep for 4 seconds
================================================================*/
// Watchdog interrupt vector
ISR (WDT_vect)
{
WDTCR &= ~(1<<WDIE); // Disable the watchdog interrupt
}
void doSleep()
{
// Set watchdog time to 4 seconds
cli();
byte b = (1<<WDE)|(1<<WDP3)|(0<<WDP2)|(0<<WDP1)|(0<<WDP0);
WDTCR = b;
WDTCR = b|(1<<WDIE); // Enable watchdog interrupt (this wakes me up!)
wdt_reset();
// sleep
sei();
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_mode();
}
/*================================================================
Main program
================================================================*/
void setup()
{
power_all_disable();
// All pins input with pullups
DDRB = 0;
PORTB = 0x1f;
// Do these achieve anything? They don't seem to...
ADCSRA = 0;
DIDR0 = 0x3c;
}
// Alternate between sleep/work (the reading on the multimeter will switch every 4s...)
void loop()
{
// Sleep for 4s
doSleep();
// Work for 4s
_delay_ms(4000);
}
With a 10k resistor in series with the 5V supply the voltage across the resistor changes between 2.2V (sleep mode) and 3.6V (in _delay_ms()). That corresponds to currents of 220uA and 360uA - two orders of magnitude more than what I should be getting.
Aside: I don't understand that method. With a 1M resistor on a 5V supply you can never measure than 5uA no matter what the chip is doing. It's Ohms law.
Try adding a 0.1uF decoupling capacitor between the Vcc and ground pins of the chip. Without it, the chip may misbehave.
btw I just found this in the attiny datasheet:
10.2.5 Digital Input Enable and Sleep Modes
As shown in Figure 10-2, the digital input signal can be clamped to ground at the input of the
schmitt-trigger. The signal denoted SLEEP in the figure, is set by the MCU Sleep Controller in
Power-down mode to avoid high power consumption if some input signals are left floating, or
have an analog signal level close to VCC/2.
SLEEP is overridden for port pins enabled as external interrupt pins. If the external interrupt
request is not enabled, SLEEP is active also for these pins. SLEEP is also overridden by various
other alternate functions as described in “Alternate Port Functions” on page 59.
So it looks like setting the pins to inputs with pullups enabled isn't necessary on the attiny. It might even be worth trying without the internal pullups enabled.
dc42:
Try adding a 0.1uF decoupling capacitor between the Vcc and ground pins of the chip. Without it, the chip may misbehave.
I was actually doing most of the tests in the little PCB shown below which has a capacitor. The breadboard was a paranoia test.
(No, there's no difference in readings...)
dc42:
btw I just found this in the attiny datasheet:
...
So it looks like setting the pins to inputs with pullups enabled isn't necessary on the attiny. It might even be worth trying without the internal pullups enabled.
I just tried it...maybe a tiny bit lower without pullups, but background noise level.
There's a definite difference between sleep/awake (220uA vs. 360uA) so I'm fairly confident that the 'sleep' code is doing something.
This makes me think something is left switched on, something that uses 220uA. I don't know what it might be though, there's only four things you can switch off and I've done all of them (individually, all at once, it's the same).
I built an attiny-based remote control a while ago, and I seem to be using different sleep code. This is what I use:
// Wait for button to be pressed
do
{
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
cli();
if (PORTB & 0b00000100)
{
GIMSK = _BV(INT0);
sleep_enable();
sei();
sleep_cpu();
sleep_disable();
}
sei();
uint32_t now = micros();
while ((micros() - now) < 5000) {}
} while (PORTB & 0b00000100);
Ignore the PORTB stuff, it checks that a button isn't pressed. I can't remember why I used sleep_enable(), sleep_cpu() and sleep_disable() rather than sleep_mode(), but I expect there was a reason (possibly to do with using an interrupt to wake up from sleep mode, but maybe not).
What does the current drop to if you don't use the watchdog?
Are you sure the watchdog is being set correctly? Normally you need to set WDCE before changing WDE or the prescaler bits.
BTW, after the watchdog interrupt WDIF is cleared automatically (so you don't need to do it in the ISR). Meanwhile the WDT is still running, and may reset the processor before the 4s delay finishes (not that it matters much in this case).
I also noticed that you're not switching the ADC off after disabling it (power reduction register, PRR).
tim7:
Are you sure the watchdog is being set correctly? Normally you need to set WDCE before changing WDE or the prescaler bits.
Not if the WDTON bit is set in the fuses (bit 4 of fuse high byte)...
tim7:
BTW, after the watchdog interrupt WDIF is cleared automatically (so you don't need to do it in the ISR). Meanwhile the WDT is still running, and may reset the processor before the 4s delay finishes (not that it matters much in this case).
This is still a bit mysterious to me. I checked the MCUSR:WRDF flag in setup() but I never had the watchdog cause a reset, only interrupts.
I need to investigate further but I'm more worried about the power consumption at the moment.
tim7:
I also noticed that you're not switching the ADC off after disabling it (power reduction register, PRR).
Are you sure? The datasheet makes a point of saying that the ADC must be disabled (ADCSRA) before being shutdown (PRR). You commented that disabling the ADC doesn't seem to do anything, but it should make a noticeable difference.
tim7:
Are you sure? The datasheet makes a point of saying that the ADC must be disabled (ADCSRA) before being shutdown (PRR). You commented that disabling the ADC doesn't seem to do anything, but it should make a noticeable difference.
Bingo!
By putting the "power_all_disable()" at the end of setup() the voltage across my 10K resistor went from 2.2V to 68mV(!)
That means power consumption is 6.8uA ... and that's exactly where it should be for "5V power down with Watchdog".
dc42:
You've misunderstood my reply, I didn't say anything about the programmer. What have you done to ensure that none of the I/O pins is a floating input?
I set them to input with pullup resistors.
I found that enabling pullups while sleeping might use a LOT more power.
If there's a switch attached to a pin and the switch is held closed it uses over 0.1mA because of the pullup resistor. This could happen if a device with buttons on it is stuffed in a bag/pocket/whatever.
Maybe this is why they say to enable pullups on unused pins.
fungus:
If there's a switch attached to a pin and the switch is held closed it uses over 0.1mA because of the pullup resistor. This could happen if a device with buttons on it is stuffed in a bag/pocket/whatever.
Udo Klein demonstrated a way to reduce that to nearly zero. I believe he used a combination of pin-change interrupts, polling, and disabling/enabling the pull-up. He posted a fairly detailed explanation. If you have trouble finding the posts, let me know.