Hi, I have a circuit that turns 12V power on and off using an ATMEGA328P and a MOSFET, at intervals controlled with a DS3231 clock that wakes the sleeping MCU with alarm interrupts. In the setup the program sets the clock, sets the alarm for 15 seconds later, runs a test on-and-off of the MOSFET that controls the 12V power. Then the clock VCC is turned off (it then runs on its battery). Then in 15 seconds, the main program loop starts, the ATMEGA wakes up, the 12V power turns on for a while, and then turns off. The clock power is turned on for communication, the alarm is set for 5 minutes later. Then the ATMEGA sleeps until the alarm.
The 5-minute interval works fine from there as long as I don't turn off the clock VCC at the end of the main program loop. But I need to turn that off to save power. If I turn it off, the MOSFET is fired either randomly but short intervals--or maybe resetting the whole program; I'm not sure. I have struggled with learning about the interrupts and will continue with that, but I thought I'd post this here in case someone would just be able to look at this and figure out why I can't turn off that clock and still have the interval work. Can anyone help? Thank you!
#include <DS3232RTC.h> // https://github.com/JChristensen/DS3232RTC
#include <LowPower.h>
#define ALARM_PIN 2
#define MOSFET_PIN 7
#define CLOCK_VCC_PIN 8
#define SDA A4
#define SCL A5
const time_t ALARM_INTERVAL(300);
void setup()
{
pinMode(MOSFET_PIN, OUTPUT);
pinMode(CLOCK_VCC_PIN, OUTPUT);
mosfetOn();
clockvccOn();
time_t t = RTC.get();
RTC.setAlarm(ALM1_MATCH_DATE, 0, 0, 0, 1);
RTC.setAlarm(ALM2_MATCH_DATE, 0, 0, 0, 1);
RTC.alarm(ALARM_1);
RTC.alarm(ALARM_2);
RTC.alarmInterrupt(ALARM_1, false);
RTC.alarmInterrupt(ALARM_2, false);
RTC.squareWave(SQWAVE_NONE);
pinMode(ALARM_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(ALARM_PIN), alarmIsr, FALLING);
time_t alarmTime = t + 15;
RTC.setAlarm(ALM1_MATCH_HOURS, second(alarmTime), minute(alarmTime), hour(alarmTime), 0);
RTC.alarm(ALARM_1);
RTC.alarmInterrupt(ALARM_1, true);
delay(3000);
mosfetOff();
clockvccOff();
}
volatile boolean alarmIsrWasCalled = false;
void alarmIsr()
{
alarmIsrWasCalled = true;
}
void loop()
{
attachInterrupt(digitalPinToInterrupt(ALARM_PIN), alarmIsr, FALLING);
pinMode(A4, INPUT);
pinMode(A5, INPUT);
LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
pinMode(A4, OUTPUT);
pinMode(A5, OUTPUT);
detachInterrupt(digitalPinToInterrupt(ALARM_PIN));
clockvccOn();
delay(50);
RTC.alarm(ALARM_1);
RTC.alarm(ALARM_2);
alarmIsrWasCalled = false;
time_t t = RTC.get();
time_t alarmTime = t + ALARM_INTERVAL;
RTC.setAlarm(ALM1_MATCH_HOURS, second(alarmTime), minute(alarmTime), hour(alarmTime), 0);
RTC.alarm(ALARM_1);
RTC.alarmInterrupt(ALARM_1, true);
delay(100);
LipoControl();
// clockvccOff();
}
void LipoControl() {
mosfetOn();
delay(10000);
mosfetOff();
}
void mosfetOn() {
digitalWrite(MOSFET_PIN, HIGH);
}
void mosfetOff() {
digitalWrite(MOSFET_PIN, LOW);
}
void clockvccOn() {
digitalWrite(CLOCK_VCC_PIN, HIGH);
}
void clockvccOff() {
digitalWrite(CLOCK_VCC_PIN, LOW);
}
// function to return the compile date and time as a time_t value
time_t compileTime()
{
const time_t FUDGE(10); //fudge factor to allow for upload time, etc. (seconds, YMMV)
const char *compDate = __DATE__, *compTime = __TIME__, *months = "JanFebMarAprMayJunJulAugSepOctNovDec";
char compMon[4], *m;
strncpy(compMon, compDate, 3);
compMon[3] = '\0';
m = strstr(months, compMon);
tmElements_t tm;
tm.Month = ((m - months) / 3 + 1);
tm.Day = atoi(compDate + 4);
tm.Year = atoi(compDate + 7) - 1970;
tm.Hour = atoi(compTime);
tm.Minute = atoi(compTime + 3);
tm.Second = atoi(compTime + 6);
time_t t = makeTime(tm);
return t + FUDGE; //add fudge factor to allow for compile time
}type or paste code here