You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
431 lines
12 KiB
431 lines
12 KiB
#include <Arduino.h>
|
|
#include <avr/sleep.h>
|
|
|
|
#include <Wire.h>
|
|
#include <RtcDS3231.h>
|
|
|
|
RtcDS3231<TwoWire> Rtc(Wire);
|
|
|
|
const int ledPin = 17;
|
|
const int wakeUpPin = 7;
|
|
const int wakeUpInterrupt = digitalPinToInterrupt(wakeUpPin);
|
|
|
|
volatile uint16_t interuptCount = 0;
|
|
volatile bool interuptFlag = false;
|
|
|
|
bool Alarmed();
|
|
void printDateTime(const RtcDateTime &dt);
|
|
|
|
void ISR_ATTR InteruptServiceRoutine()
|
|
{
|
|
// sleep_disable();
|
|
// detachInterrupt(wakeUpInterrupt);
|
|
|
|
interuptCount++;
|
|
interuptFlag = true;
|
|
}
|
|
|
|
void sleepNow()
|
|
{
|
|
// set_sleep_mode(SLEEP_MODE_PWR_DOWN);
|
|
noInterrupts();
|
|
// sleep_enable();
|
|
attachInterrupt(wakeUpInterrupt, InteruptServiceRoutine, FALLING);
|
|
interrupts();
|
|
// sleep_cpu();
|
|
}
|
|
|
|
void setup()
|
|
{
|
|
pinMode(wakeUpPin, INPUT_PULLUP);
|
|
pinMode(ledPin, OUTPUT);
|
|
|
|
Serial.begin(9660);
|
|
Rtc.Begin();
|
|
|
|
RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__);
|
|
|
|
if (!Rtc.IsDateTimeValid())
|
|
{
|
|
if (Rtc.LastError() != 0)
|
|
{
|
|
// we have a communications error
|
|
// see https://www.arduino.cc/en/Reference/WireEndTransmission for
|
|
// what the number means
|
|
Serial.print("RTC communications error = ");
|
|
Serial.println(Rtc.LastError());
|
|
}
|
|
else
|
|
{
|
|
Serial.println("RTC lost confidence in the DateTime!");
|
|
Rtc.SetDateTime(compiled);
|
|
}
|
|
}
|
|
|
|
if (!Rtc.GetIsRunning())
|
|
{
|
|
Serial.println("RTC was not actively running, starting now");
|
|
Rtc.SetIsRunning(true);
|
|
}
|
|
|
|
RtcDateTime now = Rtc.GetDateTime();
|
|
if (now < compiled)
|
|
{
|
|
Serial.println("RTC is older than compile time! (Updating DateTime)");
|
|
Rtc.SetDateTime(compiled);
|
|
}
|
|
|
|
Rtc.Enable32kHzPin(false);
|
|
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeAlarmOne);
|
|
|
|
DS3231AlarmOne alarm1(0, 0, 0, 0, DS3231AlarmOneControl_OncePerSecond);
|
|
Rtc.SetAlarmOne(alarm1);
|
|
|
|
Rtc.LatchAlarmsTriggeredFlags();
|
|
|
|
attachInterrupt(wakeUpPin, InteruptServiceRoutine, FALLING);
|
|
}
|
|
|
|
// void loop()
|
|
// {
|
|
// digitalWrite(ledPin, !digitalRead(ledPin));
|
|
// Serial.println("interrupred");
|
|
|
|
// sleepNow();
|
|
// }
|
|
|
|
void loop ()
|
|
{
|
|
if (!Rtc.IsDateTimeValid())
|
|
{
|
|
if (Rtc.LastError() != 0)
|
|
{
|
|
// we have a communications error
|
|
// see https://www.arduino.cc/en/Reference/WireEndTransmission for
|
|
// what the number means
|
|
Serial.print("RTC communications error = ");
|
|
Serial.println(Rtc.LastError());
|
|
}
|
|
else
|
|
{
|
|
Serial.println("RTC lost confidence in the DateTime!");
|
|
}
|
|
}
|
|
|
|
RtcDateTime now = Rtc.GetDateTime();
|
|
|
|
printDateTime(now);
|
|
Serial.println();
|
|
|
|
// we only want to show time every 10 seconds
|
|
// but we want to show responce to the interupt firing
|
|
for (int timeCount = 0; timeCount < 20; timeCount++)
|
|
{
|
|
if (Alarmed())
|
|
{
|
|
Serial.print(">>Interupt Count: ");
|
|
Serial.print(interuptCount);
|
|
Serial.println("<<");
|
|
digitalWrite(ledPin, !digitalRead(ledPin));
|
|
}
|
|
delay(500);
|
|
}
|
|
|
|
// sleepNow();
|
|
}
|
|
|
|
bool Alarmed()
|
|
{
|
|
bool wasAlarmed = false;
|
|
if (interuptFlag) // check our flag that gets sets in the interupt
|
|
{
|
|
wasAlarmed = true;
|
|
interuptFlag = false; // reset the flag
|
|
|
|
// this gives us which alarms triggered and
|
|
// then allows for others to trigger again
|
|
DS3231AlarmFlag flag = Rtc.LatchAlarmsTriggeredFlags();
|
|
|
|
if (flag & DS3231AlarmFlag_Alarm1)
|
|
{
|
|
Serial.println("alarm one triggered");
|
|
}
|
|
if (flag & DS3231AlarmFlag_Alarm2)
|
|
{
|
|
Serial.println("alarm two triggered");
|
|
}
|
|
}
|
|
return wasAlarmed;
|
|
}
|
|
|
|
#define countof(a) (sizeof(a) / sizeof(a[0]))
|
|
|
|
void printDateTime(const RtcDateTime& dt)
|
|
{
|
|
char datestring[20];
|
|
|
|
snprintf_P(datestring,
|
|
countof(datestring),
|
|
PSTR("%02u/%02u/%04u %02u:%02u:%02u"),
|
|
dt.Month(),
|
|
dt.Day(),
|
|
dt.Year(),
|
|
dt.Hour(),
|
|
dt.Minute(),
|
|
dt.Second() );
|
|
Serial.print(datestring);
|
|
}
|
|
|
|
// // CONNECTIONS:
|
|
// // DS3231 SDA --> SDA
|
|
// // DS3231 SCL --> SCL
|
|
// // DS3231 VCC --> 3.3v or 5v
|
|
// // DS3231 GND --> GND
|
|
// // SQW ---> (Pin19) Don't forget to pullup (4.7k to 10k to VCC)
|
|
|
|
// /* for software wire use below
|
|
// #include <SoftwareWire.h> // must be included here so that Arduino library object file references work
|
|
// #include <RtcDS3231.h>
|
|
|
|
// SoftwareWire myWire(SDA, SCL);
|
|
// RtcDS3231<SoftwareWire> Rtc(myWire);
|
|
// for software wire use above */
|
|
|
|
// /* for normal hardware wire use below */
|
|
// #include <Wire.h> // must be included here so that Arduino library object file references work
|
|
// #include <RtcDS3231.h>
|
|
// RtcDS3231<TwoWire> Rtc(Wire);
|
|
// /* for normal hardware wire use above */
|
|
|
|
// bool Alarmed();
|
|
// void printDateTime(const RtcDateTime& dt);
|
|
// const byte LED = 17;
|
|
|
|
// // Interrupt Pin Lookup Table
|
|
// // (copied from Arduino Docs)
|
|
// //
|
|
// // CAUTION: The interrupts are Arduino numbers NOT Atmel numbers
|
|
// // and may not match (example, Mega2560 int.4 is actually Atmel Int2)
|
|
// // this is only an issue if you plan to use the lower level interupt features
|
|
// //
|
|
// // Board int.0 int.1 int.2 int.3 int.4 int.5
|
|
// // ---------------------------------------------------------------
|
|
// // Uno, Ethernet 2 3
|
|
// // Mega2560 2 3 21 20 [19] 18
|
|
// // Leonardo 3 2 0 1 7
|
|
|
|
// #define RtcSquareWavePin 7 // Mega2560
|
|
// #define RtcSquareWaveInterrupt 4 // Mega2560
|
|
|
|
// // marked volatile so interrupt can safely modify them and
|
|
// // other code can safely read and modify them
|
|
// volatile uint16_t interuptCount = 0;
|
|
// volatile bool interuptFlag = false;
|
|
|
|
// void ISR_ATTR InteruptServiceRoutine()
|
|
// {
|
|
// // since this interupted any other running code,
|
|
// // don't do anything that takes long and especially avoid
|
|
// // any communications calls within this routine
|
|
// interuptCount++;
|
|
// interuptFlag = true;
|
|
// }
|
|
|
|
// void setup ()
|
|
// {
|
|
// Serial.begin(9600);
|
|
|
|
// // set the interupt pin to input mode
|
|
// pinMode(RtcSquareWavePin, INPUT);
|
|
|
|
// //--------RTC SETUP ------------
|
|
// // if you are using ESP-01 then uncomment the line below to reset the pins to
|
|
// // the available pins for SDA, SCL
|
|
// // Wire.begin(0, 2); // due to limited pins, use pin 0 and 2 for SDA, SCL
|
|
|
|
// Rtc.Begin();
|
|
|
|
// RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__);
|
|
|
|
// if (!Rtc.IsDateTimeValid())
|
|
// {
|
|
// if (Rtc.LastError() != 0)
|
|
// {
|
|
// // we have a communications error
|
|
// // see https://www.arduino.cc/en/Reference/WireEndTransmission for
|
|
// // what the number means
|
|
// Serial.print("RTC communications error = ");
|
|
// Serial.println(Rtc.LastError());
|
|
// }
|
|
// else
|
|
// {
|
|
// Serial.println("RTC lost confidence in the DateTime!");
|
|
// Rtc.SetDateTime(compiled);
|
|
// }
|
|
// }
|
|
|
|
// if (!Rtc.GetIsRunning())
|
|
// {
|
|
// Serial.println("RTC was not actively running, starting now");
|
|
// Rtc.SetIsRunning(true);
|
|
// }
|
|
|
|
// RtcDateTime now = Rtc.GetDateTime();
|
|
// if (now < compiled)
|
|
// {
|
|
// Serial.println("RTC is older than compile time! (Updating DateTime)");
|
|
// Rtc.SetDateTime(compiled);
|
|
// }
|
|
|
|
// Rtc.Enable32kHzPin(false);
|
|
// Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeAlarmBoth);
|
|
|
|
// // Alarm 1 set to trigger every day when
|
|
// // the hours, minutes, and seconds match
|
|
// RtcDateTime alarmTime = now + 88; // into the future
|
|
// DS3231AlarmOne alarm1(
|
|
// alarmTime.Day(),
|
|
// alarmTime.Hour(),
|
|
// alarmTime.Minute(),
|
|
// alarmTime.Second(),
|
|
// DS3231AlarmOneControl_HoursMinutesSecondsMatch);
|
|
// Rtc.SetAlarmOne(alarm1);
|
|
|
|
// // Alarm 2 set to trigger at the top of the minute
|
|
// DS3231AlarmTwo alarm2(
|
|
// 0,
|
|
// 0,
|
|
// 0,
|
|
// DS3231AlarmTwoControl_OncePerMinute);
|
|
// Rtc.SetAlarmTwo(alarm2);
|
|
|
|
// // throw away any old alarm state before we ran
|
|
// Rtc.LatchAlarmsTriggeredFlags();
|
|
|
|
// // setup external interupt
|
|
// attachInterrupt(RtcSquareWaveInterrupt, InteruptServiceRoutine, FALLING);
|
|
// }
|
|
|
|
// void loop ()
|
|
// {
|
|
// if (!Rtc.IsDateTimeValid())
|
|
// {
|
|
// if (Rtc.LastError() != 0)
|
|
// {
|
|
// // we have a communications error
|
|
// // see https://www.arduino.cc/en/Reference/WireEndTransmission for
|
|
// // what the number means
|
|
// Serial.print("RTC communications error = ");
|
|
// Serial.println(Rtc.LastError());
|
|
// }
|
|
// else
|
|
// {
|
|
// Serial.println("RTC lost confidence in the DateTime!");
|
|
// }
|
|
// }
|
|
|
|
// RtcDateTime now = Rtc.GetDateTime();
|
|
|
|
// printDateTime(now);
|
|
// Serial.println();
|
|
|
|
// // we only want to show time every 10 seconds
|
|
// // but we want to show responce to the interupt firing
|
|
// for (int timeCount = 0; timeCount < 20; timeCount++)
|
|
// {
|
|
// if (Alarmed())
|
|
// {
|
|
// Serial.print(">>Interupt Count: ");
|
|
// Serial.print(interuptCount);
|
|
// Serial.println("<<");
|
|
// digitalWrite(LED, !digitalRead(LED));
|
|
// }
|
|
// delay(500);
|
|
// }
|
|
// }
|
|
|
|
// bool Alarmed()
|
|
// {
|
|
// bool wasAlarmed = false;
|
|
// if (interuptFlag) // check our flag that gets sets in the interupt
|
|
// {
|
|
// wasAlarmed = true;
|
|
// interuptFlag = false; // reset the flag
|
|
|
|
// // this gives us which alarms triggered and
|
|
// // then allows for others to trigger again
|
|
// DS3231AlarmFlag flag = Rtc.LatchAlarmsTriggeredFlags();
|
|
|
|
// if (flag & DS3231AlarmFlag_Alarm1)
|
|
// {
|
|
// Serial.println("alarm one triggered");
|
|
// }
|
|
// if (flag & DS3231AlarmFlag_Alarm2)
|
|
// {
|
|
// Serial.println("alarm two triggered");
|
|
// }
|
|
// }
|
|
// return wasAlarmed;
|
|
// }
|
|
|
|
// #define countof(a) (sizeof(a) / sizeof(a[0]))
|
|
|
|
// void printDateTime(const RtcDateTime& dt)
|
|
// {
|
|
// char datestring[20];
|
|
|
|
// snprintf_P(datestring,
|
|
// countof(datestring),
|
|
// PSTR("%02u/%02u/%04u %02u:%02u:%02u"),
|
|
// dt.Month(),
|
|
// dt.Day(),
|
|
// dt.Year(),
|
|
// dt.Hour(),
|
|
// dt.Minute(),
|
|
// dt.Second() );
|
|
// Serial.print(datestring);
|
|
// }
|
|
|
|
// // #include <Arduino.h>
|
|
// // // **** INCLUDES *****
|
|
// // #include "LowPower.h"
|
|
|
|
// // // Use pin 2 as wake up pin
|
|
// // const int wakeUpPin = 7;
|
|
// // const int ledPin = 17;
|
|
|
|
// // void wakeUp()
|
|
// // {
|
|
// // // Just a handler for the pin interrupt.
|
|
// // }
|
|
|
|
// // void setup()
|
|
// // {
|
|
// // // Configure wake up pin as input.
|
|
// // // This will consumes few uA of current.
|
|
// // pinMode(wakeUpPin, INPUT);
|
|
// // }
|
|
|
|
// // void loop()
|
|
// // {
|
|
// // // Allow wake up pin to trigger interrupt on low.
|
|
// // attachInterrupt(digitalPinToInterrupt(wakeUpPin), wakeUp, 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);
|
|
|
|
// // // Disable external pin interrupt on wake up pin.
|
|
// // detachInterrupt(digitalPinToInterrupt(wakeUpPin));
|
|
|
|
// // // Do something here
|
|
// // // Example: Read sensor, data logging, data transmission.
|
|
// // pinMode(ledPin, OUTPUT);
|
|
// // delay(100);
|
|
// // digitalWrite(ledPin, HIGH);
|
|
// // delay(100);
|
|
// // digitalWrite(ledPin, LOW);
|
|
// // delay(100);
|
|
// // pinMode(ledPin, INPUT);
|
|
// // }
|
|
// |