2

I am trying to create smart clock with alarm using an Arduino Uno.

My problem is when I set the alarm, I can't set the alarm again. Every time I must power off my Arduino and then power on in order to set the alarm again.

I am using:
Arduino Uno
LCD 16*2
buttons
buzzer and LED
RTC

My code works like this: At the beginning it will let you to set date and time by buttons and you can set alarm too. When it reaches the alarm time, it turns on the melody of buzzer and LEDs turn on.

but

I want to turn off the alarm so I can set another alarm.

This is my code:

#include "RTClib.h"
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int alarmState = 0;
int alarmSnooze = 0;
int btnSet = 0;
int btnSel = 0;
int alarmValue = 0;
int alarmCounter = 0;
boolean turnOffAlarm = false;
boolean settingAlarm = false;
int counter = 0;
boolean initialCount = true;
boolean alarmSet = false;
int timeArray[6]; // 0=Hour, 1=Minutes, 2=day, 3=Day of Week, 4=Month, 5=Year;
int timeCounter = 0;
int alarmArray[2];
char* days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
char* months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
RTC_DS1307 rtc;    // Create a RealTimeClock object
DateTime now; // Read data from the RTC Chip

//////////////////////////
 ///difine button////
int  b6=6;
int b7=7;
int b8=8;
int b9=9;
////////////////////




///melody///
#include "pitches.h"

const int piezoPin = 13; //piezo
const int rPin = A0;  //red LED
const int gPin = A1;  //green LED
const int bPin = A2;  //blue LED
const int pPin = 6;  //pushbutton

int ledState = 0;
int ledOn = false;


// notes
int melody[] = {
  NOTE_F5,NOTE_D5,NOTE_AS4,NOTE_D5,NOTE_F5,NOTE_AS5,NOTE_D6,NOTE_C6,NOTE_AS5,NOTE_D5,NOTE_E5,NOTE_F5,
  NOTE_F5,NOTE_F5,NOTE_D6,NOTE_C6,NOTE_AS5,NOTE_A5,NOTE_G5,NOTE_A5,NOTE_AS5,NOTE_AS5,NOTE_F5,NOTE_D5,NOTE_AS4,
  NOTE_D6,NOTE_D6,NOTE_D6,NOTE_DS6,NOTE_F6,NOTE_F6,NOTE_DS6,NOTE_D6,NOTE_C6,NOTE_D6,NOTE_DS6,NOTE_DS6,
  0,NOTE_DS6,NOTE_D6,NOTE_C6,NOTE_AS5,NOTE_A5,NOTE_G5,NOTE_A5,NOTE_AS5,NOTE_D5,NOTE_E5,NOTE_F5,
  NOTE_F5,NOTE_AS5,NOTE_AS5,NOTE_AS5,NOTE_A5,NOTE_G5,NOTE_G5,NOTE_G5,NOTE_C6,NOTE_DS6,NOTE_D6,NOTE_C6,NOTE_AS5,NOTE_AS5,NOTE_A5,
  NOTE_F5,NOTE_F5,NOTE_AS5,NOTE_C6,NOTE_D6,NOTE_DS6,NOTE_F6,NOTE_AS5,NOTE_C6,NOTE_D6,NOTE_DS6,NOTE_C6,NOTE_AS5
};

// durations: 2 = half note, and 8/3,4,6,8,12. It appears that 8/2.9 is more accurate than 8/3.
float noteDurations[] = {
  6,12,4,4,4,2,6,12,4,4,4,2,
  8,8,8/2.9,8,4,2,8,8,4,4,4,4,4,
  6,12,4,4,4,2,8,8,4,4,4,2,
  8,8,8/2.9,8,4,2,8,8,4,4,4,2,
  4,4,4,8,8,4,4,4,4,8,8,8,8,4,4,
  8,8,8/2.9,8,8,8,2,8,8,4,4,4,2
};


// calculates the number of elements in the melody array.
int musicLength=sizeof(melody)/sizeof('NOTE_F5');

//////////////////////////






void setup()
{


  pinMode(pPin, INPUT);
  pinMode(rPin, OUTPUT);
  pinMode(gPin, OUTPUT);
  pinMode(bPin, OUTPUT);


  Serial.begin(9600);
  lcd.begin(16, 2);
  pinMode(10, OUTPUT);
  rtc.begin(); // Start the RTC library code
  rtc.adjust(DateTime(0, 0, 0, 0, 0, 0));
}
void loop()

{ alarmState = digitalRead(b9);
  alarmSnooze = digitalRead(b6);
  btnSet = digitalRead(b7);
  btnSel = digitalRead(b8);


  if (timeCounter == 0)
  {
    if(initialCount == true){
      counter=0;
      initialCount = false;
    }
    setHour();
  }
  else if (timeCounter == 1)
  {
    if(initialCount == true){
      counter=0;
      initialCount =false;
    }
    setMinute();
  }
  else if (timeCounter == 2)
  {
    if(initialCount == true){
      counter= 1;
      initialCount=false;
    }
    setDay();
  }
  else if (timeCounter == 3)
  {
    if(initialCount == true){
      counter = 0;
      initialCount =false;
    }
    setDOW();
  }
  else if (timeCounter == 4)
  {
    if(initialCount==true){
      counter=0;
      initialCount=false;
    }
    setMonth();
  }
  else if (timeCounter == 5)
  {
    if(initialCount==true){
      counter=0;
      initialCount=false;
    }
    setYear();
  }
  else if (timeCounter == 6)
  {
    rtc.adjust(DateTime(2000+timeArray[5], timeArray[4], timeArray[2], timeArray[0], timeArray[1], 0));
    timeCounter++;
    delay(200);
  }
  else if (timeCounter > 6){
    if(alarmState == LOW&&settingAlarm==false){
      now = rtc.now();
      digitalClockDisplay();
    }
    else if(alarmState == HIGH||settingAlarm==true)
    {
      settingAlarm = true;
      if(alarmValue==0){
        if(initialCount==true)
        {
          lcd.clear();
          alarmCounter=0;
          initialCount=false;
        }
        setAlarmHour();
      }
      else if(alarmValue==1){
        if(initialCount==true)
        {
          alarmCounter=0;
          initialCount=false;
        }
        setAlarmMinute();
      }
      else if(alarmValue>1){
        alarmSet = true;
        settingAlarm = false;
      }
    }
    if(alarmArray[0]==now.hour()&&alarmArray[1]==now.minute()&&turnOffAlarm==false&&alarmSet==true&&alarmSnooze==LOW){
       for (int thisNote = 0; thisNote < musicLength; thisNote++) {
      // blink the three LEDs in sequence
      if (thisNote%3==0){    
        digitalWrite(rPin, HIGH);
        digitalWrite(gPin, LOW);
        digitalWrite(bPin, LOW);
      }
      else if (thisNote%3==1){    
        digitalWrite(rPin, LOW);
        digitalWrite(gPin, HIGH);
        digitalWrite(bPin, LOW);
      }
      else if (thisNote%3==2){    
        digitalWrite(rPin, LOW);
        digitalWrite(gPin, LOW);
        digitalWrite(bPin, HIGH);
      }

      // calculate the note duration. change tempo by changing 2000 to other values
      int noteDuration = 2000/noteDurations[thisNote];
      tone(piezoPin, melody[thisNote],noteDuration);

      // to distinguish the notes, set a minimum time between them.
      // the note's duration + 30% seems to work well
      float pauseBetweenNotes = noteDuration * 1.30;

      //split the delay into two parts and check to see
      //whether the pushbutton is pressed to turn off
      //the sound and light
      delay(pauseBetweenNotes/2);
      if(digitalRead(pPin)==HIGH) {
        break;      
      }
      delay(pauseBetweenNotes/2);
      if(digitalRead(pPin)==HIGH) {
        break;      
      }

    }
      digitalWrite(13, HIGH);

    }




    else if(alarmArray[0]==now.hour() && alarmArray[1]==now.minute()&&turnOffAlarm==false&&alarmSet==true&&alarmSnooze==HIGH){
      noTone(13);
      digitalWrite(13, LOW);
      digitalWrite(rPin, LOW);
    digitalWrite(gPin, LOW);
    digitalWrite(bPin, LOW);
      turnOffAlarm = true;
    } 
  }
}

void nextValue(){
  btnSel=LOW;
  // Update array value with counter
  timeArray[timeCounter] = counter;
  counter=0;
  initialCount = true;
  timeCounter++;
  delay(200);
  lcd.clear();
}
void nextAlarmValue(){
  btnSel=LOW;
  // Update array value with counter
  alarmArray[alarmValue] = alarmCounter;
  alarmCounter=0;
  initialCount = true;
  alarmValue++;
  delay(200);
  lcd.clear();
}

void setAlarmHour(){
   if(alarmCounter==24){
    alarmCounter=0;
    lcd.clear();
  }
  lcd.setCursor(0,0);
  lcd.print("Set alarm hour");
  lcd.setCursor(7,1);
  lcd.print(alarmCounter);
  if (btnSet==HIGH)
  {
    alarmCounter++;
    delay(200);
  }
 else if(btnSel==HIGH)
 {
  nextAlarmValue();
 }
}

void setAlarmMinute(){
  if(alarmCounter==59){
  alarmCounter=0;
  lcd.clear();
  }
  lcd.setCursor(0,0);
  lcd.print("Set alarm minute");
  lcd.setCursor(7,1);
  lcd.print(alarmCounter);
  if (btnSet==HIGH)
  {
    alarmCounter++;
    delay(200);
  }
 else if(btnSel==HIGH)
 {
  nextAlarmValue();
 }
}

void setDOW(){
  if(counter==7){
    counter=0;
    lcd.clear();
  }
  lcd.setCursor(0,0);
  lcd.print("Set day of week");
  lcd.setCursor(7,1);
  lcd.print(days[counter]);
  if (btnSet==HIGH)
  {
    counter++;
    delay(200);
  }
 else if(btnSel==HIGH)
 {
  nextValue();
 }
}
void setHour()
{
  if(counter==24){
    counter=0;
    lcd.clear();
  }
  lcd.setCursor(0,0);
  lcd.print("Set hour");
  lcd.setCursor(7,1);
  lcd.print(counter);
  if (btnSet==HIGH)
  {
    counter++;
    delay(200);
  }
 else if(btnSel==HIGH)
 {
  nextValue();
 }
}

// Function to set minutes
void setMinute()
{
  if(counter==60){
    counter=0;
    lcd.clear();
  }
  lcd.setCursor(0,0);
  lcd.print("Set minute");
  lcd.setCursor(7,1);
  lcd.print(counter);
  if (btnSet==HIGH)
  {
    counter++;
    delay(200);
  }
 else if(btnSel==HIGH)
 {
  nextValue();
 }
}

// Function to set date
void setDay()
{
  if(counter==32){
    counter=1;
    lcd.clear();
  }
  lcd.setCursor(0,0);
  lcd.print("Set day");
  lcd.setCursor(7,1);
  lcd.print(counter);
  if (btnSet==HIGH)
  {
    counter++;
    delay(200);
  }
 else if(btnSel==HIGH)
 {
  nextValue();
 }
}

// Function to set month
void setMonth()
{
  if(counter==12){
    counter=0;
    lcd.clear();
  }
  lcd.setCursor(0,0);
  lcd.print("Set month");
  lcd.setCursor(7,1);
  lcd.print(months[counter]);
  if (btnSet==HIGH)
  {
    counter++;
    delay(200);
  }
 else if(btnSel==HIGH)
 {
  nextValue();
 }
}

// Function to set year
void setYear()
{
  lcd.setCursor(0,0);
  lcd.print("Set year");
  lcd.setCursor(7,1);
  lcd.print(counter);
  if (btnSet==HIGH)
  {
    counter++;
    delay(200);
  }
 else if(btnSel==HIGH)
 {
  nextValue();
 }
}

void digitalClockDisplay(){
  // digital clock display of the time
  long hours;
  String amOrPm = "";
  if(now.hour() > 12){
    hours = now.hour() - 12;
    amOrPm = "PM";
  }
  else if(now.hour()==0){
    hours=12;
    amOrPm = "AM";
  }
  else{
    hours = now.hour();
    amOrPm = "AM";
  }
  lcd.setCursor(0,0);
  lcd.print(days[timeArray[3]]);
  lcd.print(" ");
  lcd.print(months[timeArray[4]]);
  lcd.print(" ");
  lcd.print(now.day());
  lcd.print(" ");
  lcd.print(now.year());
  lcd.setCursor(0,1);
  lcd.print(hours);
  printDigits(now.minute());
  printDigits(now.second());
  lcd.print(" ");
  lcd.print(amOrPm);
}

void printDigits(int digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  lcd.print(":");
  if(digits < 10)
    lcd.print('0');
  lcd.print(digits);
}
| improve this question | | | | |
  • What did you try to do by sizeof(melody)/sizeof('NOTE_F5')??? What is the point of sizeof('NOTE_F5') specifically? What did the compiler tell you about 'NOTE_F5'? – AnT May 3 '19 at 14:40
1

It looks like you haven't reset your state variable turnOffAlarm after you turn off the alarm.

| improve this answer | | | | |
0

Since the question is tagged [code-review]

  1. char* days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
    

    This should be a const array of const char *, not of char *.

    const char *const days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
    

    Same goes for months.

  2. int  b6=6;
    ...
    const int piezoPin = 13;
    ...
    

    Why some of your pins are const and others are not? I don't see any attempts or reasons to change the value of b6 in the code. Why is it not const?

  3. int melody[] = { ... };
    float noteDurations[] = { ... };
    

    Both are supposed to be be const, apparently.

  4. // calculates the number of elements in the melody array.
    int musicLength=sizeof(melody)/sizeof('NOTE_F5');
    

    Really? What is 'NOTE_F5'? What did your compiler tell you about it? Did you just ignore the compiler's message?

    Should be

    const int musicLength = sizeof melody / sizeof *melody;
    

    I'd prefer unsigned or size_t, but let's not open this can of worms.

  5. In a single-file sketch all global variables (i.e. the ones that really need to be global) should be declared either const or static (or placed in an anonymous namespace). Declaring a global variable that is not const or static requires a good reason for doing so.

| improve this answer | | | | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.