Приветствую! Прошу совета. Сделал код для работы четырех реле, с задержками кратными секунде. Просто по сути подача 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);} }
Миллис - штука не самая точная. Она накапливает ошибку, потом её компенсирует. Вот и расползаются из-за компенсации, наверное. У тебя кратные интервалы, потому можно сделать очень просто: Оставь один интервал - самый маленький. Для остальных реле просто заведи счётчики срабатывания (изначально - нули). Когда интервал истёк. Переключай первое реле, а для второго увеличивай на 1 счётчик. Если он стал 2, то переключай реле и сбрасывай счётчик в 0. Для третьего увеличивай на 1 счётчик. Если он стал 3, то переключай реле и сбрасывай счётчик в 0. Для четвёртого увеличивай на 1 счётчик. Если он стал 4, то переключай реле и сбрасывай счётчик в 0. Собственно всё. Все реле будут всегда включаться синхронно.
Спасибо за ответ. Интервалы взял равные для теста и подстройки на столе, в реальной работе придется делать не кратные интервалы. Но мысль вашу понял, спасибо! И еще вопрос. планирую сделать на два реле кнопки для увеличения или уменьшения времени, чтобы нажал кнопку "плюс" - время задержки увеличилось на 100мс, нажал "минус" - соответственно уменьшилось на 100мс. Допустим была задежка 2с, нажал и стала 2,1 сек., и так и сталось пока не отключишь питание. Как это лучше реализовать?
Они всё равно чему-нибудь, да кратны. Берёте в качестве базового интервала их наибольший общий делитель и делаете счётчики для всех (включая и первый). Да так и реализовать, увеличивать или уменьшать граничное значение счётчика, о котором я писал.