Сдвигается время задержки при работе цикла

Тема в разделе "Arduino & Shields", создана пользователем belllomoe, 26 фев 2020.

Метки:
  1. belllomoe

    belllomoe Нуб

    Приветствую! Прошу совета.
    Сделал код для работы четырех реле, с задержками кратными секунде. Просто по сути подача HIGH на пин с определенной задержкой.
    Проблема в том, что начинают работать они синхронно, через минуту работы наблюдается запаздывание включения одного реле от другого, через пять минут явная рассинхронизация. Прошу помочь с советом, только начал осваивать millis, возможно, что то не догоняю...
    Код (C++):
    const int r1pin = 12;
    const int r2pin = 8;
    const int r3pin = 3;
    const int r4pin = 2; //номер пина выхода на реле

    int r1on = LOW;
    int r2on = LOW;
    int r3on = LOW;
    int r4on = LOW;       //переменная состояния реле

    long postimer1 = 0;
    long postimer2 = 0;
    long postimer3 = 0;
    long postimer4 = 0;   //храним время последнего вкл реле (Пос.тайм.р1-р4)

    long inttimer1 = 1000;
    long inttimer2 = 2000;
    long inttimer3 = 3000;
    long inttimer4 = 4000;  //интервал вкл-выкл реле


    void setup() {
      // put your setup code here, to run once:
    pinMode(r1pin, OUTPUT);
    pinMode(r2pin, OUTPUT);
    pinMode(r3pin, OUTPUT);
    pinMode(r4pin, OUTPUT);  //режим работы пина - выход
    }

    void loop() {
     
      unsigned long currentMillis = millis();  // проверяем не прошел ли нужный интервал, если прошел, то

    if( currentMillis - postimer1 >   inttimer1)
    {postimer1 = currentMillis;  //сохраняем время посл переключения
    if (r1on == LOW)    //если светодиод реле не вкл, включаем, и наоборот
    r1on = HIGH;
    else
    r1on = LOW;

    digitalWrite (r1pin, r1on);  //устанавливаем состояние выхода, чтобы вкл или выкл реле.
    }
      if( currentMillis - postimer2 >   inttimer2)
    {postimer2 = currentMillis;
    if (r2on == LOW)
    r2on = HIGH;
    else
    r2on = LOW;

    digitalWrite (r2pin, r2on);
      }
     
       if( currentMillis - postimer3 >   inttimer3)
    {postimer3 = currentMillis;
    if (r3on == LOW)
    r3on = HIGH;
    else
    r3on = LOW;

    digitalWrite (r3pin, r3on);}

      if( currentMillis - postimer4 >   inttimer4)
    {postimer4 = currentMillis;
    if (r4on == LOW)
    r4on = HIGH;
    else
    r4on = LOW;

    digitalWrite (r4pin, r4on);}
     
     
      }


     
     
  2. Asper Daffy

    Asper Daffy Иксперд

    Миллис - штука не самая точная. Она накапливает ошибку, потом её компенсирует. Вот и расползаются из-за компенсации, наверное.

    У тебя кратные интервалы, потому можно сделать очень просто:

    Оставь один интервал - самый маленький. Для остальных реле просто заведи счётчики срабатывания (изначально - нули).

    Когда интервал истёк. Переключай первое реле, а для второго увеличивай на 1 счётчик. Если он стал 2, то переключай реле и сбрасывай счётчик в 0. Для третьего увеличивай на 1 счётчик. Если он стал 3, то переключай реле и сбрасывай счётчик в 0. Для четвёртого увеличивай на 1 счётчик. Если он стал 4, то переключай реле и сбрасывай счётчик в 0.

    Собственно всё. Все реле будут всегда включаться синхронно.
     
    arkadyf и Daniil нравится это.
  3. belllomoe

    belllomoe Нуб

    Спасибо за ответ. Интервалы взял равные для теста и подстройки на столе, в реальной работе придется делать не кратные интервалы. Но мысль вашу понял, спасибо!
    И еще вопрос. планирую сделать на два реле кнопки для увеличения или уменьшения времени, чтобы нажал кнопку "плюс" - время задержки увеличилось на 100мс, нажал "минус" - соответственно уменьшилось на 100мс. Допустим была задежка 2с, нажал и стала 2,1 сек., и так и сталось пока не отключишь питание. Как это лучше реализовать?
     
  4. Asper Daffy

    Asper Daffy Иксперд

    Они всё равно чему-нибудь, да кратны. Берёте в качестве базового интервала
    их наибольший общий делитель и делаете счётчики для всех (включая и первый).
    Да так и реализовать, увеличивать или уменьшать граничное значение счётчика, о котором я писал.
     
    Последнее редактирование: 27 фев 2020
    arkadyf нравится это.