Как преобразовать код кухонного таймера в обратный отсчет

Я нашел этот код для кухонного таймера, он был ближе всего к обратному отсчету. Код находится здесь:


#include <LiquidCrystal.h>

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

signed short minutes, secondes;
char timeline[16];

void setup() {

  lcd.begin(16, 2);
  lcd.print("Chronometre :");


}

void loop() {

  lcd.setCursor(0, 1);
  sprintf(timeline,"%0.2d mins %0.2d secs", minutes, secondes);
  lcd.print(timeline);
  
  delay(1000);
  secondes++;
  
  if (secondes == 60)
  {
    secondes = 0;
    minutes ++;
  }

}

Как правильно преобразовать его в обратный отсчет от 1 минуты и 30 секунд?

, 👍1

Обсуждение

Как насчет инициализации переменных времени "секунды" и "минуты" со значениями 1:30, а затем вместо увеличения их уменьшения? И, конечно, проверка того, чтобы секунды были ниже нуля, для уменьшения минут. Вы пробовали это сделать?, @chrisl

Я не знал, как это сформулировать. Не могли бы вы предложить какой-нибудь код?, @James Christaldi

Вы действительно должны сделать несколько базовых руководств по C/C++ и Arduino, когда захотите заняться Arduino. В противном случае вам будет не очень весело. Кроме того, мы не являемся бесплатной службой кодирования. Посмотрите на код, в котором определены упомянутые переменные. Дайте каждому подходящее значение, написав " = " после имени, а затем значение. В "цикле ()" вы заменяете ++ после имен переменных на"--", чтобы уменьшить их. Затем в случае, если условие " повторяется < 0)` и внутри оператора if "secondes = 59". Это все, на что я здесь пойду. С помощью некоторых учебных пособий и экспериментов вы сможете понять этот код., @chrisl

- Я не знал, как это сформулировать.` ... как вы думаете, что делает такая строка, как " секунды = 0;"?, @jsotola

"настройте этот код, который я нашел" - это не то, почему мы здесь. Я имею в виду, что это действительно тривиально. Разбейте проблему на более мелкие этапы и попросите о помощи, когда вы застряли. Часто используйте Serial.println (), когда вы начинаете кодировать. много., @dandavis

@christl Я знаю, что это не бесплатная служба кодирования. Это был простой вопрос. Есть ли в этом что-то неправильное?, @James Christaldi

@JamesChristaldi Нет, абсолютно ничего плохого в том, чтобы задать вопрос. Это было не для того, чтобы ругать тебя. Я просто думаю, что ваш вопрос оставляет в основном два способа ответа здесь: написать для вас код или дать вам базовый курс C/C++. На первого здесь смотрят неодобрительно по некоторым веским причинам. Второе выполняется намного лучше с помощью множества базовых учебных пособий/курсов по C/C++ в Интернете. Таким образом, я дал комментарий о необходимых шагах и предоставил вам изучить соответствующий синтаксис C/C++ в одном из учебных пособий/курсов., @chrisl

Но это Arduino, а не C/C++, @James Christaldi

Верно? Может быть, я ошибаюсь в этом?, @James Christaldi

Код Arduino в основном на C/C++, включая "Arduino.h", который определяет функции, связанные с Arduino, такие как " digitalRead()` и многое другое. Если вы умеете программировать на C/C++, программирование на Arduino будет намного проще, потому что вы понимаете, как инициализировать переменные, использовать циклы и т.д., @Python Schlange


2 ответа


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

1

Для начала вам нужно инициализировать переменные secondes и minutes до 30 и 1 соответственно.

заменить подписанные короткие минуты, секунды; на:

signed short minutes = 1;
signed short secondes = 30;

Следующее, что я замечаю, - это то, что предоставленный вами код отсчитывается, а вы запросили, чтобы он отсчитывался.

Измените secondes++; и minutes++; с помощью:

secondes--;
minutes--;

Наконец, вам нужно изменить логику для того момента, когда переменные secondes и minutes достигнут нуля.

Если переменная secondes достигает нуля, а переменная minutes больше нуля, то вы уменьшаете количество минут (используя приведенную выше строку кода) и пополняете secondes на 59.

secondes = 59;

Вам нужно будет проверить значение переменных secondes и minutes с помощью пары операторов if...else.

if (secondes == 0 && minutes == 0) {
    // вставьте свой готовый код таймера сюда
}
else if ( secondes == 0 && minutes > 0) {
    minutes--;
    secondes = 59;
}
else {
    // Error - ваш код не должен доходить сюда.
    // Отображение сообщения об ошибке на lcd
}

Этот оператор if..else должен будет идти в верхней части вашего цикла, а не в конце.

,

Большое вам спасибо!!, @James Christaldi


1

Первое, что я рекомендую, - это не использовать функцию sprintf(). Ваш скетч "пространство для хранения программ" падает с 3502 байт до 1928 байт, если вы НЕ используете этот вызов функции, а используемая динамическая память падает со 101 до 79 байт.

Я бы порекомендовал ООП-дизайн, который позволил бы легко добавлять функциональные возможности, такие как возможность запуска, остановки и сброса таймера.

// Arduino Uno, IDE version 1.8.9
// 2330 bytes (7%) of program storage space.
// Global variables use 201 bytes (9%) of dynamic memory.
class CountdownTimer{

  private:

    byte m_hour;
    byte m_minute;
    byte m_second;
    byte m_timerActive;
    byte m_timerComplete;
    unsigned long m_previousMillis;

  public:

    CountdownTimer():
      m_hour(0),
      m_minute(0),
      m_second(0),
      m_timerActive(0),
      m_timerComplete(0),
      m_previousMillis(0){}

    bool Update(){

      if(m_hour == 0 && m_minute == 0 && m_second == 0){
        m_timerComplete = 1;
        return 0;
      }

      if(m_timerActive && (millis() - m_previousMillis >= 1000)){
        m_previousMillis += 1000;
        m_second--;
        if(m_second == 255){
          m_second = 59;
          m_minute--;
          if(m_minute == 255){
            m_minute = 59;
            m_hour--;
            if(m_hour == 255){
              m_hour = 0;
            }
          }
        }
        return 1;
      }
      else{
        return 0;
      }
    }

    byte GetIsTimerComplete(){
      return m_timerComplete;
    }

    void SetHour(byte hour){
      m_hour = constrain(hour, 0, 23);
    }

    void SetMinute(byte minute){
      m_minute = constrain(minute, 0, 59);
    }

    void SetSecond(byte second){
      m_second = constrain(second, 0, 59);
    }

    void Start(){
      m_timerActive = 1;
    }

    void Stop(){
      m_timerActive = 0;
    }

    void ReStart(){
      m_timerActive = 1;
      m_timerComplete = 0;
      m_previousMillis = millis();
    }

    void PrintTimeRemaining(){
      if(m_hour < 10){Serial.print("0");}
      Serial.print(m_hour);
      Serial.print(":");
      if(m_minute < 10){Serial.print("0");}
      Serial.print(m_minute);
      Serial.print(":");
      if(m_second < 10){Serial.print("0");}
      Serial.println(m_second);
    }

};

// Сделать копию объекта для работы.
CountdownTimer myCountdownTimer;
  
void setup(){

  // Встроенный PIN 13 светодиодный индикатор завершения таймера.
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);

  // Тестовый выход на последовательный монитор.
  Serial.begin(9600);

  // Установите значения таймера обратного отсчета,
  // запустите таймер обратного отсчета и
  // выведите начальную настройку таймера.
  myCountdownTimer.SetHour(0);
  myCountdownTimer.SetMinute(1);
  myCountdownTimer.SetSecond(30);
  myCountdownTimer.Start();
  myCountdownTimer.PrintTimeRemaining();
}

void loop(){

  // Вызовите функцию обновления как можно быстрее.
  if(myCountdownTimer.Update()){
    myCountdownTimer.PrintTimeRemaining();
  }

  // Включите светодиод Uno Pin 13 после завершения таймера.
  if(myCountdownTimer.GetIsTimerComplete()){
    digitalWrite(LED_BUILTIN, HIGH);
  }

}
,