Заменить delay на millis()
- Войдите на сайт для отправки комментариев
Хочу в коде заменить delay на millis(). Не понимаю, почему не работает. Код можно разделить на 2 блока. один выполняется при помощи delay, а второй я хочу выполнить при помощи millis. Задача на LED дисплее написать, какая кнопка нажата. Проблема в том, что без задержки запись сразу пропадает. В следствии появляется задержка в 1 секунду.
Мое понятия написанного мной кода в том, что как только срабатывает положительное значение, то на дисплей выводится надпись. Она там будет написана, пока не сотрется. Стирание происходит при помощи millis. Я создал интервал времени в 1 секунда, далее millis приравнивается к значению к прошлому значению. Если интервал закончился, то выполняется стирание надписи. блок заканчивается. начинается новый цикл.
void loop () if (val < 20) // если значение val меньше 20, то выполняется задача { lcd.setCursor (5,1); // отображается на дисплее на второй линии на 6 символе начинается моя надпись lcd.print ("Right"); // отображается информация if (millis() - last_time > 1000) //интервал в 1 секунду last_time = millis(); // следствия условия lcd.clear(); //следствия условия } if (val > 120 && val < 150) { lcd.setCursor (7,1); lcd.print("UP"); delay (1000); lcd.clear (); }
После какого события нужно начинать отсчитывать миллисекунды?
Приведите скетч целиком
sadman41, давайте, наконец требовать выкладывания полного кода! Иначе опять будет как в соседней теме - все бедного новичка обижают.
Строка 6 и 7 надо:
А то у вас получается - сколько будет дважды два - сорок учитель, нет 7-8 где-то так, но не сорок жеж )))
sadman41, давайте, наконец требовать выкладывания полного кода! Иначе опять будет как в соседней теме - все бедного новичка обижают.
Слушаю и повинуюсь.
После какого события нужно начинать отсчитывать миллисекунды?
отсчет миллисекунд должен начаться после нажатия на кнопку. Соответсвенно после того, как условие if (val < 20) стало верным. 11 строчка
я выложил почти полный код.
Строка 6 и 7 надо:
А то у вас получается - сколько будет дважды два - сорок учитель, нет 7-8 где-то так, но не сорок жеж )))
Я понимаю строку 6 и 7 так.
Начинает функция millis, идет отсчет. Изначально last_time = 0. как только millis() - last time стал больше 1000.
last_time = millis(). Это значит, что last_time стал равен 1000. и дальше millis() - 1000, где millis уже 1001. По сути строка ничем не отличается от Вашей.
При условии, что я правильно все понимаю.
я выложил почти полный код.
Ну, а Вам почти помогли разобраться.
отсчет миллисекунд должен начаться после нажатия на кнопку. Соответсвенно после того, как условие if (val < 20) стало верным. 11 строчка
Ваша val, в строке №3 получает значение 0 и больше нигде и никогда не изменяется. Она всегда < 20. Это нормально? Так и задумывалось?
Извините, пожалуйста, в коде пропущена одна самая важная строчка. Добавил строку 10. значение val считывается при помощи аналогового входа. Исходя из этих данных я могу определить, какая кнопка нажата и какую информацию мне нужно выводить на дисплей. Далее я пишу информацию на дисплее, которая сама по себе не стирается. Остается написанной пока не будет дана команда стереть или будет дана команда написать поверх этой надписи.
Соотвественно, проблема состоит в том, что бы стереть надпись через интервал времени 1 секунду. При помощи delay у меня нет никаких проблем, но это в корне не правильно и я написал альтернативу при помощи millis().
ардуина мега?
по видимому оно стирается и тут же выводится вновь, так написано по крайней мере
а так?
После какого события нужно начинать отсчитывать миллисекунды?
отсчет миллисекунд должен начаться после нажатия на кнопку. Соответсвенно после того, как условие if (val < 20) стало верным. 11 строчка
Окей, тогда почему после того, как условие стало верным, в переменную last_time не помещается кол-во мс?
Вам нужно для начала сделать для двух кнопок следующее: определили, что кнопка нажата, запомнили в какой момент была нажата, вывели что-то на экран. Лишнее пока убрать. Пусть временно будут наслоения.
Окей, тогда почему после того, как условие стало верным, в переменную last_time не помещается кол-во мс?
Вам нужно для начала сделать для двух кнопок следующее: определили, что кнопка нажата, запомнили в какой момент была нажата, вывели что-то на экран. Лишнее пока убрать. Пусть временно будут наслоения.
Верно. Я сейчас осознал 1 ошибку. нажатие на кнопку может быть в любой момент и у меня не было точки отсчета. Я исправил.
Я хотел бы разобраться на 1-ой кнопке, потому что с остальным у меня уже не будет проблем. Вторая кнопка оставлена только для того, что бы Вы могли бы понять, какая стоит задача, провести аналогию.
Исправленный код. Я фиксирую момент нажатия кнопки.
В таком варианте у меня надпись появляется на дисплее сразу после нажатия. Надпись все время отображается. Можно только поверх нее что-то написать.
Далее я добавляю условие millis(). По истечению 1 секунды дисплей очищается.
По моему пониманию, дальше как только условие времени становится истиной, следует команда - очистить дисплей, но на практике символы не успевают отображаться, сразу же стираются.
Я для проверки использую симулятор Arduino UNO на сайте Tinkercad.com. Может с этим можем быть проблема. Хотя лампочками моргать при помощи millis() там получилось.
Я вам не зря про две кнопки написал. Это ключевой момент для понимания.
вот такой таймер постоянно раз в интервал делает выражение в фигурных скобках:
а вот такой делает один раз, спустя интервал после того момента, как вы его запускаете
запускаем таймер так
Соответственно вам нужен второй вариант. Запускать таймер после определения, что кнопка нажата. В фигурных скобках таймера сделать очистку экрана.
Макс, ты только полностью не вываливай код. Человек же понять должен, а не списать бездумно.
ок, не буду. Пусть мозг тренируется, хотя иногда по комментам лучше понять можно.
вот такой таймер постоянно раз в интервал делает выражение в фигурных скобках:
а вот такой делает один раз, спустя интервал после того момента, как вы его запускаете
запускаем таймер так
Соответственно вам нужен второй вариант. Запускать таймер после определения, что кнопка нажата. В фигурных скобках таймера сделать очистку экрана.
Может я что-то не правильно понимаю или упускаю что-то, но в моём случае условие millis() выполняется всего 1 раз, потому что условие millis() вызывается оператором IF, что кнопка нажата. Если кнопка не нажата, то условие millis() никогда не будет выполняться. Это следует из строки if (val > 100). Дальше фигурные скобки, которые при TRUE должны выполниться и при FALSE пропустить или выполнить ELSE.
Это я не к тому, что бы ничего не делать, а просто хочу разобраться. У меня теперь появилось понимание, как сделать цикл с повторением в 1 раз.
а при не нажатой кнопке какое значение val?
дак в том то и дело - нужно чтобы ваш таймер тикал, когда вы уже отпустили кнопку. Поэтому в условии нажатия кнопки вы только его запускаете, а тикает он в loop(). Когда кончается - очищаете дисплей и выключаете таймер.
Спасибо за помощь. Осознал, что оператор if millis исполняется только в тот момент пока нажата кнопка. Получился такой рабочий код. Возможно там есть ошибки, которые стоит исправить.
Теперь просто засекайте время во всех случаях обнаружения нажатия кнопок. Блок "тушения", расположенный таким образом, как сейчас, сработает для всех.
Ну, и для скорости, clear() делать не стоит. Лучше запечатать строку пробелами. На физическом LCD разница будет видна невооруженным глазом.
Теперь просто засекайте время во всех случаях обнаружения нажатия кнопок. Блок "тушения", расположенный таким образом, как сейчас, сработает для всех.
Ну, и для скорости, clear() делать не стоит. Лучше запечатать строку пробелами. На физическом LCD разница будет видна невооруженным глазом.
Допустим мне надо было бы стирать надпись А через 1 секнкдк, а надпись Б через 2. В таком случае я бы поменял условия вызова таймера. В 1 секунде вызывал бы flag = 1, в 2 секундах timer = 1 , это правильное решение задачи или можно лучше?
вместо цифры 1000 введите переменную. И в ифе нажатия каждой кнопки впишите какой таймаут вам нужен и нафига delay то остался в строке 33 ?
В данном варианте обе надписи удаляются через 1 секунду. Возможно я допустил ошибку в знаках. Выходит так, как говорил Sadman, поэтому я уточнил. Что бы у надписей были разные времена, мне тогда надо использовать дополнительный запуск другого "таймера". Соответственно, правильное ли это.
А где :
вместо цифры 1000 введите переменную. И в ифе нажатия каждой кнопки впишите какой таймаут вам нужен
?
вместо цифры 1000 введите переменную. И в ифе нажатия каждой кнопки впишите какой таймаут вам нужен
Допустим мне надо было бы стирать надпись А через 1 секунду, а надпись Б через 2. В таком случае я бы поменял условия вызова 2 таймеров. В 1 секунде вызывал бы flag = 1, который отвечал бы за таймер в одну секунду. В 2 секундах timer = 1, который отвечал бы за 2 секунды. Это правильное регулирования таймаута, который мне нужен или можно лучше?
Пример.
Второй вариант, который я смог придумать, задумавшись над вашей идеей такой.
Естественно - #2.
Только переменная 'а' должна быть того же типа, что и остальные, в которых миллисекунды хранятся.
Огромное спасибо за оказанную помощь и наставления Sadman41 и MaksVV. Премного благодарен за уделенное теме время. Еще раз спасибо.