+2 голосов
Здравствуйте, подскажите пожалуйсто, как сделать метеостанцию с часами и автополивом. Сделал не большую метеостанцию с часами и LCD дисплеем на ардуино 2560, хочу подключить к этой же плате автополив. Как написать функцию которая будет срабатывать через время, не затрагивая основные функции? Когда пишу скетч с несколькими фунциями, в которых разный промежуток времени, то функция loop  исполняет их по очереди, то есть если в фунции в которой время выводится каждую секунду, а за ней идёт функция автополива которая срабатывает через 8 часов,  то функция времени ждет восемь часов чтобы повторить всю функцию loop.  Я конечно знаю что есть решение ввиде ардуина мега DUE в которой можно исполнять несколько функций loop,  Но можно ли как нибуть сделать это на обычной меге?

Я новичок, если чего то не знаю, не закидывайте помидорками

Взаранее спасибо)
(31 баллов) 8

1 Ответ

+6 голосов
 
Лучший ответ

Обычно применяют конструкцию с счётчиком и в loop() проверяют на его переполнение. То есть у нас есть функция millis(), которая возвращает время, а мы пишем примерно такое:

  if (millis() - my_timer > period_time) {
    my_timer = millis();   // сбрасываем таймер
    
    // здесь пишем код который хотим выполнять
  
  }

// не забываем в setup() указать периодичность срабатывания действия (period_time)
// и завести таймер (my_timer = millis())

Также можно написать очень удобный макрос для вашей цели:

    //===========================
    #define EVERY_MS(x) \
      static uint32_t tmr;\
      bool flag = millis() - tmr >= (x);\
      if (flag) tmr = millis();\
      if (flag)
    //===========================


// пользоваться им можно так:

void loop() {
  {
    EVERY_MS(100) {
      // ваш код
    }
  }
  
  {
    EVERY_MS(500) {
      // ваш код
    }
  }
  
}

// обратите внимание на скобки. Они обязательны, иначе будет ошибка.

Если вы часто сталкиваетесь с этой проблемой, то имеет смысл использовать какую-нибудь библиотеку, которая реализует "многозадачность". Например: GyverTimer

Про неё можно подробно прочитать здесь . В разделе "время, таймеры".

При таком подходе обязательно необходимо отказаться от функции delay(). Она тормозит выполнение loop(), в котором проверяется счетчик. То есть ваш таймер не будет срабатывать, пока delay() не "отпустит" выполнение программы.

(429 баллов) 5 18
выбран
Добро пожаловать на Бредборд! Сайт вопросов и ответов на тему Arduino, Raspberry Pi и хоббийной электроники в целом. Цель Бредборда — быть максимально полезным. Поэтому мы строго следим за соблюдением правил, боремся с холиворами и оффтопиком.
  1. parovoZZ

    102 балл(ов)

  2. Un_ka

    66 балл(ов)

  3. sser

    38 балл(ов)

  4. Тигрыч

    10 балл(ов)

  5. Kiprais

    9 балл(ов)

  6. N08I40K

    8 балл(ов)

Награды месяца
1-е место: Raspberry Pi 3 Model A+
2-е место: Raspberry Pi Zero W
3-е место: Raspberry Pi Zero

...