Hello,
I found that awesome sketch from Nick Gammon and test it on an Attiny45
The goal is to light LED1 on LOW and if pressed again then light LED2.
At the moment the Leds are changing on pin change. Can somebody help me how I can change the interrupt from "pin change" to "pin low"?
I still dont get it with those interrupts and need a little help.
As I'd like to run it at two AA batteries it should consumes as less energy as possible so that it con operate without switching it off.
Thank you!
// ATtiny45 sleep mode, wake on pin change interrupt demo
// Author: Nick Gammon
// Date: 12 October 2013
// ATMEL ATTINY 45 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 LED2 = 1; // pin 6
const byte SWITCH = 4; // pin 3 / PCINT4
boolean k=LOW;
ISR (PCINT0_vect)
{
// do something interesting here
}
void setup ()
{
pinMode (LED, OUTPUT);
pinMode (LED2, 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 ()
{
if (k==LOW) {
digitalWrite (LED, HIGH);
delay (50);
digitalWrite (LED, LOW);
k=HIGH;
}
else {
digitalWrite (LED2, HIGH);
delay (50);
digitalWrite (LED2, LOW);
k=LOW;
}
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
Since you will have to deal with switch bounce sooner or later why not stick with edge triggered interupts , add a delay for switch bounce then read the state of the switch line in your loop(). You may wish to disable interupts in the ISR where it says "do something interesting here" and re-enable them prior to gotoSleep().
Hi, thanks for your reply.
my thoughts are that if it's interrupted on pin change then I will have 4 interrupts instead of two
1.press -low 1.wake up
-high 2.wake up
2.press -low 3.wake up
-high 4.wake up
and I would like to learn how to change the sketch to low triggerd
1.press -low 1.wake up
-high still sleeping
2.press -low 2.wake up
-high still sleeping
The key (with or without) interrupts is to look for the change. So if the pin was high and is know low ....
Mark
I suspect you mean "trigger on falling edge" rather than "trigger on low". The latter will generate a continuous streams of interupts as long as you hold the button down.
The standard arduino chip has the option of triggering on falling or rising edge- not sure about the ATTiny. There is not so much documentation about the ATtiny- perhaps this will help?
You are aware that a mechanical switch contact will generate multiple on/off events (too fast for the human eye but slow enough to trigger multiple interupts) every time you press down the button? And another lot when you release it?
Not sure if the standard arduino attachInterupt() function is available for ATtiny but if it is then its much easier to use that than directly manipulating the registers like Nick Gammon does.
Hello,
oh yes you're right, I meant "trigger on falling edge"
I think that would be the best option otherwise I can manage it with a variable but it would be nicer to do it that way.
Yes I am aware of debouncing a mechanical switch. this time the signal is from a wireless receiver and there will be no bouncing.
I already got it working on an arduino nano without interrupts but would like to change it to a more battery-friendly version with sleep and wake up
Unless you especially need speed, the usual way to do something when a switch is pressed is to look at it in the loop().
It might be best to do just the sleepy-wakey stuff in interrupts, and to leave the complex decide-what-to-do stuff to the loop(). By the looks of it, your interrupt handler doesn't have to do anything at all - it just needs to be there. Perhaps it might be reasonable for it to set a volatile boolean named "I just got woken up" for the loop() to look at.