Power problem with Gammon's classic code

Hi Folks,

Maybe a stupid question but... I apply the great Nick Gammons code for AtTiny45.
Power consumption is round 400-500 nA if INT is NOT grounded. But, if grounded,
sleep power is round 100uA! I have a quicksilver switch, and it is ON or OFF: when
status is changed action should do. The problem is: if switch remains in ON position,
the power consumpition is round 100uA.

Please help!

// ATtiny85 sleep mode, wake on pin change interrupt demo
// Author: Nick Gammon
// Date: 12 October 2013

// ATMEL ATTINY 25/45/85 / ARDUINO
//
// +-/-+
// Ain0 (D 5) PB5 1| |8 Vcc
// Ain3 (D 3) PB3 2| |7 PB2 (D 2) Ain1
// Ain2 (D 4) PB4 3| |6 PB1 (D 1) pwm1
// GND 4| |5 PB0 (D 0) pwm0
// +----+

#include <avr/sleep.h> // Sleep Modes
#include <avr/power.h> // Power management

const byte LED = 3; // pin 2
const byte SWITCH = 4; // pin 3 / PCINT4

ISR (PCINT0_vect)
{
// do something interesting here
}

void setup ()
{
pinMode (LED, OUTPUT);
pinMode (SWITCH, INPUT);
digitalWrite (SWITCH, HIGH); // internal pull-up

// pin change interrupt (example for D4)
PCMSK |= bit (PCINT4); // want pin D4 / pin 3
GIFR |= bit (PCIF); // clear any outstanding interrupts
GIMSK |= bit (PCIE); // enable pin change interrupts

} // end of setup

void loop ()
{
digitalWrite (LED, HIGH);
delay (500);
digitalWrite (LED, LOW);
delay (500);
goToSleep ();
} // end of loop

void goToSleep ()
{
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
ADCSRA = 0; // turn off ADC
power_all_disable (); // power off ADC, Timer 0 and 1, serial interface
sleep_enable();
sleep_cpu();
sleep_disable();
power_all_enable(); // power everything back on
} // end of goToSleep

Sounds about right. a pullup resistor on a contact connected to ground consumes power.
The INPUT_PULLUP resistor is supposed to be about 40k. 5V/40K is about 100uA.
You can:

  • use a SPDT switch
  • use a higher-value external pullup or pulldown register.
  • Turn off the pullup EXCEPT when you actually need to detect interrupts.

Thanks westfw,

My idea is to trigger 1-2 minutes blinking period when quicksilver switch is going ON --> OFF or OFF-->ON.

The swicth is locating in dog's collar (to be seen in darkness when led is blinking). The dog is constantly moving around, and my device works perfectly when I walk with the dog.

Problem is only when I take off the dogs collar and quicksilver switch happens to be in ON mode --> 100uA for nothing!

Further ideas? I will try the solution you mentioned later this evening. -kari

To be continued...

Where (AtTiny45) should I place the higher value
external pull-up resistor? Gammon's code above.

  1. use a higher-value external pullup or pulldown register.

Where (AtTiny45) should I place the higher value external pull-up resistor?

Between the pin and Vcc.

jremingon: thank you!

SOLVED, with 10M resistor between Vcc (+) and triggeg (physical pin #2)
in code above, the stand-by current is between 0.1 uA (open) and 0.5 uA (closed). This is
enough for me.

I'm not sure, can work both ways, but I changed line

digitalWrite (SWITCH, HIGH); // internal pull-up

to digitalWrite(SWITCH, LOW);

and it works. Could also work with original code, I'm not sure.

BR, -kari