The ADXL345, for example, requires that interrupts are responded to by querying the INT_SOURCE
(interrupt source) register. In example code for the SparkFun ADXL345 Arduino Library, there is code that looks like:
void ADXL_ISR() {
// getInterruptSource clears all triggered actions after returning value
// Do not call again until you need to recheck for triggered actions
byte interrupts = adxl.getInterruptSource();
// Free Fall Detection
if(adxl.triggered(interrupts, ADXL345_FREE_FALL)){
However, under the covers adxl.getInterruptSource()
is sending an I2C message and receiving a response. This seems to be a bad idea in an interrupt service routine (ISR).
A possible option seems to be to turn on interrupts prior to calling adxl.getInterruptSource()
, however there is much advice about not doing this (such as, Nick Gammon's informative post). I've managed to get it to work with something of the form:
void setup() {
attachInterrupt(digitalPinToInterrupt(INT_PIN), isr, LOW);
...
}
void isr() {
detachInterrupt(digitalPinToInterrupt(INT_PIN));
interrupts();
byte interrupts = adxl.getInterruptSource();
...
attachInterrupt(digitalPinToInterrupt(INT_PIN), isr, LOW);
}
This seems to work but I'm worried I'm missing something. Any suggestions?
EDIT: Thanks for the answers that suggest polling, however I am using a MKR1400 and wish to minimise power consumption by putting the processor into a sleep state - only waking up to process the relatively rare "activity" or "free fall" events. As pointed out by @Majenko, a combination of sleeping and polling might be used. So this really just leaves the question of why is the above a bad idea.
detachInterrupt
.