LCD 1602: как заставить мигать текст или значение переменной?

wenom86
Offline
Зарегистрирован: 04.11.2012

Здравствуйте. В процессе написания программы столкнулся с проблемой. Нужно на экране 1602 сделать так, чтобы значение переменной, либо закоментированный текст, мигали. С операторами lcd.noBlink и lcd.blink добиться желаемого не смог. Может есть у кого какой либо скетч, где это работает?

Logik
Offline
Зарегистрирован: 05.08.2014

Да есть. Мигает но не на этих... алгоритм очевиден, пишем текст, ждем, очищаем место где текст, ждем и повторяем с начала. 

axill
Offline
Зарегистрирован: 05.09.2011

Аппаратно мигать может только курсор

а именно текст придется стирать-рисовать-стирать, но врядли это будет нормально смотреться

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Можно попробовать выделить буфер под текст, менять текст в буфере, а буфер постоянно выводить на дисплей. У DI HALTа так сделано в демке (правда там ассемблер и его RTOS), обновление экрана 5 раз в секунду. Искать строку "Быстрый старт. AVR"

 

keefa
Offline
Зарегистрирован: 19.06.2015

Я делал так. правильно или нет не знаю. но работает. правильность кода не проверял, написал в текстовом редакторе. показал просто вариант решения.

if (millis() -lastmillis >= 500){
i = !i;
}
set.cursor(0,0);
if (i == 1) {
lcd.print("значение");
}
if (i == 0){
lcd.print("        ");
}

 

wenom86
Offline
Зарегистрирован: 04.11.2012

большое спасибо за ответы. сегодня попробую.

wenom86
Offline
Зарегистрирован: 04.11.2012

Все получилось.  Мой рабочий пример. может кому пригодится.

long previousMillisTimeSW = 0; //счетчик прошедшего времени для мигания изменяемых значений.
long intervalTimeSW = 500;     //интервал мигания изменяемых значений.

if(currentMillis - previousMillisTimeSW >= intervalTimeSW)                //Если счетчик превысил интервал, 
{ i = !i; previousMillisTimeSW = previousMillisTimeSW+intervalTimeSW; }   //меняем значение переменной i, добавляем к переменной время интервала.


lcd.print("TEMPgarMIN="); 
   if (i == 1) {lcd.print(TEMPgarMIN); }
   if (i == 0){ lcd.print("   "); }

 

 

keefa
Offline
Зарегистрирован: 19.06.2015

wenom86 пишет:

Все получилось.  Мой рабочий пример. может кому пригодится.

long previousMillisTimeSW = 0; //счетчик прошедшего времени для мигания изменяемых значений.
long intervalTimeSW = 500;     //интервал мигания изменяемых значений.

if(currentMillis - previousMillisTimeSW >= intervalTimeSW)                //Если счетчик превысил интервал, 
{ i = !i; previousMillisTimeSW = previousMillisTimeSW+intervalTimeSW; }   //меняем значение переменной i, добавляем к переменной время интервала.


lcd.print("TEMPgarMIN="); 
   if (i == 1) {lcd.print(TEMPgarMIN); }
   if (i == 0){ lcd.print("   "); }

Зачем создавать переменную для хранения текущего времени? curentmillis, как я понимаю, всегда будет равна millis().

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Например для того, чтобы использовать эту переменную еще где нибудь

keefa
Offline
Зарегистрирован: 19.06.2015

kisoft пишет:
Например для того, чтобы использовать эту переменную еще где нибудь

Если мне нужно использовать текущее время, я использую millis(). без дополнительных переменных. Что я делаю не так? В чем я ошибаюсь? это не сарказм, в программировании новичек. Просветите.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Вопрос философский. Два вызова millis дадут два разных значения и чем дальше эти вызовы, тем больше разница. Иногда это может быть критично. Во вторых, считать значение из переменной быстрее, чем вызов millis. Разумеется все это зависит от задачи. Лично я предпочитаю читать millis в переменную и использовать ее в алгоритме, часто оно используется больше одного раза (сравнить и сохранить).

Logik
Offline
Зарегистрирован: 05.08.2014

keefa пишет:

kisoft пишет:
Например для того, чтобы использовать эту переменную еще где нибудь

Если мне нужно использовать текущее время, я использую millis(). без дополнительных переменных. Что я делаю не так? В чем я ошибаюсь? это не сарказм, в программировании новичек. Просветите.

Предпочтительней в начале лупа присвоить millis() переменной и затем использовать её а не вызовы. Однако этот подход дает преимущества только если луп крутится быстро, до десятков мс ну и программа достаточно сложная. Преимущества следующие: выше быстродействие (думаю понятно почему), однозначность прохождения цикла. На этом подробней. Допустим у Вас есть два временных интервала, 1 и 2 мс. Вы логично предполагаете, что за время второго интервала первый всегда будет отмерятся два раза и используете это свойство в программе. Так вот если для измерения времени использовать только один вызов millis() в начале а затем время брать из переменной то чудес нет, в каждом лупе будет одно из: не завершение ни одного интервала, или завершение только короткого или завершение обоих. При индивидуальных вызовах millis() возможен весь спектр вариантов например интервал 2мс завершился в данном цикле а 1мс - нет. И все ети варианты будут гулять, как бог на душу положет, по сложным закономерностям, но не случайным образом как может показатся сразу. Как результат - некоторые из них могут возникнуть очень редко при стечении совершенно левых обстоятельств, гдето прерывание подзадержало луп, где-то кнопку нажали не в тему. В результате этого программа попадет в состояние вызывающее ошибку. Причем по логике ошибка как бы связана с прерыванием или кнопкой, но возникает она в совершенно левом месте. Найти её даже для прожженого профи - задача сверхсложная. Потому проще соломки подстелить...

 ИМХО, правильный стиль - луп в начале цикла сохранить millis() (или  micros() для гарантировано сильно быстрых задачв глобальную переменную word, использовать ее в программе вместо millis() (или вместо micros() )  везде, кроме отладки. Почему word - быстрей, компактней и хватает.

keefa
Offline
Зарегистрирован: 19.06.2015

Logik, kisoft

Спасибо за разъяснение. я понял в чем разница. В общем оба варианта имеют право на жизнь, главное, правильно  и в нужном месте их применять.