0

I really need help here. I'm a total noob in Arduino and this is my first Arduino project. I've been trying to get the keypad to be able to input time for my alarm clock project but I only managed to get the welcome part of the program. But then the display stuck at the welcome part only. I want to set alarm time by using the keypad only, and if the alarm time is the same as the time display, the buzzer should ring.

Plus, the deadline is in two days. I'm certain that there's no problem with hardware since all of the components (16x2 LCD, RTC DS1307, buzzer, 4x4 keypad) work properly when I use some basic tutorial coding for the components.

Please check what could be wrong in my code? I've tried to replace some of the codes but it had no change; the display's still stuck at the welcome part.

[Edit]I've added the "milli" code at the timedate() part. But I'm not sure, how to improve the alarm() part of this code? I can't input any key to insert the alarm time at this part.

If there's any update on what I've edit to my code later, I will edit this question's body. Thank you in advance.

#include <EEPROM.h>
#include <Keypad.h>
#include <DS1307.h>
#include <Wire.h>
#include <LiquidCrystal.h>
DS1307 rtc(SDA, SCL);
LiquidCrystal lcd(A3, A2, A1, A0, 5, 4);
Time t;

#define buz 3

int Hor, Min, Sec, h, m, s;
int ASCII = 48;
char* tim;
char* dat;
char buffer[3];
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {6, 7, 8, 9};
byte colPins[COLS]= {10, 11, 12, 13};
Keypad keypad= Keypad(makeKeymap(keys),rowPins, colPins, ROWS, COLS);

unsigned long previousMillis = 0;
const long interval = 1000; 

void setup() {
Wire.begin();
rtc.begin();
pinMode(buz, OUTPUT);
lcd.begin(16, 2);
welcome();

rtc.setDOW(TUESDAY); //Set Day-of-Week to SUNDAY
rtc.setTime(18, 20, 00); //Set the time to 12:00:00     (24hr format)
rtc.setDate(18, 12, 2018); //Day, Month, Year
}

void loop() {
t = rtc.getTime();
Hor = t.hour;
Min = t.min;
Sec = t.sec;
tim = rtc.getTimeStr();
dat = rtc.getDateStr();
char key = keypad.getKey();

if(key == 'A'){
alarm();
}

if (key == 'C'){
digitalWrite(buz, LOW);
EEPROM.write(2, ASCII+6);
EEPROM.write(3, ASCII);
}
changealarm();
checkalarm();
timedate();
}

void checkalarm(){
if( Hor == h && Min == m)
{
delay(3000);
lcd.setCursor(0,1);
lcd.print("Hold C");
digitalWrite(buz, HIGH);
delay(3000);
}
}

void changealarm(){
buffer[2] = 0;
buffer[0] = EEPROM.read(0);
buffer[1] = EEPROM.read(1);
h = atoi(buffer);
buffer[0] = EEPROM.read(2);
buffer[1] = EEPROM.read(3);
m = atoi(buffer);
buffer[0] = EEPROM.read(4);
buffer[1] = EEPROM.read(5);
s = atoi(buffer);
}

void timedate(){
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Date: ");
lcd.print(rtc.getDateStr());

lcd.setCursor(0,1);
lcd.print("Time: ");
lcd.print(rtc.getTimeStr());
delay(3000);
lcd.setCursor(0,1);
lcd.print("Alarm: ");
lcd.print(h);
lcd.print(":");
lcd.print(m);
lcd.print(":");
lcd.print(s);
}
}

void welcome(){
lcd.setCursor(0,0);
lcd.print("Welcome");

lcd.setCursor(0,1);
lcd.print("To");
delay(2000);

lcd.setCursor(0,1);
lcd.print("TIMe Project");
delay(2000);
}

void alarm()
{
int j=0;
char key = keypad.getKey();
lcd.clear();
lcd.print("Enter Alarm Time: ");
lcd.setCursor(0,1);
while(j<4)
{
lcd.print(h);
lcd.print(":");
lcd.print(key);
lcd.print(m);
lcd.print(":");
lcd.print(key);
lcd.print(s);
lcd.print(key);
key=0;
}
delay(500);
}
0

Your function timedate() is called every time through loop() and it has a total of 6000ms of delay. During a delay, NOTHING can happen, not even checking for a keypress.

So, you would have to hold the desired key down until the key = keypad.getKey() statement is executed, which is a minimum of every 6 seconds.

Use of delay() for an interactive program in which user input can happen any time is not desired. Instead, there is a popular example Arduino sketch called "BlinkWithoutDelay" which us used as an explanation of how to avoid using delay() by letting your loop() function run at very high speed and only taking the desired action if the desired time has elapsed since some initiating action.

The more generic concept is called a "State Machine" and there are numerous websites that attempt to teach it, such as this one.

Be prepared to make significant changes to the structure of your program, however, as moving from delay() usage to state machine usage means a re-thinking of your loop() function -- you have to consider it running tens of thousands of times per second, and most of those times it doesn't do anything but check if something needs to be done -- most often the answer is "no, nothing needs to be done this time."

| improve this answer | |
  • Thank you sir, I'll try to understand the concept first. I've edited the question as I'm quite not sure regarding the alarm() code part. – Nur Syahzanani Huda Dec 18 '18 at 18:26
  • No, your alarm() function has an infinite loop, where you loop while j<4, but never adjust j. – jose can u c Dec 18 '18 at 18:29

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.