I have a simple code I’m running on a Boron 404X (OS 4.0.0) to try and hunt down an error in my data logger code. I was bringing the full data logger code over from an Arduino so I could leverage the Boron’s cellular capabilities.
The code I am running sets up the DS3231 to trigger Alarm 1 at 1Hz. All the ISR does is set a trigger flag. In the loop, if the trigger flag is set, the program resets the trigger flag, turns off the alarm, prints the current time out via Log.info and Flips the LED state (so the LED blinks at the alarm rate). If have put the code below (I hope it is formatted correctly)
(I don’t actually need the alarm at 1Hz, but it speeds up catching the error)
#include <Particle.h>
#include "DS3231.h"
#include <Wire.h>
SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(SEMI_AUTOMATIC);
// Define Hardware Pins
#define ClockINT D4
#define LEDPin D7
// Set Up the Objects
SerialLogHandler logHandler(9600); // Serial log output
DS3231 cdRTC; // Clock Object for the chrono dot RTC
uint32_t sampleCounter = 0; // Used to track how many samples have been counted
bool blink = 0;
// DateTime variables
DateTime currentTime;
// Alarm 1 Variables: Used for triggering the start of a sample.
byte alarmBits1Hz = 0b00001111; // Alarm will trigger every second.
bool alarmDayIsDay = false; // alarmDay is the day of the month NOT day of the week
bool alarmH12 = false; // Clock hours in 00-23. (true) if hour is 1 - 12, (false) if hour is 00 - 23
bool alarmPM = false; // Not used in 24 hour mode. (true) if 12-hour time is PM, (false) if AM
// State Variables
volatile byte tick = 0; // Interrupt signaling byte. When an alarm is triggered, tick is switched to 1.
void setup() {
// Wait for a USB serial connection for up to 30 seconds
waitFor(Serial.isConnected, 30000);
// Start the i2c
Wire.begin(); // Begin I2C communication
// Set up RTC and turn off Alarm 2
cdRTC.setClockMode(false); // Set the clock mode to 24-hoour.
// Set minutes to 255 so there can never be a match.
cdRTC.setA2Time( 255, 255, 255, alarmBitsBurstStart, alarmDayIsDay, alarmH12, alarmPM);
cdRTC.turnOffAlarm(2); // disable Alarm 2 interrupt
cdRTC.checkIfAlarm(2); // clear Alarm 2 flag
// Connect to the particle cloud
Particle.connect();
// Set the alarm to trigger at 1Hz
cdRTC.setA1Time(0, 0, 0, 0, alarmBits1Hz, alarmDayIsDay, alarmH12, alarmPM);
// The alarm time is set to all zeros because the alarmBits should trigger the alarm
// at 1Hz and esentially ignore the alarm time.
cdRTC.checkIfAlarm(1); // Clear the Alarm 1 flag: This brings the interrupt pin back high
cdRTC.turnOnAlarm(1); // Enable Alarm 1 interrupt
// Setup the interputs
// RTC interrupt
pinMode(ClockINT, INPUT_PULLUP); // Interrupt pin brought high so it can be brought low by the RTC alarm.
attachInterrupt(digitalPinToInterrupt(ClockINT), isr_TickTock, FALLING);
// Set up the LED and turn it off
pinMode(LEDPin, OUTPUT);
digitalWrite(LEDPin, 0);
}
void loop() {
if (tick){
// Set tick back to zero
tick = 0;
// Clear the alarm
cdRTC.checkIfAlarm(1);
// Get the time
currentTime = RTClib::now();
// Increment the sample counter
sampleCounter++;
// Print the time
Log.info("%06d %04d/%02d/%02d %02d:%02d:%02d", sampleCounter, currentTime.year(), currentTime.month(), currentTime.day(), currentTime.hour(), currentTime.minute(), currentTime.second());
// blink the led
blink = !blink; // Cycle the LED state
digitalWrite(LEDPin, blink);
}
}
void isr_TickTock() {
tick = 1;
return;
}
After something like 12 hours the boron will stop. It’s like it either doesn’t catch the trigger or fails to flip the alarm flag to turn the alarm off. When it has stopped I can usually just trigger the alarm pin manually get everything going again.
I have tried a couple different DS3231 breakout boards and a couple different libraries for the DS3231.
I don’t have a ton of experience in embedded systems and I’m at a loss for how to debug this.