Topic: Выполнение скрипта с задержками выполнения программы
Добрый день. В рамках реализации проекта удаленного управления водонагревателем, написал скрипт автовключения водонагревателя. Если включен переключатель ВКЛ.таймер и в поле ввода введено время и температура нагрева в формате HH:MM:TT - каждый цикл производится вызов одной из функций автовключения. Скриншот интерфейса ниже.
В теле функции schedule_func_ON() необходимо совершать несколько последовательных действий. Чтобы установить температуру нагрева, допустим с текущего значения 35 градусов на значение 75 градусов, нужно 9 раз замкнуть и разомкнуть реле temp_relay (первое замыкание - холостое, а далее температура меняется при нажатии с инкрементом 5 градусов). Каждое замыкание-размыкание реле имитирует нажатие человеком на кнопку на передней панели водонагревателя. После замыкания и размыкания необходимо на некоторое время остановить выполнение программы для того, чтобы реле успевало реагировать и не "залипало".
Когда я писал программу без использования remoteXY - просто использовал delay(). С RemoteXY использование delay() недопустимо, как понял из документации. Попробовал с пустым циклом while() - программа ведет себя не корректно. Видимо в силу той же причины - пока закончится несколько циклов while() - RemoteXY_Handler теряет связь.
В void loop() у меня уже есть задержки включения-выключения реле. Но там на каждое действие - свой условный оператор if. Поэтому программа работает по циклу корректно и без задержек. Пример ниже:
___________________________________________________________
if ((RemoteXY.button_1 !=0) && (millis() - button_1_time > 500))
// если кнопка нажата (состояние 1) и с момента последнего нажатия прошло не менее 500 мс (исключение многократного срабатывания при долгом нажатии на кнопку) выполняем код ниже
{
digitalWrite(ON_OFF_relay, LOW);
button_1_time = millis(); //актуализируем значение button_1_time
}
//через 200-300 мс после замыкания реле (может выполниться несколько раз за 100 мс) выполняем код ниже
if ((millis() - button_1_time > 200) && (millis() - button_1_time < 300))
{
digitalWrite(ON_OFF_relay, HIGH);
}
___________________________________________________________________________
А при выполнении описанного мной скрипта в функции schedule_func_ON() возникает проблема потому что я не могу вызывать эту функцию каждый цикл. Мне нужно вызвать ее единожды и выполнить код внутри функции.
Собственно вопрос в том, как можно такое реализовать, учитывая некоторые ограничения с использование задержек.
Ниже код. В функции schedule_func_ON() для простоты показан код только на 1 замыкание-размыкание реле.
________________________________________________________________________
void loop()
{
..........
if ((RemoteXY.switch_1 != 0) && (strlen(RemoteXY.edit_1) == 8)) //если переключатель таймера в положении ВКЛ и в строку таймера вписаны значения в формате HH:MM:TT - выполняем код ниже
{
if (ON_OFF_state == 1)
{
//вызов функции включения водонагревателя по расписанию с изначально включенным водонагревателем
schedule_func_ON();
}
else
{
//вызов функции включения водонагревателя по расписанию с изначально выключенным водонагревателем
schedule_func_OFF();
}
}
}
void schedule_func_ON()
{
int Hrs = (RemoteXY.edit_1[0] - 48)*10 + (RemoteXY.edit_1[1] - 48);
int Min = (RemoteXY.edit_1[3] - 48)*10 + (RemoteXY.edit_1[4] - 48);
int Temp = (RemoteXY.edit_1[5] - 48)*10 + (RemoteXY.edit_1[6] - 48);
//получаем данные от часов
get3231Date();
if ((Hrs == hours) && (Min == minutes))
//если настал "час X" - запускаем код ниже
{
Serial.println("Heater autoON operation start!!");
Serial.println("IDLE pressing of TEMP button");
Serial.print("Heat TEMP is: "); Serial.print(temp_state); Serial.println('°С');
digitalWrite(temp_relay,LOW); //замыкаем реле (замкнуто при LOW)
//бегаем в цикле while, пока не пройдет не менее 300мс
unsigned long relay_time = 0;
while (millis() - relay_time < 300)
{
}
relay_time = millis(); // актуализируем значение relay_time
digitalWrite(temp_relay,HIGH); // размыкаем реле (разомкнуто при HIGH)
//Чтобы реле успело произвести размыкание перед следующим замыканием
// (а у реле SRD-05VDC время release равно 5 мсек) - снова бегаем в цикле while 50 мсек
while (millis() - relay_time < 50)
{
}
}
__________________________________________________________________________________