Desired behaviour:
- Go to IDLE sleep mode.
- When PB2 (blue trace) goes low wake up and give a 10 ms HIGH on PB1 pulling a pull-up low (yellow trace on Figure 1).
- Go to 1.
What I get:
Figure 1. (1) The input triggers, (2) the CPU wakes from sleep, (3) the CPU goes back to sleep and wakes up repeatedly until (9) the input goes high again.
I want one 10 ms low pulse and then go back to sleep until the next negative going edge on PB2 regardless of how long PB2 is held low.
Even though I set MCUCR to falling edge of INT0 the device seems to wake repeatedly when PB2 is held low. My code below attempts to solve this by switching to rising edge interrupt if the input is low and falling edge interrupt if the input is high. The result is shown in Figure 1.
void setup(){
ADCSRA &= ~_BV(ADEN); // ADC off. ADC not used.
pinMode(reedPin, INPUT);
}
void loop(){
system_sleep(); // Go straigth to sleep.
// ---- System woken up by interrupt. ---------
if (!digitalRead(reedPin)) { // Check that input is low.
pinMode(outPin, OUTPUT); // Enable output.
digitalWrite(outPin, HIGH); // Pull motor sensor input low by MOSFET.
delay(pulseTime); // Pulse time.
digitalWrite(outPin, LOW); // Pulse off.
}
}
// From http://interface.khm.de/index.php/lab/experiments/sleep_watchdog_battery/
void system_sleep() {
MCUCR |= _BV(ISC01); // Required for both rising and falling edge interrupt.
if(digitalRead(reedPin)) { // Input is high so set interrupt for detecting low.
MCUCR &= ~_BV(ISC00); // Clear MCUCR bit 0 for falling edge interrupt.
} else { // Input is low so set interrupt for detecting high.
MCUCR |= _BV(ISC00); // Set MCUCR bit 0 for rising edge interrupt.
}
GIMSK |= _BV(INT0); // Enable Pin Change Interrupts
set_sleep_mode(SLEEP_MODE_IDLE); // Leaves the clock running for elapsedMillis.
sleep_enable(); // Sets the Sleep Enable bit in the MCUCR Register (SE BIT)
sei(); // Enable interrupts
sleep_cpu(); // sleep
// ZZZZZZZZZZZzzzzzzzzzzz .......
// ------- CPU is now asleep and awaiting interrupt. ----------------------
cli(); // Disable interrupts on wake up.
sleep_disable(); // Clear SE bit.
}
ISR(INT0_vect){ // Wake up.
GIMSK = 0; // Disable external interrupts. (Only need one to wake up.)
}
Can anyone guide me through this?
Many thanks.