Blink a single word on 16x2 LCD screen

I’ve been reading a few resources on how to get a single word to blink on an on a 16x2 LCD screen. Why? Just to bring attention to the screen. This example just does the blinking, I haven’t added any code to set ‘when’ that occurs as yet.

There have been a few previous questions about blink LCD text posted in the past, but it seems the most common answer was to write your own function.

The downside is that I wasn’t able to find a good reference custom function to do the blinking in my project. Some just cleared the whole screen, loosing the text I wanted to keep, others used the delay function and that halted the execution of other code (not included in this example).

This post is to ask for a quick review of my code, but also to possible act as a source for other people looking to do something similar. I’ve tried to use the state machine concept and utilise millis() for my interval measurement.

I’ll test this code on my Uno later tonight, but I wanted to ask if I’m using the array pointers and strlen() function correctly? The idea is to print the same number of blank characters as the original text being displayed.

In the code below, I’m outputting 2 lines of text to the LCD and I want just a single word to blink.
I may be very wrong for both of these thoughts: I figured it would be quicker to not redraw the entire display. I also didn’t want to use the lcd.clear() or delay(xxx); functions to keep this process efficient. (yes I know I’m not saving much, but on an Uno I’m always looking to save time wherever I can and hope it adds up in the greater project.

#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#define Blink_interval  500            // Set at top of source code file
unsigned long previousMillis = 0;
bool BlankOnOff = false;
int i = 0;
LiquidCrystal_I2C    lcd(0x27,2,1,0,4,5,6,7, 3,POSITIVE);

void setup() {
  lcd.begin (16,2); // for 16 x 2 LCD module
}

void BlinkText(char *msgtxt, int col, int row) {
  unsigned long currentMillis = millis();
  lcd.setCursor(col, row);
  if(currentMillis - previousMillis > Blink_interval)   {
    previousMillis = currentMillis;
    if(BlankOnOff){
      for(i = 1; i < strlen(msgtxt); i++) {
        lcd.print(" ");
      } //End For
    } // End If
    else {
      lcd.print(msgtxt);
    } //End Else
    BlankOnOff = !BlankOnOff;
  } //End If
} // End BlinkText
 

void loop() {
  BlinkText("Limit:", 0, 0);
  lcd.setCursor(8, 0);
  lcd.print("RNGValue");
  lcd.setCursor(0, 1);
  lcd.print("Alert message");
   // Other code stuff goes here
}

edit: Yay! just tested it and it works.

Without reading your full post.

Use the lcd.cursor positioning commands - and refresh 'that word' as often as you need to flash.
Keep a global or static boolean toggle state, then
Each alternate time - write 'WORD" or "....."

Use millis() for your timing - then the rest of your program can run happily in the foreground.

lastchancename:
Without reading your full post.

Use the lcd.cursor positioning commands - and refresh 'that word' as often as you need to flash.
Keep a global or static boolean toggle state, then
Each alternate time - write 'WORD" or "....."

Use millis() for your timing - then the rest of your program can run happily in the foreground.

And for your edification and future programming. For programs that must wait for a long period of time before doing something obvious, I did the same coding, but pick an unused place on the LCD to display a period, "." and blink that on and off at a 1 second interval. Then the user/operator is reassured the program is running properly.

Years ago I called that display a "passifier". Helps me to, sometimes.

Paul

Heartbeat or Activity indicator.
Almost every project I build has a LED somewhere - often as a hangover from the very first stages of code development!

lastchancename:
Heartbeat or Activity indicator.
Almost every project I build has a LED somewhere - often as a hangover from the very first stages of code development!

It's too bad that we don't live in a world in which you can just have faith that the bloody thing is working and not need reassurance.

The world does work pretty reliably - assuming the hardware is built up properly.
The issue is the human on the other end of the compiler!
We are not sominfallible.
I certainly use that LED, and it helps reassure customers - a short blink every second or so, to say I’m alive and OK,

lastchancename:
I certainly use that LED, and it helps reassure customers - a short blink every second or so, to say I’m alive and OK,

Not "no news is good news"?

odometer:
Not "no news is good news"?

I hope you're kidding.

No LED at all could easily mean the power has failed, or processor has locked up with the security doors wide-open.
At least (if you trust your code that much), implement the WDT to restart and hopefully not fall into the same crash condition - if there's power.

lastchancename:
Without reading your full post.

Use the lcd.cursor positioning commands - and refresh 'that word' as often as you need to flash.
Keep a global or static boolean toggle state, then
Each alternate time - write 'WORD" or "....."

Use millis() for your timing - then the rest of your program can run happily in the foreground.

Yeah - I think not reading the full post kind of made your post redundant. I had already had millis() in the example code and doesn't lcd.cursor() just show the underline? Not sure how that fits into your idea of blinking an entire word. I've not seen that use - do you have any example code?

Overnight - I did make some adjustments to the BlinkText routine. I badly coded it to write to the LCD for every individual space required for the word I wanted to blink. That seemed quite inefficient

I've since modified it to store the length of spaces into a String and then send a single lcd.print with that string to the display.

At work at the moment, but I'll post the revised code later tonight.

dougp:

lastchancename:

Could we keep the political comments out of this thread before it gets more derailed than it already is?

There is a General Discussion area on the forum where you can discuss things like that or if you are looking for a soapbox. I’m not in the US, nor care about the latest happenings of its political system.

Getting back on topic: The question was about the code I posted and if I could make any efficiencies through functions I may not be aware of.

Alternatively, does anyone have an alternative LCD function they’d like to share to blink a single word? (doesn’t refresh the entire screen)

I just had a look at your code that works - and it seems fine.
Not much in the blinkenlights function that I’d change at first glance.

It works as you want - and that’s a big plus.

I've since modified it to store the length of spaces into a String and then send a single lcd.print with that string to the display.

Do you really mean String (capital S) ? If, why ?

One change that I would make is not to move the cursor to the required position unless it is time to change the text

UKHeliBob:
Do you really mean String (capital S) ? If, why ?

One change that I would make is not to move the cursor to the required position unless it is time to change the text

Ah good point on the cursor… it’s outside the ‘if’ statement. I’ve moved that inside the IF.

I vaguely know there is a cost with Strings when using Arduino, but I’ve not investigated that cost yet, so this is coded in ignorance of that sorry. It’s on my list of stuff to learn and work ways around it / understand the trade-offs.

Here’s the amended code so far. Thanks for the feedback from all.

#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#define Blink_interval  500            // Set at top of source code file
unsigned long previousMillis = 0;
bool BlankOnOff = false;
String blnk = "";

LiquidCrystal_I2C    lcd(0x27,2,1,0,4,5,6,7, 3,POSITIVE);

void setup() {
  lcd.begin (16,2); // for 16 x 2 LCD module
}


void BlinkText(char *msgtxt, int col, int row) {
  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis > Blink_interval)   {
    lcd.setCursor(col, row);
    previousMillis = currentMillis;
    
    if(BlankOnOff){
      lcd.print(msgtxt);
    }
    else {
      //for loop creates a String of spaces same length as word specified
      for(int i = 1; i <= strlen(msgtxt); i++) {
        blnk += " ";
      }
      lcd.print(blnk);
      blnk="";  //need to reset this back to blank otherwise it'll keep adding spaces to it on next iteration.
    }
    BlankOnOff = !BlankOnOff;
  }
}
 

void loop() {
  BlinkText("Limit:", 0, 0);
  lcd.setCursor(8, 0);
  lcd.print("RNGValue");
  lcd.setCursor(0, 1);
  lcd.print("Alert message");
   // Other code stuff goes here
}

wile1411:
I vaguely know there is a cost with Strings when using Arduino, but I’ve not investigated that cost yet, so this is coded in ignorance of that sorry. It’s on my list of stuff to learn and work ways around it / understand the trade-offs.

there are only trade-ups when using C strings over String class. Try something like this:

void BlinkText(char *msgtxt, int col, int row) {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis > Blink_interval)   {
    lcd.setCursor(col, row);
    previousMillis = currentMillis;
    if (BlankOnOff) {
      lcd.print(msgtxt);
    } else {
      //for loop creates a string of spaces same length as word specified
      char spaceBuffer[strlen(msgtxt) +1] = "";
      for (int i = 0; i < strlen(msgtxt); i++) {
        strcat(spaceBuffer, " " );
      }
      lcd.print(spaceBuffer);
    }
    BlankOnOff = !BlankOnOff;
  }
}

BulldogLowell:
there are only trade-ups when using C strings over String class. Try something like this:

That works too - I'll use that now, but have it on my research list as to why it's better. I know it saves a String variable, so that's got to be good. Thanks!