Задержка включения и отключения реле
- Войдите на сайт для отправки комментариев
Всем доброго времени суток! При создании моего проекта появилась необходимость в реализации задержек при срабатывании реле. При превышение некоторого порога реле должно отключится с определенной выдержкой по времени, потом через некоторое время реле должно включится и если порог на отключения выше снова отключится и больше не реле не должно включится. Delay - здесь не подойдет. Потому что нужно постоянно снимать данные с датчиков и исключается возможность редактирования временных уставок из меню, что важно. Хотя с помощью delay удалось что то подобное, но не понимаю как сделать однократное включения реле. Вроде подходит функция millis, но она у меня почему то не работает, хотя компилируется и делаю вроде все правильно. Возможно тема не новая, но думаю уже несколько дней. Возможно у вас есть какие нибуть наработки или посоветуете библиотеки, которыми пользуетесь. Заранее всем спасибо. Часть скетча прикреплю ниже.
long timer1=3000;
long timer2=10000;
unsigned long timer;
void setup()
{
}
void loop()
{
if(Irms1 > Delta2 && millis() - timer >= timer1)
{
timer=millis();
digitalWrite (relay_pin, HIGH);
if(millis() - timer >= timer2)
{
timer=millis();
digitalWrite (relay_pin, LOW);
}
}
}
вас при прошлой регистрации на форуме не iliar звали?
по коду - обьясните, как он должен работать и что не устраивает в работе
Есть несколько условий, а реле сразу срабатывает по одному. Заведите переменные - флаги - и выставляйте убирайте флаги в зависимости от состояния системы. Только в одном месте - в подпрограмме - функции или отдельном куске loop проанализировав флаги включайте или выключайте реле. С помощью миллис и флагов можно одновременно следить за несколькими разными временными интервалами. С делеем такое не возможно.
Нет, я зарегистрировался впервые т.к. недавно начал учится работать с ардуино.
По коду не срабатывает задержка с millis, а точнее не включается реле. Хотелось бы узнать ещё как сделать однократное включение.
Впринципе вариант. Флаг состояния реле у меня есть, но используется не здесь. Получается нужно сделать во втором if добавить условие состояния реле?
Хотелось бы узнать ещё как сделать однократное включение.
заведите флаг, как вам выше сказали.
А что до вашего кода - он и не будет работать. потому что у вас второе условие миллис вызывается внутри первого. Это все равно что delay
А в первом if реально сделать задержку на подобии как в автоматических выключателях. Где ток превышает намного больше чем номинальный на некоторое время. Там необходимая задержка что бы не было лишних отключений?
А в первом if реально сделать задержку
все реально. Надо только внимательно подумать над примером "блинк без делей"
Делаете флаг превышения и проверяете ток. Если ток упал сбрасываете флаг и таймер. Повторное превышение запустит таймер с нуля.
Может это поможет
Oscar, функция millis() возвращает значение типа unsignet long, переменную timer Вы также определили как unsignet long, а переменные timer1 и timer2, участвующих в операциях и сравнениях с timer, Вы определили как long. Зачем это так?
А так веселее будет через 24 дня.
Переменные timer1 и timer2 я определил как long потому что их значение будет меняться в меню. Я думал сделать также как и для борьбы с дребезгом контактов. Функция та же, но реализовать нужно по другому.
А так веселее будет через 24 дня.
а почему через 24?
Переменные timer1 и timer2 я определил как long потому что их значение будет меняться в меню.
в чем логика? unsigned long в меню менять нельзя?
в чем логика? unsigned long в меню менять нельзя?
[/quote]
Возможно и можно, я ещё такого не делал. Я пробую разобраться с флагами, но не знаю как обнулить millis, судя по информации из сети это не просто.
А Вы из секты Обнуления Миллиса? С какой целью вступили в нее?
Делаете флаг превышения и проверяете ток. Если ток упал сбрасываете флаг и таймер. Повторное превышение запустит таймер с нуля.
Ваш способ я понял и он вроде рабочий. Но есть проблема, как сбросить таймер, ведь в сети однозначного решения я не нашел.
Обнулять миллис не надо. Достаточно флаг события обнулить-сбросить. Интервал проверять только при поднятом флаге. При установке флага запоминать миллис в переменной времени соответствующего события. Этим автоматически обнуляется таймер события. Это только один из вариантов. Дед давал ссылку на библиотеку таймеров. Работает отлично. Телодвижений меньше, чем выдумывать самому.
Да, я читаю сейчас что он умеет. Буду пробовать прикрутить его в свой код. Я напишу тогда что получилось.
не знаю как обнулить millis, судя по информации из сети это не просто.
этого просто не нужно делать
Здраствуйте. Вчера удалось добиться того что я писал когда создавал тему. Получилось благодаря библиотеке GyverTimer. Я так понял, что она похожа по принципу на ту что давал ссылку Дед. Также пришлось задействовать два флажка. Один на срабатывание защиты, а другой на срабатывания и блокировку повторного включения. Я пробивал по разному писать, но результата удалось добиться только так. Часть скетча прилагаю.
#include <GyverTimer.h> boolean flagAPV = 1; boolean flag = 0; GTimer myTimer(MS); GTimer myTimerAPV(MS); void setup() { pinMode(relay_pin,OUTPUT); myTimer.setInterval(3000); myTimerAPV.setInterval(5000); } void loop() { if(flag==0 && I1 > I2 && myTimer.isReady() ) { digitalWrite (relay_pin, HIGH); flag=1; myTimerAPV.start(); } else if ( I1 < I2) { myTimer.reset(); } if (flag==1 && flagAPV==0 && myTimerAPV.isReady()) { flag=0; flagAPV=1; digitalWrite (relay_pin, LOW); } }