Beginner here, seeking help with a surprising output.
I'm programming an alarm clock that turns off when a target is hit. I have both parts working - the alarm clock and the target sensor - but I've made an unidentified error in getting the alarm to turn off when the target is hit.
I also get duplicates of some serial monitor lines. That's probably unrelated, but in case it's not, I figured I'd mention it.
The target is being read correctly, and 'alarmstate' set to 0, which should end the alarm, but the buzzer doesn't stop. I see in the serial monitor that the 'alarmstate' is being set back to 1.
Why is that? The code setting alarmstate = 1 is in the setup, not in the loop of the program.
The loop does have a brief check to reset the alarmstate to 1 at midnight, but the problem remains even when I remove those lines. Then the setup is the ONLY place the alarmstate is set to 1.
How is it getting back to 1?
Thanks, oh Arduino gurus. This one is puzzling me.
#include <DS3231.h>
#include <Wire.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
DS3231 rtc(SDA, SCL);
Time t;
#define buz 11
int Hor;
int Min;
int Sec;
const int knockSensor = A0; // the piezo is connected to analog pin 0
const int threshold = 550; // high threshold value to decide when the detected sound is a knock or not
const int threshold2 = 470; // low threshold
int sensorReading; // variable to store the value read from the sensor pin
int end_time; // variable to set how long the starting buzzer activates
// A starting buzzer makes it easier to test the target whent the program is loaded
// but it can be commented out if you just want the alarm clock to run
int alarmstate; // make alarm to active. Set to zero to turn off.
void setup()
{
// setting base values for the variables
sensorReading = 500;
end_time= 0;
alarmstate = 1;
// this limits the starting buzzer to (end_time/1000) seconds and prints the value
// end_time=millis()+60000; un-comment this to activate the starting buzzer for 60 seconds.
// Alarm Clock Code begins here
Wire.begin();
rtc.begin();
Serial.begin(9600);
// Note length of starting buzzer, in seconds. Oddly, this prints twice.
Serial.print("end time = ");
Serial.println((end_time/1000));
pinMode(buz, OUTPUT);
lcd.begin(16,2);
lcd.setCursor(0,0);
lcd.print("Arduino Alarm ");
lcd.setCursor(0,1);
lcd.print(" Target ");
delay(100);
// Un-comment these 3 lines to set the date and time, then re-comment after running once.
// rtc.setDOW(SUNDAY); // Set Day-of-Week to SUNDAY
// rtc.setTime(15, 37, 30); // Set the time to 12:00:00 (24hr format)
// rtc.setDate(9, 5, 2021); // Set the date to Sep 5th, 2021
}
void loop()
{
// Update and display time
t = rtc.getTime();
Hor = t.hour;
Min = t.min;
Sec = t.sec;
lcd.setCursor(0,0);
lcd.print("Time: ");
lcd.print(rtc.getTimeStr());
lcd.setCursor(0,1);
lcd.print("Date: ");
lcd.print(rtc.getDateStr());
// reset alarm active state at midnight
if( Hor == 00 && Min == 00 )
{
alarmstate=1;
}
// this sounds a buzzer when the program starts, making it easy to test the target.
// it runs for (end_time/1000) seconds, or until the target is hit
// when the target is hit, end_time is set to zero, so the starting buzzer isn't re-activated.
if( (millis()<=end_time) && (sensorReading < threshold || sensorReading > threshold2)) //Comparing the current time with the Alarm time
{
// prints the time in seconds that this initial routine has been running
Serial.print("seconds = ");
Serial.println((millis()/1000));
Buzzer();
Buzzer();
lcd.clear();
lcd.print("Alarm ON");
lcd.setCursor(0,1);
lcd.print("Alarming");
Buzzer();
Buzzer();
}
delay(100);
if( Hor == 16 && (Min == 45 || Min == 46) && (alarmstate = 1))//Comparing current time with Alarm time and seeing if the alarm is turned on.
{
sensorReading = analogRead(knockSensor);
Serial.print("Sensor Reading = ");
Serial.println(sensorReading);
Serial.print("Alarm State = ");
Serial.println(alarmstate);
if (sensorReading < threshold && sensorReading > threshold2)
{
Buzzer();
Buzzer();
lcd.clear();
lcd.print("Alarm ON");
lcd.setCursor(0,1);
lcd.print("Alarming");
Buzzer();
Buzzer();
}
else
{
Serial.print("Sensor Reading = ");
Serial.println(sensorReading);
Serial.println("Target hit!");
alarmstate=0;
Serial.print("Alarm State = ");
Serial.println(alarmstate);
}
// set end_time to zero so that this loop stops playing the starting buzzer
end_time = 0;
delay(100); // delay to avoid overloading the serial port buffer
}
}
void Buzzer()
{
digitalWrite(buz,HIGH);
delay(10);
digitalWrite(buz, LOW);
delay(100);
}