1

I am a PHP web programmer, but I am a beginner studying Arduino. I would like to inquire about a problem with the following function that I am creating while looking for various references. (This article was written through Google Translator.)

I would appreciate it if you could see what the problem is and give me some advice.

I also posted this question on the arduino forum.

Program function: To save battery, in sleep mode, when the button is low, it wakes up with a button interrupt and pressing and holding the button sets the alarm. After setting the alarm, it goes back into sleep mode and when the time comes, the LED blinks through an interrupt via RTC. When the button is set low, the alarm is disabled and you must press and hold it to reset the alarm.

Problem: The first run goes well, but if you turn off the alarm and set the alarm again, the next alarm does not run. (When the alarm time comes, you have to turn it off and then set the alarm again after a certain time.)

Hardware used: Arduino Nano (CH340), DS3231 RTC, Ywrobot LED button switch module

Program source:

#include "RTClib.h" // DS3231 library
#include <avr/sleep.h>
const int alarmPin = 2; // The number of the pin for monitoring alarm status on DS3231
const int btnPin = 3; // button interrupt
const int ledPin = 4;
int countBlink;
unsigned long buttonPressTime;
bool buttonState;
bool ledState;
long current_millis;
unsigned long previousMillis = 0;
bool alarmActive = false;
const int check_interval = 1000;
RTC_DS3231 rtc;
DateTime alarmTime;
void setup() {
 Serial.begin(9600); // Start serial port for monitoring
 pinMode(alarmPin, INPUT_PULLUP); // Set alarm pin as pullup
 pinMode(btnPin, INPUT_PULLUP); 
 pinMode(ledPin, OUTPUT);
 if (!rtc.begin()) {
 Serial.println("Couldn't find RTC");
 Serial.flush();
 abort();
 }
 if (rtc.lostPower()) {
 // this will adjust to the date and time at compilation
 rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
 }
 rtc.disableAlarm(1);
 rtc.clearAlarm(1);
 rtc.writeSqwPinMode(DS3231_OFF); // Place SQW pin into alarm interrupt mode
 DateTime now = rtc.now();
 char buff1[] = "Now: YYYY MM DD hh:mm:ss";
 Serial.println(now.toString(buff1));
 delay(1000);
}
void loop() {
 current_millis = millis();
 buttonState = digitalRead(btnPin);
 if (buttonState == LOW) {
 alarmActive = false;
 buttonPressTime = millis();
 while (digitalRead(btnPin) == LOW)
 ;
 if (millis() - buttonPressTime > 1500) {
 Serial.println("Long press detected"); 
 settingAlarm();
 }
 }
 if (alarmActive) {
 blink_led();
 }
 if (!alarmActive) {
 digitalWrite(ledPin, LOW);
 Serial.println("...Zzz....");
 Serial.println("===================="); 
 enterSleep();
 }
 //delay(check_interval);
}
void blink_led() {
 unsigned long currentMillis = millis();
 if (currentMillis - previousMillis >= 1000) {
 previousMillis = currentMillis;
 if (ledState == LOW) {
 ledState = HIGH;
 } else {
 ledState = LOW;
 }
 digitalWrite(ledPin, ledState);
 }
}
void sleeping_led() {
 for (countBlink = 0; countBlink < 5; countBlink++) {
 digitalWrite(ledPin, HIGH);
 delay(200);
 digitalWrite(ledPin, LOW);
 delay(200);
 }
}
void settingAlarm() {
 DateTime now = rtc.now(); // Get current time
 alarmTime = now + TimeSpan(0, 0, 0, 20);
 rtc.setAlarm1(alarmTime, DS3231_A1_Second); // In 20 seconds
 char buff4[] = " YYYY MM DD hh:mm:ss";
 Serial.println(alarmTime.toString(buff4));
 Serial.println("===================");
 sleeping_led();
}
void enterSleep() { 
 set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Setting the sleep mode, in this case full sleep
 noInterrupts(); // Disable interrupts
 sleep_enable(); // Enabling sleep mode
 attachInterrupt(digitalPinToInterrupt(alarmPin), wakeUp, FALLING);
 attachInterrupt(digitalPinToInterrupt(btnPin), checkUp, FALLING);
 Serial.flush(); // Ensure all characters are sent to the serial monitor
 interrupts(); // Allow interrupts again
 sleep_cpu(); // Enter sleep mode
 rtc.disableAlarm(1);
 rtc.clearAlarm(1);
}
void wakeUp() {
 sleep_disable(); // Disable sleep mode
 detachInterrupt(digitalPinToInterrupt(alarmPin)); // Detach the interrupt to stop it firing
 detachInterrupt(digitalPinToInterrupt(btnPin)); // Detach the interrupt to stop it firing
 alarmActive = true;
}
void checkUp() {
 sleep_disable(); // Disable sleep mode
 detachInterrupt(digitalPinToInterrupt(alarmPin)); // Detach the interrupt to stop it firing
 detachInterrupt(digitalPinToInterrupt(btnPin)); // Detach the interrupt to stop it firing
}
ocrdu
1,7953 gold badges12 silver badges24 bronze badges
asked Feb 1, 2024 at 9:59
2

0

Know someone who can answer? Share a link to this question via email, Twitter, or Facebook.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.