Таймер обратного отсчета для управления реле (множество функций в пустом контуре)
Я пытаюсь построить этот проект с помощью простого кода. Цель состоит в том, чтобы нажать кнопку «вверх», чтобы увеличить минуты, или «вниз», чтобы уменьшить минуты, затем нажать «старт», чтобы начать обратный отсчет, в то время как его счетное реле будет включать свет, пока подсчет не будет завершен, свет выключится, и если я нажму кнопку завершения во время подсчета, он завершит счет и выключит реле.
Вот моя попытка. Буду признателен, если вы поддержите меня. я не могу перейти к функции countDown() в цикле, если я нажму старт Мне нужна помощь, чтобы найти хорошую технику объявления функций в цикле void в arduino.
#include <LiquidCrystal.h>
LiquidCrystal lcd(1,2,4,5,6,7);
#define numberOfSeconds(num) ((num/1000) % 60 )
#define numberOfMinutes(num) (((num/1000) / 60) % 60)
//без знака long timeLimit = 3600000; // 1000 мс за 1 секунду, 60 секунд за 1 минуту, 60 минут за 1 час. Итак, 1000x60x60 = 3600000 мс = 1 час
const int upBtn = 8;
const int downBtn = 9;
const int startBtn = 10;
const int endBtn = 11;
int btnPushCounter = 0;
int minutes;
int seconds;
unsigned long minutesGiven;
unsigned long timeLimit;
unsigned long timeRemaining;
int upBtnState = 0;
int lastUpBtnState = 0;
int downBtnState = 0;
int lastDownBtnState = 0;
int startBtnState = 0;
int lastStartBtnState = 0;
int endBtnState = 0;
int lastEndBtnState = 0;
bool bPress = false;
void setup() {
lcd.begin(16,2);
pinMode(upBtn, INPUT_PULLUP);
pinMode(downBtn, INPUT_PULLUP);
pinMode(startBtn, INPUT_PULLUP);
pinMode(endBtn, INPUT_PULLUP);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Minutes : ");
lcd.print(btnPushCounter);
}
void loop() {
checkUp();
checkDown();
// обратный отсчет();
if(bPress){
bPress = false;
displayNumber();
}
}
void displayNumber(){
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Minutes : ");
lcd.print(btnPushCounter);
}
void checkUp(){
upBtnState = digitalRead(upBtn);
// сравниваем состояние кнопки с предыдущим состоянием
if (upBtnState != lastUpBtnState) {
// если состояние изменилось, увеличиваем счетчик
if (upBtnState == HIGH) {
bPress = true;
btnPushCounter++;
}
delay(50);
}
// сохранить текущее состояние как последнее состояние для следующего прохода цикла
lastUpBtnState = upBtnState;
}
void checkDown(){
downBtnState = digitalRead(downBtn);
// сравниваем состояние кнопки с предыдущим состоянием
if (downBtnState != lastDownBtnState && btnPushCounter != 0 ) {
// если состояние изменилось, увеличиваем счетчик
if (downBtnState == HIGH) {
bPress = true;
btnPushCounter--;
}
// Небольшая задержка, чтобы избежать подпрыгивания
delay(50);
}
// сохранить текущее состояние как последнее состояние для следующего прохода цикла
lastDownBtnState = downBtnState;
}
void checkStart(){
startBtnState = digitalRead(startBtn);
if(startBtnState != lastStartBtnState){
if(startBtnState == HIGH){
bPress = true;
// ЖК.
}
}
}
void countDown() {
// unsigned long timeLimit = 3600000;
minutesGiven = btnPushCounter;
timeLimit = minutesGiven * 1000 * 60;
timeRemaining = timeLimit - millis();
while(timeRemaining > 0){
seconds = numberOfSeconds(timeRemaining);
minutes = numberOfMinutes(timeRemaining);
lcd.setCursor(2,7);
lcd.print(minutes);
lcd.print(" ");
lcd.print(seconds);
delay(50);
timeRemaining = timeLimit - millis();
}
}
@Ahmed Younes, 👍0
Обсуждение1 ответ
Лучший ответ:
Я думаю, вам нужно объявить свои функции в верхней части файла, обычно перед первой функцией, которую вы пишете, setup()
, в данном случае. Поэтому добавьте это чуть выше функции setup()
:
// Вперед объявления функций
void displayNumber(void);
void checkUp(void);
void checkDown(void);
void checkStart(void);
void countDown(void);
Компиляторы C (и, следовательно, C++, поскольку он был производным от C) читают исходный код только один раз, поэтому любая функция должна быть известна компилятору до того, как она будет вызвана в первый раз. Это потребует, чтобы вы сначала поместили все низкоуровневые функции, затем все функции, которые их вызывают, затем функции, которые вызывают эти, ... и т. д. И есть некоторые случаи, которые даже такое расположение не решит, например, функции которые звонят друг другу (ой, мой мозг болит!!). Поэтому объявления функций используются, чтобы избежать этого неудобства.
Объявление функции просто означает информирование компилятора о ее имени, типах параметров и возвращаемом типе — фактический код функции на данном этапе не требуется.
- Странная проблема. Ардуино перестает работать через несколько часов. Мнения, пожалуйста
- Включайте Arduino по таймеру каждые 24 часа.
- Библиотека LiquidCrystal и таймеры кажутся несовместимыми.
- управление 3 реле с 1 кнопки
- Как закодировать 4 реле, чтобы они срабатывали с интервалами, а не последовательно?
- Включить реле на некоторое время непрерывным входом
- Проблемы с добавлением обратного отсчета к фрагменту кода
- Пытаюсь добавить обратный отсчет в код Arduino, но он делает 0 дней, 04:09:36 вместо того, чтобы начинать с 7 дней
какой у Вас вопрос?, @jsotola
только что обновил, посмотрите, пожалуйста, спасибо, @Ahmed Younes
до сих пор не задан вопрос .... позвольте мне сказать по-другому .... вы написали «я работаю над проектом ABC, вот мой код» .... нам нужно увидеть что-то вроде этого «я работаю над проектом ABC, вот мой код. я ожидаю, что программа сделает XYZ, но она делает ZYX. как мне отладить такую проблему?, @jsotola
Я думаю, вы ищете не способ объявления функции, а логический код, который вам нужно вызывать в правильных ситуациях. Это верно?, @chrisl
И почему бы вам просто не поместить
countDown()
вcheckStart()
?, @chrislперемещение функций выше настройки решило проблему, большое спасибо, ребята, @Ahmed Younes