Что не так с моей клавиатурой и программой времени?

rtc

Мне очень нужна помощь. Я полный нуб в Arduino, и это мой первый проект Arduino. Я пытался заставить клавиатуру вводить время для моего проекта будильника, но мне удалось получить только приветственную часть программы. Но затем на дисплее застряла только часть приветствия. Я хочу установить время будильника, используя только клавиатуру, и если время будильника совпадает с отображаемым временем, должен прозвенеть зуммер.

Кроме того, срок выполнения — два дня. Я уверен, что с аппаратным обеспечением проблем нет, поскольку все компоненты (ЖК-дисплей 16x2, RTC DS1307, зуммер, клавиатура 4x4) работают правильно, когда я использую базовое учебное программирование для компонентов.

Пожалуйста, проверьте, что может быть не так в моем коде? Я пытался заменить некоторые коды, но ничего не изменилось; дисплей все еще застрял на приветственной части.

[Изменить]Я добавил код «милли» в часть timedate(). Но я не уверен, как улучшить часть alarm() этого кода? Я не могу ввести никакую клавишу, чтобы вставить время будильника в этой части.

Если позже появятся какие-либо обновления о том, что я отредактировал в своем коде, я отредактирую тело этого вопроса. Заранее спасибо.

#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); //Установим день недели на ВОСКРЕСЕНЬЕ
rtc.setTime(18, 20, 00); //Установим время 12:00:00 (24-часовой формат)
rtc.setDate(18, 12, 2018); //День месяц год
}

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


1 ответ


Лучший ответ:

0

Ваша функция timedate() вызывается каждый раз через loop() и имеет общую задержку 6000 мс. Во время задержки НИЧЕГО не может произойти, даже не будет проверяться нажатие клавиши.

Итак, вам придется удерживать нужную клавишу до тех пор, пока не будет выполнен оператор key = keypad.getKey(), что происходит минимум каждые 6 секунд.

Использование delay() для интерактивной программы, в которой пользовательский ввод может произойти в любое время, нежелательно. Вместо этого есть популярный пример скетча Arduino под названием "BlinkWithoutDelay", который мы использовали в качестве объяснения того, как избежать использования delay(), позволяя вашей функции loop() работать на очень высокой скорости и выполнять желаемое действие только в том случае, если желаемое время прошло с момента какого-либо инициирующего действия.

Более общая концепция называется «Машина состояний», и существует множество веб-сайтов, которые пытаются ее объяснить, например этот.

Однако будьте готовы внести существенные изменения в структуру вашей программы, поскольку переход от использования delay() к использованию конечного автомата означает переосмысление вашего loop() — вы должны учитывать, что она выполняется десятки тысяч раз в секунду, и в большинстве случаев она ничего не делает, а проверяет, нужно ли что-то сделать — чаще всего ответ «нет, ничего». нужно сделать на этот раз."

,

Спасибо, сэр, сначала я попытаюсь понять концепцию. Я отредактировал вопрос, так как не совсем уверен относительно части кода «alarm()»., @Nur Syahzanani Huda

Нет, ваша функция Alarm() имеет бесконечный цикл, в котором вы выполняете цикл, пока j<4, но никогда не меняете j., @jose can u c