How do I set pin change interrupts to only interrupt on LOW? I'm not using attachInterrupt() but setting the bits via PCIFR/PCICR, since I couldn't find any examples of using pin change with attachInterrupt().
I'm using a Pro Mini 3.3V clone and have attached a power button to D5, and a reed switch to D9. I want to sleep the Arduino until either of these is pressed and when they are pressed, they will turn on a MOSFET that will turn on a Raspberry Pi. I didn't use the standard external interrupts since I want to add two additional hardware interrupts later. Using pin change instead.
At the moment it's configured to interrupt on every change, both LOW and HIGH. When I depress the button it interrupts, and when I release it, the interrupt runs again. Same with the reed switch.
How do I get it to fire on only LOW? I think it's via another bit() into PCICR but I'm lost how to do that. The datasheet and some examples seem to talk about using EICRA and ISC10 and 11 but I'm lost how to proceed.
#include <avr/interrupt.h>
#include <avr/sleep.h>
volatile byte pwrButtonPressed = 0;
volatile byte upReedState = 0;
volatile byte dnReedState = 0;
byte piPwr = 4;
byte pwrButton = 5;
byte upReed = 9;
char dnReed = A0;
void detachAll () {
detachInterrupt (digitalPinToInterrupt (pwrButton));
detachInterrupt (digitalPinToInterrupt (upReed));
detachInterrupt (digitalPinToInterrupt (dnReed));
}
// Wake on power button
ISR (PCINT2_vect) {
sleep_disable();
detachAll();
pwrButtonPressed = 1;
} // End of wake()
// Wake on up reed
ISR (PCINT0_vect) {
sleep_disable ();
detachAll();
upReedState = 1;
} // End of wake()
// Wake on down reed
ISR (PCINT1_vect) {
sleep_disable ();
detachAll();
dnReedState = 1;
} // End of wake()
void setup() {
// Up reed
PCMSK0 |= bit (PCINT1); // Pin D9
PCIFR |= bit (PCIF0); // Clear any outstanding interrupts
PCICR |= bit (PCIE0); // Enable pin change interrupts for D8 to D13
// Down reed
PCMSK1 |= bit (PCINT8); // Pin A0
PCIFR |= bit (PCIF1); // Clear any outstanding interrupts
PCICR |= bit (PCIE1); // Enable pin change interrupts for A0 to A5
// Power button
PCMSK2 |= bit (PCINT21); // Pin D5
PCIFR |= bit (PCIF2); // Clear any outstanding interrupts
PCICR |= bit (PCIE2); // Enable pin change interrupts for D0 to D7
pinMode(piPwr, OUTPUT);
pinMode(pwrButton, INPUT_PULLUP);
pinMode(upReed, INPUT_PULLUP);
pinMode(dnReed, INPUT_PULLUP);
// FIXME Uncomment digitalWrite(piPwr, HIGH); // Boot up together
Serial.begin(9600);
Serial.println("Booted up.");
} // End of setup()
void loop() {
if (pwrButtonPressed == 1) {
Serial.println("Power button pressed. Powering up the Pi.");
Serial.flush();
digitalWrite(piPwr, HIGH);
pwrButtonPressed = 0;
}
if (upReedState == 1) {
Serial.println("Door is in the up position. Powering up the Pi.");
Serial.flush();
digitalWrite(piPwr, HIGH);
upReedState = 0;
}
if (dnReedState == 1) {
Serial.println("Door is in the down position. Powering up the Pi.");
Serial.flush();
digitalWrite(piPwr, HIGH);
dnReedState = 0;
}
// FIXME Wrap around a serial read so I can send the shutdown and sleep 's' command
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable(); // Enables the sleep bit in the mcucr register
Serial.println("Zzz...");
Serial.flush();
sleep_cpu(); // Here the device is actually put to sleep
delay(1);
} // End of loop()