Hello all,
I am having trouble finding the appropriate library or libraries to use for my project. I am trying to use a DS3231 module, Overview | Adafruit DS3231 Precision RTC Breakout | Adafruit Learning System , with the nano 33 (I know it has a built in RTC). I then want the DS3231 to wake up the nano from sleep using an interrupt. Eventually, I will add in the ArduinoOTA code, so that I can update the program running on the arduino, to change the times via WiFi.
This is all to control a set of Exterior LED lights via 5V relays. I am trying to keep power usage to an absolute minimum as last time I did this, with the DS3231, Rocketstream's Low Power library and an UNO. It killed a 12V lawn tractor battery in 2 months. It has a 10W solar panel connected to the battery.
I do plan on using a cheap 12V to 5V USB DC plug so that the arduino nano is still powered via USB. I need the 5V for the relays. The relays are active LOW.
// Hardware:
// Arduino nano 33 iot, DS3231 myRTC.
// Connect myRTC SDA to Arduino pin SDA.
// Connect myRTC SCL to Arduino pin SCL.
// Connect myRTC INT/SQW to Arduino pin 2.
//
// Based on the example Alarm_ex8 by Jack Christensen 17Dec2018
#include <TimeLib.h>
#include <TimeAlarms.h>
#include <DS3232RTC.h> // https://github.com/JChristensen/DS3232myRTC
#include <Streaming.h> // http://arduiniana.org/libraries/streaming/
#include "ArduinoLowPower.h"
//#include <Time.h>
#include <SPI.h>
#include <WiFiNINA.h>
#include <ArduinoOTA.h>
#include "arduino_secrets.h"
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
/////// Wifi Settings ///////
char ssid[] = SECRET_SSID; // your network SSID (name)
char pass[] = SECRET_PASS; // your network password
int status = WL_IDLE_STATUS;
// pin definitions
const uint8_t myRTC_INT_PIN(2);
const int LEDPin = LED_BUILTIN;
const int relayPin = 7; // use this pin to drive the transistor
const int hourInt = 10;
const int minInt = 56;
boolean awake;
unsigned long previousMillis = 0; // will store last time LED was updated
const long timeON = 6000;
// current time from the RTC in text format
char timestamp[32];
DS3232RTC myRTC(false);
void printWifiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your WiFi shield's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
void wakeUp()
{
// Just a handler for the pin interrupt.
awake = true;
}
void setAlarm () {
tmElements_t tm2;
tm2.Hour = hourInt;
tm2.Minute = minInt;
tm2.Second = 0;
// formatTime(timestamp, tm2);
time_t alarmTime = makeTime(tm2);
formatTime(timestamp, alarmTime);
timestamp[8] = 0; // keep just hh:mm:ss
myRTC.setAlarm(ALM1_MATCH_HOURS, minute(alarmTime), hour(alarmTime), 1);
myRTC.alarm(ALARM_1); // ensure myRTC interrupt flag is cleared
myRTC.alarmInterrupt(ALARM_1, true);
}
// format a time_t value, return the formatted string in buf (must be at least 25 bytes)
void formatTime(char *buf, time_t t)
{
char m[4]; // temporary storage for month string (DateStrings.cpp uses shared buffer)
strcpy(m, monthShortStr(month(t)));
sprintf(buf, "%.2d:%.2d:%.2d %s %.2d %s %d",
hour(t), minute(t), second(t), dayShortStr(weekday(t)), day(t), m, year(t));
}
void printDigits(int digits)
{
// utility function for digital clock display: prints preceding colon and leading 0
Serial.print(':');
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}
void setup()
{
Serial.begin(115200);
delay(1000);
// Serial << F( "\n" __FILE__ " " __DATE__ " " __TIME__ "\n" );
pinMode(myRTC_INT_PIN, INPUT_PULLUP);
pinMode(relayPin, OUTPUT);
pinMode(LEDPin, OUTPUT);
setSyncProvider(myRTC.get); // the function to get the time from the RTC
LowPower.attachInterruptWakeup(myRTC_INT_PIN, wakeUp, CHANGE);
awake = true;
//
// attempt to connect to Wifi network:
// while ( status != WL_CONNECTED) {
// Serial.print("Attempting to connect to SSID: ");
// Serial.println(ssid);
// // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
// status = WiFi.begin(ssid, pass);
// }
//
// // start the WiFi OTA library with internal (flash) based storage
// ArduinoOTA.begin(WiFi.localIP(), "Arduino", "Eastwind3", InternalStorage);
//
// // you're connected now, so print out the status:
// printWifiStatus();
}
void loop()
{
// print the current time
// time_t t = myRTC.get();
// formatTime(timestamp, t);
// Serial << millis() << F(" Current RTC time ") << timestamp << endl;
//
// ArduinoOTA.poll();
if (awake) {
// Serial.println("I'm awake");
digitalWrite(relayPin, LOW);
delay(timeON); //3 hours in ms, 10800000
// unsigned long currentMillis = millis();
// if (currentMillis - previousMillis >= interval) {
// save the last time you blinked the LED
// previousMillis = currentMillis;
digitalWrite(relayPin, HIGH);
myRTC.alarm(ALARM_1);
awake = false;
setAlarm();
}
// check to see if the INT/SQW pin is low, i.e. an alarm has occurred
// Allow wake up pin to trigger interrupt on low.
digitalWrite(LEDPin, LOW);
// Enter power down state with ADC and BOD module disabled.
// Wake up when wake up pin is low.
// LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
LowPower.sleep();
}
As it stands, I can get a good Low power library to work: GitHub - arduino-libraries/ArduinoLowPower: Powersave features for SAMD boards
The trouble starts to arise when I try to wake it up using the SQW pin on the DS3231, I can't seem to find a library that support the SAMD architecture.
Any help would be appreciated.