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
}
2

0

Your Answer

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

Browse other questions tagged or ask your own question.