RTC Alarm sketch problem

I have made an alarm using DS3231 RTC and TM1637 Display
I'm using the RTClib library

Everything appears to work fine.
The clock keeps time, I can set an alarm, the led lights when the alarm is set, I can cancel the alarm or it will time out and cancel itself and when it is canceled the led goes out.
Exactly what I want
However, evrey day at midnight an alarm goes off without me setting anything and without the led on. This happens even if another alarm is set and the led is on :frowning:
I have tried everything I can think of.
I have changed out hardware. I have even tried removing the batery from the RTC incase there is something in memory that hasn't cleared
I have examined the code to see if I have accidentally set a second alarm which doesn't appear to be the case but, no matter what I try it still behaves same.

Could some kind person please take a look at it for me, help put an end to my sleepless nights, and tell me what I have missed or done wrong.
(if you look at the code you will see when I initiated this clock ------ I have been trying to sort this problem out since it woke me up on the first night lol)

#include <Wire.h>
#include "RTClib.h"
#include <TM1637Display.h>

RTC_DS3231 rtc;

#define CLK 8
#define DIO 9
#define ldr A1  //input for light sensor not setup yet but will use this to dim the display
#define led 6   //Alarm set warning light

TM1637Display display(CLK, DIO);

const uint8_t blank[] = {0x00, 0x00, 0x00,0x00};

int setButton = 2; // pushbutton for setting alarm
int hourButton = 3; // pushbutton for hour
int minButton = 4; // pushbutton for minutes
int exitButton = 5; // pushbutton for exit of set alarm
int buzzer = 13;

int t, a, Hour, Min, h, m;
int set_time, alarm_time, auto_alarmStop, set_alarm_min, set_alarm_hour;

int setButtonState = 0; // pushbutton state for setting alarm
int hourButtonState = 0; // pushbutton state for hour
int minButtonState = 0;// pushbutton state for minutes
int exitButtonState = 0; // pushbutton state for exit of set alarm

int activate;

void setup() {
  
  Serial.begin(9600);  // Begin serial communication at a baud rate of 9600: 
  delay(3000);  // Wait for console opening:
  if (! rtc.begin()) {  // Check if RTC is connected correctly:
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (rtc.lostPower()) { // Check if the RTC lost power and if so, set the time:
    Serial.println("RTC lost power, lets set the time!");
    // The following line sets the RTC to the date & time this sketch was compiled:
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // July 02, 2020 at 3:47am you would call:
    //rtc.adjust(DateTime(2020, 7, 02, 03, 47, 0));
  }
  
  Wire.begin();
  display.setBrightness(7);           
  pinMode(setButton, INPUT_PULLUP);      
  pinMode(hourButton, INPUT_PULLUP);     
  pinMode(minButton, INPUT_PULLUP);      
  pinMode(exitButton, INPUT_PULLUP);     
  pinMode(buzzer, OUTPUT);
  pinMode (led, OUTPUT);
 // pinMode(ldr, INPUT); //used to read light sensor
  
  activate = 0;

 rtc.begin();
//rtc.adjust(DateTime(2021,5,14,10,27.00)); 


}

void loop() {
    
    DateTime now = rtc.now();
    Hour = now.hour();
    Min = now.minute();
    t =(now.hour()* 100 )+ now.minute();
    a=now.second()%2;
    
 
  display.showNumberDecEx(t,(0x80>>1), true);
  delay(500);
  display.showNumberDecEx(t,(0x80>>2), true);
  delay(500); 

    switch(activate){
    case 0:
    display.showNumberDec(t, true);
    setButtonState = digitalRead(setButton);
    if(setButtonState == LOW){ delay(50); activate = 1;}
    if(t == alarm_time && now.second()==0){activate = 2;}
    break;
    case 1:
       display.setSegments(blank);//clear display
       display.showNumberDec(0, true);

       while(activate == 1){
       hourButtonState = digitalRead(hourButton);
       if(hourButtonState == LOW){
           h++;
           edit();
           set_alarm_hour = h;
           delay(200);
       }
       
       minButtonState = digitalRead(minButton);
       if(minButtonState == LOW){
          m++;
          edit();
          set_alarm_min = m;
          delay(200);
       }
       
       
       exitButtonState = digitalRead(exitButton);
       if(exitButtonState == LOW){delay(50); activate = 0;}
     }
     alarm_time = (set_alarm_hour*100)+set_alarm_min;
        digitalWrite(led,HIGH);
    break;
    case 2:
      alarm();
         
      display.showNumberDec(t, true);
      
      auto_alarmStop = alarm_time+1;    //Auto stp after (# min)
      exitButtonState = digitalRead(exitButton);
      if(exitButtonState == LOW){delay(50); activate = 0; digitalWrite(led,LOW);}
      if(t == auto_alarmStop){activate = 0;
      digitalWrite(led,LOW);}
      display.showNumberDec(t, true);
    break;
      
    }
    delay(5);
} 
 

void edit(){
  if(m==60){m=0; h++;}
  if(m<0){m=59; h--;}
  if(h==24){h=0;}
  if(h<0){h=23; m=59;}
  set_time = (h*100)+ m;
  display.showNumberDec(set_time, true);

}

void alarm(){

      digitalWrite(buzzer,HIGH);
      delay(75);
      digitalWrite(buzzer,LOW);
      delay(75);
      digitalWrite(buzzer,HIGH);
      delay(75);
      digitalWrite(buzzer,LOW);
      delay(75);
      digitalWrite(buzzer,HIGH);
      delay(75);
      digitalWrite(buzzer,LOW);
      delay(300);
          
      digitalWrite(buzzer,HIGH);
      delay(200);
      digitalWrite(buzzer,LOW);
      delay(100);
      digitalWrite(buzzer,HIGH);
      delay(200);
      digitalWrite(buzzer,LOW);
      delay(100);
      digitalWrite(buzzer,HIGH);
      delay(200);
      digitalWrite(buzzer,LOW);
      delay(300);
      
      digitalWrite(buzzer,HIGH);
      delay(75);
      digitalWrite(buzzer,LOW);
      delay(75);
      digitalWrite(buzzer,HIGH);
      delay(75);
      digitalWrite(buzzer,LOW);
      delay(75);
      digitalWrite(buzzer,HIGH);
      delay(75);
      digitalWrite(buzzer,LOW);
      delay(300);
          
      
}

TIA

1 Like

I see a Serial.begin, but not many prints

I can get the time/date to display but Cant work out how to print the alarm status etc,

Have a look at some other time management libraries like TimeLib.h and TimeAlarms.h

thank you and I will but I really want to understand where I have made a mistake and I don't see how looking at other lib's will help me

Sometimes it helps to get something working then other things fall into place.
You are using the DS3231.
There is a library for that but DS1307RTC works just as well.
As @anon73444976 pointed out, you aren't making use of Serial.print to help with diagnostics.
Somewhere in the code, the conditions to call the alarm are being met, even if you did not intend it.
If you included a Serial.print where the alarm is activated to see some of the values of time, you might get some clues.
You have a lot of delay()'s in your alarm() function which will slow the sketch.
You could spend a lot of time trying to track the problem down and libraries are there to help you.
I use several DS3231 RTCs with TimeLib and TimeAlarms libraries and all work well.
I'm sure whatever approach you take, it will resolve itself.

   alarm_time = (set_alarm_hour*100)+set_alarm_min;

must be set to zero, if you mean the false alarm is at midnight exactly. So print at this point any value assigned to see when it becomes 0.

Also. How do you cancel or turn off the alarm? Does the alarm sound very day at the right time as you set without needing to be reset? Can you turn off the alarm so it does not sound next time?

If your code works as you say, I think you should figure out this baffling mystery, without adding any complications in the name of simplifying. I would be very curious, as at a glance I do not see why an alarm goes off.

a7

Correct!

There are lots of different libs for the RTC DS3231. I am using the RTClib as you can see from the code and as already stated
Changing the lib for a different version may make the problem disappear but it will not help me to solve it.
I want to understand the problem so I may do better in future. Not push the problem away and ignore my short comings.

Agreed. but I have already stated above that I am struggling with that. I can SP all the time interrupts but cannot work out how to SP the alarm state so how about helping with that problem instead of stating the obvious but not providing a solution or any advice?

This is running an alarm clock not a NASA Space Station.
I cannot see the reason why delays on a script that sounds an alarm sequence would cause a second, unprogrammed, alarm to sound
I do not believe that this is were the problem lies
But I could be wrong so convince me

Good. I'm really pleased for you. And I am sure that I will use other libs on other projects. Plus I am sure I will have many successes and equally as many failures on this journey.
furthermore, I have already spent a great deal of time trying to solve this problem on my own. Now I have asked for help. Not a solution that tells me to "run away and live to fight another day"
However, I want to solve and understand this problem. Not move it and run away!
Is it the lib I am using that has a fault within or is it the way I have put this sketch together?
If it is down to me then I need to learn what I have done wrong and try to understand why
If it isn't me then I need to learn what the author of the library has done wrong although I have little confidence that it is someone else's code because they have enough experience to put together a library in the first place where as I have so little that I cannot even work out where or how to write a simple line of code that will, in this instance, tell me the state of an alarm that I haven't coded into my sketch.
sorry for my inexperience and ignorance but I came here to learn

Thank you

The RTC3231 has two alarms built in
I am setting one of them
the second one is apparently doing it's own thing lol
Even if I completely remove my coded alarm and all it's references I still have a false alarm at midnight :frowning:

Help with that would be a good start. I have tried various ways to SP that and can't seem to get it right so how should that line read? ---------- 'Serial.print (********?) '

I can SP all the other stuff like 'Serial.print(now. ******* (), DEC);'

The alarm does not sound every day and is not designed to
The time displays continuously but the alarm is set on an " as and when required" basis
If you examine 'case2' (below) you will see that once an alarm is set there is an auto shut off after 1 minute or I can push the 'exit' button to stop the alarm manually
This works as I expected it to and is all that I need it to do

I need it to sit in the corner and tell me the time
I need to be able to set an alarm that sounds at a pre determined time
I need it to be annoying enough that it will wake me even if I have only been asleep for an hour
I need it to be so persistent that I need to get out of bed to shut the flipping thing up

All this it does and very well but I don't need the false alarm that sounds at midnight lol
I have tried everything I can think of.
I am convinced that it is the second alarm facility built into the DS3231 that is misbehaving but I can find nothing in my code that is calling or setting it

I was sort of hoping that someone would jump in and say something like "Dumb ***. Its line *** where you have called alarm2 by **********" :frowning: lol

case 2:
alarm();

  display.showNumberDec(t, true);
  
  auto_alarmStop = alarm_time+1;    //Auto stp after (# min)
  exitButtonState = digitalRead(exitButton);
  if(exitButtonState == LOW){delay(50); activate = 0; digitalWrite(led,LOW);}
  if(t == auto_alarmStop){activate = 0;
  digitalWrite(led,LOW);}
  display.showNumberDec(t, true);
break;

I have looked at your original code.

It has no section that uses the build-in alarm system of the DS3231. Or please point that part out to me.

Post the code you are actually working on, the one that truly magically wakes you up at midnight.

delay() can have unfortunate effects on the program operation. I think the small ones are probably OK, but the delays of 500 add up to more than one second, and your logic requires a match to the second for sounding the alarm. I hope you see the delays could mean you miss the window, there is no alarm, you oversleep, miss class and fail to graduate. It could happen.

As for printing,

    Serial.print("Hey, look at some examples, X = ");
    Serial.println(X);

a7

The code I have posted is the full code that I am using

If this is the RTClib provided by Adafruit, then you should be able to call the following function to disable alarm 2:

rtc.disableAlarm(2);

If you aren't doing anything with alarm2 in your code, then you should be able to call that function once in your setup(), and that should do it. If you still get an alarm at midnight, then something else is going on. I haven't studied your code, but you might want to look at the DS3231 alarm example sketch in the library to see how it handles the alarm.

Perhaps I missed it, but I don't see a way in that library to read in the current value of a DS3231 register. The ones of interest are:

DS3231_CONTROL
DS3231_STATUSREG

Where in your code do you think you are setting an alarm provided by the DS3231?

I don’t see it, so I must be overlooking something.

Point out the specific lines that deal with the DS3231 alarms.

Your RTC object is called rtc, here is how you have used the library:

rtc.begin()
rtc.lostPower()
rtc.adjust();
rtc.now();

No mention of any alarm.

The following functions from the library must be used if you want to use the build-in alarms of the DS3231. The absence of any such calls in your program makes me wonder.

bool RTC_DS3231::setAlarm1(const DateTime &dt, Ds3231Alarm1Mode alarm_mode) {

bool RTC_DS3231::setAlarm2(const DateTime &dt, Ds3231Alarm2Mode alarm_mode) {

void RTC_DS3231::disableAlarm(uint8_t alarm_num) {

void RTC_DS3231::clearAlarm(uint8_t alarm_num) {

bool RTC_DS3231::alarmFired(uint8_t alarm_num) {

a7

An alarm is called when activate is = 2.

Serial.println(activate);

Put additional Serial.println(s) in places where variables are changed and that should show you what is changing activate to 2 at 00:00:00.

Thank you
I am not using this lib. I am using a port of this lib which includes very little. So, in an attempt to solve the prob I switched to use Adafruit's version
Unfortunately it did not solve the problem and a call to disable, clear or both either or both alarms did absolutely nothing :frowning:
Clearly the problem lies elsewhere

evidently you have less understanding of my code than I have because I can assure you, not only does the ghost alarm sound but I can set and cancel an alarm
Maybe you could grab a spare RTC and try it?

Thank you
That simple call was what I couldn't work out
However, I did work it out before I read this and it confirmed a suspicion that something (I still don't know what) was setting 'activate' to 2

For now I have a solution.
It is a bit down and dirty but it does achieve what I want to achieve

if (t == 0) { activate = 0;
break;
}

So, you have a solution, but you still don't know what causes the problem in the first place.
As others have pointed out, you have a timing sketch, yet you introduce delays of over one second.
You dismiss this this with stuff about Space Stations.
Timing matters whether or not it's an alarm or or an atomic clock.
Get rid of delays and get to grips with basics like the Blink without delays in the IDE examples.
Then you come up with this.

evidently you have less understanding of my code than I have because I can assure you, not only does the ghost alarm sound but I can set and cancel an alarm
Maybe you could grab a spare RTC and try it?

I don't think anyone is realistically going to "grab a spare RTC and try it"
The fundamental problem is that somewhere in your code, the precise conditions to call your alarm are being met and that's what you need to get to the bottom of. I can't think of many other ways of doing that than making use of Serial.prints.
You admit you don't know how to use Serial.print, so why not spend some time looking at the documentation?
It could be as simple as adding (quasi code) Serial.print (hour, minute, second) to your alarm function.
Personally, I think your code is over complicated for for a first attempt at an alarm and I would break it down into smaller sketches that work then put them all together.

If you get the opportunity, have a look at a good textbook like Mike Margolis's Arduino Cookbook that covers all the aspects you have included in your code,

Other than that, I have nothing more to add.

All well said and a bit kinder than I would have be.

I argued at the beginning that it was important to get this code working, not by changing libraries and approaches and whatever, but by locating the essential logical flaw.

Now you have found a place to jam a fork in it so it "works". A time-honored technique for fixing broken code. Good thing this isn't for the Space Stations. Or Boeing.

evidently you have less understanding of my code than I have because I can assure you, not only does the ghost alarm sound but I can set and cancel an alarm
Maybe you could grab a spare RTC and try it?

I certainly hope you understand your code. If you do have such a keen understanding of it, then:

It should be no trouble at all for you to point out, in the code, exactly where you deal at all, in any way, with the internal alarms of the DS3231.

Whatever is or isn't going on with your code, it has nothing to do with the alarms. Unless someone has taken your RTC and set an alarm for midnight, it simply is not going to issue an alarm.

And if it did raise the alarm interrupt, there is nothing in your code that would make that fact run your alarm() function.

If your alarm function is going off wrongly, it is all in your own hand-rolled "alarm" system and whatever logic drives it.

OR show me where in the code you are using the alarms, either of them, at all.

a7

alto777

tigger

And I thought I had left all the pretentious idiots behind when I finished full time education nearly 50 yrs ago
My bad!
But, can I make a suggestion?
If you only want to help or teach folks that are at the same level as you then go back to kindergarten and leave it to folks who have compassion, empathy and understanding as well as the willingness to teach.

Firstly, I stated I was having a problem using serial to get the information I was looking for to get to the bottom of this problem. I didn't say that I was having a problem using serial. Have you never drawn a blank?????

FYI: With no alarm time set, 'activate' state is switching to 2 just before midnight triggering an alarm
If an alarm time is set this doesn't happen

SO I'm an idiot because I cant find it
I'm an idiot because, as a senior citizen, I am still learning fresh stuff every single day but I lack the agility of your obvious juvenility.
I'm an idiot because I really don't care that the annoying sound that wakes me up takes a little longer to run through it's sequence when the RTC is still ticking away in the background keeping perfect time.

I asked for help
I asked for help because my elderly brain was having difficulty in understanding a technology that wasn't even in it's infancy when I was last in full time education
I asked for help to understand what was going on so I can further my education

Just telling me to go learn something is not helpful
One poster gave me a pointer that was needed
It was neither of you 2 'Know It All's'

However,
I HAVE learnt something very valuable with this excercise!

This is the second time I have asked for help on this BB and both times have been met with the same attitude so my big take away is that this particular BB is not worth the trouble so I will in future ask for help in other mediums that are more accepting of folk who genuinely want to learn something

The End