Как выполнить две задачи в одном цикле в Arduino?

Я пытаюсь сделать монитор погоды с помощью Arduino. Я хочу, чтобы мой метеорологический монитор отправлял мне сообщение с данными о погоде каждые 5 часов через GSM-шлюз. Кроме того, на моем метеорологическом мониторе есть ЖК-дисплей, который показывает текущие погодные условия. Проблема, с которой я столкнулся, заключается в том, что задержка в 5 часов в моем коде также применима к ЖК-дисплею, который обновляет ЖК-дисплей каждые 5 часов, а не каждую секунду, как следовало бы. Подскажите пожалуйста, как запустить эти две функции одновременно.

, 👍0

Обсуждение

см. пример BlinkWithoutDelay, @Juraj

Вот простая абстракция (Timemark), которую очень легко писать. https://github.com/mikaelpatel/Arduino-Timemark/blob/master/Timemark.h, @Mikael Patel

пожалуйста, опубликуйте свой код, @jsotola


2 ответа


1

Рассмотрите возможность использования автомата конечных состояний для отслеживания нескольких задач. В частности, состояние, в котором вы отправляете свое сообщение раз в 5 часов. И состояние, в котором вы обновляете свой ЖК-дисплей, возможно, раз в секунду.

Поскольку ваши задачи связаны со временем, рассмотрите возможность использования встроенного в Arduino вызова millis( ), чтобы узнать, сколько миллисекунд работала программа Arduino. Это не заблокирует вашу программу. Вместо этого он немедленно вернется с номером, которым вам нужно будет управлять.

Чтобы создать задержку, используйте указанное выше число из millis() и добавьте количество миллисекунд для желаемой задержки. Вызовите millis() несколько раз, пока она не вернет вычисленное число или число, превышающее вычисленное число. Используйте это для управления вашим конечным автоматом. Возможно, вы используете millis() только для подсчета секунд, а программное обеспечение — для подсчета до 5 часов (5 x 60 x 60 секунд).

Обратите внимание, что millis() в конечном итоге перевернется, поскольку имеет тип unsigned long. То есть он будет переворачиваться раз в 50 дней. Если вы хотите сохранить точное время, когда это произойдет, вам придется учитывать переключение в вашей программе.

,

примечание: пример BlinkWithoutDelay "учитывает опрокидывание", @Juraj


0

Что-то вроде этого псевдокода должно вам помочь.

unsigned long weatherUpdate; // Используйте беззнаковые длинные значения для миллис раз
unsigned long screenUpdate;  // Вам нужно реже беспокоиться о переносе
unsigned long timeNow;

setup {

  unsigned int interval1 = 0; // 0 Должна быть любая задержка, которая вам нужна
  unsigned int interval2 = 0; // 0 Должна быть любая задержка, которая вам нужна

  updateScreen();
  screenUpdate = millis();

  updateWeather();
  weatherUpdate = millis;

}

loop {

  timeNow = millis();

  /* 
     These if statements are true when the interval between the current time
     and the last time the if ran is greater than the required interval. For
     organization purposes, maybe create separate functions for when you 
     update your screen and weather functions instead of just replacing 
     the function stubs I've included.
  */

  if((timeNow - screenUpdate) > interval1){

    updateScreen();  // Делаем то, что нужно
    screenUpdate = millis();  // Обновляем время с момента последнего запуска

  }

  if((timeNow - weatherUpdate) > interval2){

    updateWeather();  // Делаем то, что нужно
    weatherUpdate = millis();  // Обновляем время с момента последнего запуска

  }

}
,