Помогите реализовать "каскадное" включение реле.
- Войдите на сайт для отправки комментариев
Всем здравствовать!
Помогите, пожалуйста, написать код для каскадного включения реле. Суть вот в чем:
Имеем 4 реле - r1, r2, r3, r4. Сидят на пинах с А0 по А3, соответственно в коде с 14 по 17-й пин. Необходимо их включение (подачи управляемого напряжения) в следующем порядке:
1. Ожидаем 20 минут (настраивается от 10 мин до 40 мин с шагом 1 мин)
2. Включаем реле 1 на время t1 (настраивается от 0,5 сек до 5,0 сек с шагом 0,5 сек
3. Если после включения реле1 прошло время t1 - t2 (t2 фиксированное 1 сек), включаем реле 2 (то есть работают 2 реле (1 и 2))
4. По завершению времени t1 выключаем реле 1 , реле 2 остается включенным на время t1
5.Если после включения реле2 прошло время t1 - t2 , включаем реле 3 (то есть работают 2 реле (2 и 3))
6. и т.д.
Ниже приведена простенькая диаграмма включения реле.
Вот такой код для двух реле (нужно 4)
#define r1 = 14; // Реле 1 А0
#define r2 = 15; // Реле 2 А1
#define r3 = 16; // Реле 3 А2
#define r4 = 17; // Реле 4 А3
int tint = 20; // В минутах!! Настраивается с 10 мин
//до 40 мин с шагом 1 мин.
int t1 = 2000; // В миллисекундах, настраиваемое с 500 мсек
//до 5000 мсек с шагом 500 мсек
int t2 = 1000; // В миллисекундах фиксированное 1000 мсек
unsigned long t0 = 0; // Вспомогательная переменная
void setup() {
pinMode(r1, OUTPUT);
pinMode(r2, OUTPUT);
pinMode(r3, OUTPUT);
pinMode(r4, OUTPUT);
t0 = millis();
}
void loop () {
if (millis() - t0 > tint * 60000) {
while (millis() - t0 < t1) {
digitalWrite (r1, HIGH)
if (millis() - t0 >= t1 - t2) {
digitalWrite (r2, HIGH);
}
}
digitalWrite (r1, LOW);
t0 = millis();
while (millis() - t0 < t1) {
digitalWrite (r2, HIGH)
if (millis() - t0 >= t1 - t2) {
digitalWrite (r3, HIGH);
}
}
digitalWrite (r2, LOW);
t0 = millis();
while (millis() - t0 < t1) {
digitalWrite (r3, HIGH)
if (millis() - t0 >= t1 - t2) {
digitalWrite (r4, HIGH);
}
}
digitalWrite (r3, LOW);
t0 = millis();
while (millis() - t0 < t1) {
digitalWrite (r4, HIGH)
}
digitalWrite (r4, LOW);
t0 = millis();
}
}
Да, я понимаю, что код рабочий, но выглядит уж очень топорно. Возможно ли улучшение его вида, что ли? Пробовал прикрутить цикл for.., но там беда с переменными..
В общем выручайте, братцы!

Немного ошибся.. Там код для 4-х реле. И в диаграмме неточности, но суть верная.
А делеи отменили? Результат тот же, только компактнее.))))
А делеи отменили? Результат тот же, только компактнее.))))
А функции?)
Лучшее враг хорошего )))
А делеи отменили? Результат тот же, только компактнее.))))
Нет, не отменили. Но, к сожалению, есть необходимость изменения t1. Да и дилэй не по фэн-шую, говорят..
С этим не поспоришь.. Но всё же думаю тут можно оптимизировать код так, чтобы он стал компактнее. Хотя вот вопрос нужно ли, если итак работает?..
А делеи отменили? Результат тот же, только компактнее.))))
А функции?)
Вот-вот.. Функции изменять нужно.
Хм.. А если написать,
Работать будет?
Да и дилэй не по фэн-шую, говорят..
Так ваши, зависшие циклы, от него ничем не отличаются.))))
Развернуть весь цикл с квантом в одну секунду и оформить через иф или свич условия. И просто и ничо низависает.
похоже что решение через автомат от ТС далековато.
Кстати да, автомат там вообще красивый получится в виде одной функции. Вызывать по таймеру раз в секунду.
Секундный таймер Дед сегодня кому-то уже подарил.
Развернуть весь цикл с квантом в одну секунду и оформить через иф или свич условия. И просто и ничо низависает.
Благодарю! А можно поподробнее. Хотя бы в общих чертах.
Кстати да, автомат там вообще красивый получится в виде одной функции. Вызывать по таймеру раз в секунду.
Вот это мне и нужно! Всё свести к одной функции, но что то додуматься никак не могу. Просто ступор какой то ((
Секундный таймер Дед сегодня кому-то уже подарил.
А можно ссылку?
Секундный таймер Дед сегодня кому-то уже подарил.
А можно ссылку?
Думаю, тебе пока не поможет, но на https://github.com/DetSimen/Arduino_TimerList
Секундный таймер Дед сегодня кому-то уже подарил.
А можно ссылку?
Думаю, тебе пока не поможет, но на https://github.com/DetSimen/Arduino_TimerList
Благодарю! Именно оно, что и нужно было. Мы (с котом) уже разобрались и переделываем код.
с 1 таймером реле с А0 по А3 включаются последовательно на 2 секунды. Без сдвига. Добавив второй таймер, можно включать их по очереди, со сдвигом, только я с утра не сабражаю ничо, может быть пожже. А мошт и сам дагадаешь.
/* Name: RelayTest.ino Created: 03.03.2020 8:35:57 Author: DtS */ #include <Arduino.h> #include <TimerList.h> extern TTimerList TimerList; const uint8_t MIN_RELAY_PIN = 14; // А0 const uint8_t MAX_RELAY_PIN = 17; // А3 const uint32_t t1_ms = 2000; // время включения реле 2 сек (2000 мс) uint8_t CurrentRelay = MIN_RELAY_PIN; THandle hT1Timer = INVALID_HANDLE; void tmrT1Ends(void) { digitalWrite(CurrentRelay, LOW); // Выключается текущее реле CurrentRelay++; // Текущим становится следующее реле if (CurrentRelay > MAX_RELAY_PIN) CurrentRelay = MIN_RELAY_PIN; // или первое digitalWrite(CurrentRelay, HIGH); // включается текущее реле Serial.println(CurrentRelay); } // А если нада, чтоб реле сработали паочереди и остановились, тогда по другому void tmrT1Ends_v2(void) { digitalWrite(CurrentRelay, LOW); // Выключается текущее реле CurrentRelay++; // Текущим становится следующее реле if (CurrentRelay <= MAX_RELAY_PIN) digitalWrite(CurrentRelay, HIGH); // включается текущее реле else TimerList.Stop(hT1Timer); // или останавливается таймер } void setup() { Serial.begin(115200); delay(250); Serial.println("Application started."); digitalWrite(CurrentRelay, HIGH); // включаем первое реле hT1Timer = TimerList.Add(t1_ms, tmrT1Ends);// и взводим таймер на t1_ms миллисекунд } void loop() { }Не хочу быть навязчивым, но возможно вам стоит попробовать PLC?
Дёшево и сердито, как раз для дилетантов типа меня:
http://arduino.ru/forum/obshchii/interesnoe-na-aliexpress-i-ebay-chast2?...
Да, спасибо. Это интересно. Только вот сейчас с алиэкспрессом совсем беда. Они не отправляют посылки из-за этого их вируса.
Ещё вопрос. Не совсем понятно как программируются эти реле? В каком то специальном софте?