Hi everyone,
Been struggling with a strange behaviour while trying to wake Arduino Pro Mini from sleeping using external interrupt at pin 2 from ADXL345. My setup is as following:
Arduino Pro Mini 3.3v
ADXL345 (SPI, Sparkfun)
Libraries: ADXL345, u8g2lib, LowPower, SimpleTimer
Objective: The project is battery powered, therefore it is required to sleep most of the time unless movement is detected. In that case, Arduino wakes up, does the required processing, and after a delay, go back to sleep.
Issue: The code works perfectly until, I enable the power saving feature in u8g2lib. This is a fantastic library I've been using for years now, so it's likely I may have made some mistake in the code. When arduino is power cycled, the code runs fine, and goes into sleep mode. But then, it doesn't seem to wake up. This behaviour does not occur if I do not use the power saving feature in u8g2lib.
I've wrecked my brain over it, at last decided to take the help of the experts here.
Here's the code. Please notice that the "u8g2.setPowerSave(1);" has been commented out.
#include <U8g2lib.h>
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
#include <SparkFun_ADXL345.h> // SparkFun ADXL345 Library
#include <LowPower.h>
#include <SimpleTimer.h>
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
ADXL345 adxl = ADXL345(10); // USE FOR SPI COMMUNICATION, ADXL345(CS_PIN);
SimpleTimer firstTimer(5000);
int wakeUpPin = 2; // Arduino external interrupt Pin
void setup() {
Serial.begin(9600);
adxlInitialSetup();
Serial.flush();
pinMode(wakeUpPin, INPUT);
u8g2.begin();
}
void loop() {
timerReset();
interruptListener();
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_nokiafc22_tu);
u8g2.setCursor(0, 7);
u8g2.print("TEST");
} while ( u8g2.nextPage() );
}
void interruptListener() { /* Look for Interrupts and Triggered Action */
byte interrupts = adxl.getInterruptSource();
if (firstTimer.isReady()) { // Check is ready a first timer
//u8g2.setPowerSave(1); // Causing issues with wakeUp process.
Serial.println("Sleeping now");
Serial.flush();
delay(100);
attachInterrupt(0, wakeUp, RISING);
LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
} else {
//u8g2.setPowerSave(0);
Serial.println("Active");
}
}
void timerReset() {
if (digitalRead(wakeUpPin) == 1) {
firstTimer.reset();
}
}
void wakeUp() { // Just a handler for the pin interrupt.
}
void adxlInitialSetup()
{
adxl.powerOn(); // Power on the ADXL345
adxl.setRangeSetting(16); // Give the range settings
adxl.setSpiBit(0); // Configure the device to be in 4 wire SPI mode when set to '0' or 3 wire SPI mode when set to 1
adxl.setActivityXYZ(1, 1, 1); // Set to activate movement detection in the axes "adxl.setActivityXYZ(X, Y, Z);" (1 == ON, 0 == OFF)
adxl.setActivityThreshold(20); // 62.5mg per increment // Set activity // Inactivity thresholds (0-255)
adxl.setInactivityXYZ(1, 1, 1); // Set to detect inactivity in all the axes "adxl.setInactivityXYZ(X, Y, Z);" (1 == ON, 0 == OFF)
adxl.setInactivityThreshold(75); // 62.5mg per increment // Set inactivity // Inactivity thresholds (0-255)
adxl.setTimeInactivity(5); // How many seconds of no activity is inactive?
adxl.setTapDetectionOnXYZ(0, 0, 1); // Detect taps in the directions turned ON "adxl.setTapDetectionOnX(X, Y, Z);" (1 == ON, 0 == OFF)
adxl.setTapThreshold(50); // 62.5 mg per increment
adxl.setTapDuration(15); // 625 μs per increment
adxl.setDoubleTapLatency(80); // 1.25 ms per increment
adxl.setDoubleTapWindow(200); // 1.25 ms per increment
adxl.setImportantInterruptMapping(1, 1, 1, 1, 1); // Sets "adxl.setEveryInterruptMapping(single tap, double tap, free fall, activity, inactivity);"
adxl.InactivityINT(0); adxl.ActivityINT(1); adxl.doubleTapINT(0); adxl.singleTapINT(0);
}