Как выполнить код только 1 раз в цикле loop?
- Войдите на сайт для отправки комментариев
Пнд, 03/06/2019 - 12:42
Всем привет. Решил переделать автоматический освежитель воздуха. Идея такова, что после выключения света в туалете освежитель пшикает один раз и переходит в режим ожидания до следующего включения и выключения света. Для этого в схеме использовал фоторезистор и реле (потом заменю на транзистор), которое приводит в движение привод.
Так вот, я хочу, чтобы после выключения света, реле срабатывало только 1 раз (1 пшик), а затем переходило в режим ожидания.
Написал такой простенький код, однако после выключения света код в цикле loop не останавливается, реле, то включается, то выключается. Подскажите, пожалуйта, как реализовать эту затею? Спасибо!
const int photo = A0; const int motor = 13; int raw = 0; void setup() { pinMode( photo, INPUT ); pinMode( motor, OUTPUT ); } void loop() { raw = analogRead( photo ); if( raw < 500) digitalWrite( motor, HIGH ); delay(1000); digitalWrite( motor, LOW ); delay(1000); }
Например завести еще одну переменную-флаг и добавить в условие. Если флаг false - щелкаем реле и делаем флаг = true, после этого условие перестанет выполняться. Чтобы это все сработало в следующий раз при включении/выключении света придется добавить еще одно отдельное условие, которое будет делать флаг = false когда светло.
Изменил код с условием true/false, теперь реле срабатывает 1 раз как положено, но второй раз отказывается. После перезагрузки все повторяется. Подскажите, как включать реле подобным образом без перезагрузки?
while(analogRead( photo ) > 500){} //тормозим пока свет включен
while(analogRead( photo ) < 500){} //тормозим пока свет вЫключен
Эти строки (одну или две) нужно вставить в loop(). Пробуйте.
Подскажите, как включать реле подобным образом без перезагрузки?
Может... прочитать совет до конца ? :)
Изменил код с условием true/false, теперь реле срабатывает 1 раз как положено, но второй раз отказывается. После перезагрузки все повторяется. Подскажите, как включать реле подобным образом без перезагрузки?
чуть чуть не хватило, я думаю если бы расставили комментарии сами дописали как надо.
Спасибо большое! Все работает практически как надо. Вот только иногда случаются ложные срабатывания, все дело в отсутствии гистерезиса. Я думал, что проще всего в код, приведенный выше, добавить опрос фоторезистора не постоянно, а с задержкой, например, раз в 5 секунд. Delay не подходит, так как начинает тормозить другой код программы.
В интернете похожей реализации нигде не нашел (((
Такую сложную и редкую задачу в интернетах не рассматривают.
Значит добавить опрос будет сложно. А что если добавить задержку, (кроме delay), например, если свет включен более 5 секунд, то после выключения света, включить реле. Если менее 5 секунд, то ничего не делать.
... Delay не подходит, так как начинает тормозить другой код программы.
А вот про это в первом посте не было...
А вот про это в первом посте не было...
Сам участок кода с delay
меня устраивает. Хотелось бы добавить что то наподобие гистерезиса - опроса датчика раз в 5 секунд, а не постоянное((
Что подразумевается под гистерезисом?
Срабатывание реле не сразу после того, как значение датчика опустилось, например до 300. А если значение равно 300 и меньше в течение 5 сек, то включить реле. Если менее, то не включать. И наоборот.
Это я про свой пример выше - аналог delay()
Вот почти готовый пример. Попробуйте вставить в свой код. Название функции и переменных поменяйте.
Спасибо! Кстати, в моем коде вот эта функция считывает показания порта, к которому подключен фоторезистор:
И считывает постоянно, можно ли сделать опросы периодами? Например, те же раз 5 сек.
тока дай палец...
Спасибо! Кстати, в моем коде вот эта функция считывает показания порта, к которому подключен фоторезистор:
И считывает постоянно, можно ли сделать опросы периодами? Например, те же раз 5 сек.
Можно. Используйте millis()
делей надо искоренить!! когда же вы начнете использовать хотябы миллис вместо делеев!!
Долой delay() ! Хватит это терпеть ! :)
И считывает постоянно, можно ли сделать опросы периодами? Например, те же раз 5 сек.
Лучше сделать усреднение, но считывать и правда можно пореже.
както так на вскидку
ну или даже так
Жесть какая-то. ТС гистерезис не может даже в этом посте найти, как он в ваших скетчах-то разберётся...
if
( pMs1 + 5000UL <= cMs ){ pMs1 = cMs;
// срабатывает каждые 5 секунд
Щас шо будеть...))
ПЕРЕПОЛНЕНИЕ ! Всем в укрытие ! oO
:) :) :)
да, переполнение - а предложите свой вариант? )
Минуснуть противоположную сторону.
супер - и получить раз в 65 секунд переполнение миллеса... и глюк на следующие 65 сукунд (а то и на всегда до рестарта)
Уже попробовали ?
супер - и получить раз в 65 секунд переполнение миллеса...
Свидетели секты святого переполнения миилиса опять на форуме...
P.S. А вот нехер складывать, чтобы переполнения не было. Отнимать надо!
P.P.S. Обязательно к прочтению - http://arduino.ru/forum/programmirovanie/velikoe-perepolnenie-millis
Я в ней был, там хорошо :)
ок...
и что в итоге?... - код больше никогда не сработает
и что в итоге?... - код больше никогда не сработает
Обязательно к прочтению - http://arduino.ru/forum/programmirovanie/velikoe-perepolnenie-millis
и что в итоге?... - код больше никогда не сработает
Дак всё правильно. Название топика какое? "Как выполнить код только 1 раз в цикле loop". Всё в соответствии с требованиям.
вся разница в том, что переполнение 50 суток а не 65 секунд, ну перепутал с микрос...
читал я те изыскания и пробовал - лучше лишнее срабатывание , чем полный отвел....
и что в итоге?... - код больше никогда не сработает
Дак всё правильно. Название топика какое? "Как выполнить код только 1 раз в цикле loop". Всё в соответствии с требованиям.
ну да, но ему надо и "сброс" иметь, а не вечное зависание...
хотя можно и софтресет делать при выключении свет... asm("JMP 0");
ELITE - родолжаете блистать как знаток Си? :)
Запустите свой же код в ардуине и убедитесь, что переполнения нет
ну да, но ему надо и "сброс" иметь, а не вечное зависание...
Это требование противоречит основному . Придётся что-то одно выбрать.
Лучше аппаратный WatchDog - он надёжней.
Лучше аппаратный WatchDog - он надёжней.
ELITE - родолжаете блистать как знаток Си? :)
Запустите свой же код в ардуине и убедитесь, что переполнения нет
у меня уже пол года на аналогичном коде холодильник фурычит, и если бы он был не верный - то пивасик у еня был бы теплый уже на 2й месяц.... а шашлык протух бы
ок, тс пусь будет "правильное" ( cMs - pMs1 > 1000UL )
ок...
и что в итоге?... - код больше никогда не сработает
;)))))
какой зайчеГ!!!!
В твоем примере - 4 - 60 > 9(Sic!) и 5-60 и 6-60, все они больше 9 (по модулю 66). Неожиданно?
Прочти строчку выше столько раз, сколько нужно для просветления! Может быть тогда поймёшь, как работает вычисление простых операций в кАмпутере... ну там плюсик, минусик и т.п.
делей надо искоренить!! когда же вы начнете использовать хотябы миллис вместо делеев!!
Это элитный т.к. ради этих 4х строчек все и задумано :)
делей надо искоренить!! когда же вы начнете использовать хотябы миллис вместо делеев!!
теперь у нас появился "настоящий" искоренитель делеев, доказавший это собственными примерами.
и тут меня пугает слово "хотябы", что нас ждет в дальнейшем страшно подумать.
А что, Вы, хотели? Не кажный удостоился отдельного пункта (3), в "Песочнице".
а если рассмотреть хардовый вариант решения вопроса?
использовать несколько фотоэлементов + полевик и все это на ногу дога.
взять транзистор "попроще" Р-канальный с небольшим начальным напряжением открытия, открывать его примерно так, а после работы отправлять всю богодельню спать для экономии заряда батареи. еще, продают в китае очень интересные игрухи на солнечных батарейках, можно ее на ногу дога без транзистора...
тода весь код можно в луп закинуть, а просыпаться когда дог тяфкнет.
:))) ну мы же не ищем простых решений, а этот вариант жизнеспособный и интересный. ИМХО
Ух как тема разрослась)) Мне подсказали на другом форуме, что для добавления гистерезиса нужно всего лишь добавить простую строку (как ж я не смог догадаться!!), теперь все нормально работает:
Не хочу создавать новую тему. Поэтому хотелось бы поинтересоваться здесь. Как написать код, чтобы включалась блокировка времени повторного срабатывания пшика без delay? Например, зачем пшикать, если свет в туалете часто включается, почему бы не сделать блокировку минут на 10? Спасибо)
Писали вроде уже - через millis(). Запоминаете millis() в момент "пшика" в переменную t и ждете, когда millis() - 600000 > t, это условие можно добавить к raw >= 550,