Зона видимости millis()
- Войдите на сайт для отправки комментариев
Вс, 13/04/2014 - 02:07
Есть простейший код:
const int kontroller = 13; int altonika = 5; unsigned long currentMillis; long preMillis = 0; void setup() { pinMode(kontroller, OUTPUT); pinMode(altonika, INPUT); } void loop() { if (digitalRead(altonika) == LOW) { currentMillis = millis(); digitalWrite(kontroller, HIGH); if(currentMillis - preMillis > 5000) { preMillis = currentMillis; digitalWrite(kontroller, LOW); } } }
Суть - когда нет сигнала на выходе датчика "Альтроника" должен появиться сигнал на выходе "5" на 5 секунд. На выходе 5 должна быть единица всегда, если сигнала с датчика нет. С момента каждого пропадания сигнала, должен быть сигнал на выходе 5, отсчитываться заново. Поэтому delay не вариант.
Но код не работает, так как во втором условии не видится переменная currentMillis из первого условия. Как быть?
А почему не
unsigned long currentMillis = 0;
unsigned long preMillis = 0;
?
У вас логика нарушена, сами посмотрите на свой код внимательно
по идее должно заработать как надр если второй if вынести из под первого, т.е. Поднять на один уровень выше по вложенночти, на цровень самого loop
Нет, ни первое, ни второе не помогло. А вот если currentMillis = millis(); вынести из первого условия, тогда код работает и параметр currentMillis виден во втором условии, и оно выполняется. Но мне нужно чтоб время начинало отсчитываться по условию - с момента пропадания сигнала.
У Вас условия немножко противоречивые:
"При пропадании сигнала включаем LED на 5 секунд"
"С момента каждого пропадания сигнала, должен быть сигнал на выходе 5, отсчитываться заново."
То есть, если сигнал появился через секунду - таймаут сбрасываем? А если сигнал не появился и после пятой секунды - это как считать: новый тамаут, или старый?
Вложенность if-ов тут, на мой взгляд, действительно не нужна. Один if определяет наличие сигнала с датчика и взводит таймер и LED (а если таймер уже взведен: не равен нулю - не делает ничего), а второй - проверяет не истек ли таймер и гасит лед (и обнуляет таймер) по его истечению.
Я понял о чём Вы. Но этот код не работает:
Тут два отдельных условия, но я не могу понять, почему строка currentMillis = millis(); из первого условия, не видится во втором условии. Если её вынести уз условия и поместить в loop, то во втором условии она обнаруживается и условие срабатывает. Но мне нужно запускать отсчёт по собитию.
Навтыкайте отладочных принтов до и после цикла if-а. Есть подозрение, что
currentMillis внутри if и снаружи - просто разные, хотя объявлена только одна...
Sirocco, работать с событиями удобно по флагам, я бы сделал примерно так:
Какая то ерунда. Во-первых millis не идёт пока нет условия, Serial.println выводит одно и тоже значение, и нарастает только когда условие есть, Во-вторых он не обнуляется по достижению значения описанного в условии 2.
P.S. не к предыдущему сообщению написано.
Sirocco, работать с событиями удобно по флагам, я бы сделал примерно так:
Этот код работает. Спасибо! Но не совсем правильно. Если событие наступило, выполняется условие и на 5 сек зажигается пин 13. Но если в течениие этих пяти секунд поступил снова сигнал, скажем на четвёртой секунде и пропал до истечения пяти секунд, то время не продляется. А должен начинаться отсчёт заново с каждого сигнала, при этом не гася выход.
Пытаюсь разобраться в вашем коде.
upd---------------------------------
Разобрался. Просто убрал проверку && !start5sec из первого условия. В итоге рабочий код такой:
Всем огромное спасибо!