LCD won't clear screen in if statement

I am trying to send a string over serial from my computer to my Arduino Uno. I can send data and have it print to my 16x2 LCD, but the lcd.clear() command doesn’t appear to work as I intended. Here is my short code:

#include <LiquidCrystal.h>

LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

char data[32] = {0};

void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);
}

void loop() {
  if (Serial) {
    if (Serial.readBytesUntil(';', data, 32) != 0) {
      lcd.clear();
      lcd.write(data);
      Serial.flushRX();
    }
  }
}

I know the wiring for the LCD is right, because I tried a simple sketch with the same pin initialization that simply displayed a string, waited a second, cleared the LCD, waited a second, then restarted the loop. This worked exactly as intended.

But in my code, the screen never clears, even though the data variable is written. So if I send “Hello, world!;” from the Serial Monitor, you see “Hello, world!” on the screen. But if I send “Bye!;” after that, what shows on the screen is “Bye!o, world!”. So clearly lcd.write() is being called, while lcd.clear() is being skipped over.

If anyone is wondering what Serial.flushRX() is, I just did as described here:
https://forum.sparkfun.com/viewtopic.php?f=32&t=32715#p162858

If I don’t do that, the first character, and one character after the last, is 4 horizontal lines with spaces between each, so obviously I need to clear the buffer. Even without Serial.flushRX() it still doesn’t clear the screen, so that’s not the problem.

The only thing I can guess is the problem, is flushRX() isn’t actually clearing the buffer, and so the old value remains, and is being partially overwritten with lcd.readBytesUntil().

Does anyone know why lcd.clear() won’t work for me here?

Thanks! :slight_smile:

Some of you may notice I post an awful lot of threads here… I really do try to get the answer on my own, it’s just all my life I’ve had problems understanding things, so often I miss something on my own.

I suspect the problem is actually that the data buffer isn't being cleared.

Fill the data buffer with 0's prior to the read, or set the data[readlength] = 0; after the read.

Is there an easy way to fill an array with zeros? And what do you mean by data[readLength] = 0? Do you mean the maximum possible bytes (32) or the number read in that instance?

void loop() {
  if (Serial) {
    byte readlen;
    if ((readlen = Serial.readBytesUntil(';', data, 31)) != 0) {
      data[readlen] = 0;
      lcd.clear();
      lcd.write(data);
      Serial.flushRX();
    }
  }
}

Note: the read size should be 1 last than the buffer size to leave space for the string null termination.

or, to zero the array:

void loop() {
  if (Serial) {
    memset(data, 0, sizeof(data));
    if (Serial.readBytesUntil(';', data, 31) != 0) {
      lcd.clear();
      lcd.write(data);
      Serial.flushRX();
    }
  }
}

Thanks! Using memset() works fine for me. :slight_smile:

Your welcome. It's not as efficient, and you may be clearing it every time through the loop, which is also not ideal, but it'll work.

Well, what if I do this?

void loop() {
  if (Serial) {
    if (Serial.readBytesUntil(';', data, 16) != 0) {
      if (!strcmp(data, "clear")) {
        lcd.clear();
      }
      else {
        lcd.clear();
        lcd.write(data);
      }
      Serial.flushRX();
      memset(data, 0, sizeof(data));
    }
  }
}

It works the same. That should only do memset() if something is sent over serial, right?

Yep. That’s better.

For safety, you should probably also do one in your setup() function as C++ does not guarantee setting variables to 0 (although embedded systems usually do it anyway), and you’ve only set the first element in the array to 0 in your constructor.

Really? I thought "char data[16] = {0};" made it all 0...

Well, I guess everything works now. :slight_smile: Thank you very much.

My C++ is a little rusty.

For global variables

char data[16];

with no initializers actually does initialize the elements with 0 (this is not true for local/automatic variable).

char data[16] = {0};

sets the first value in the array to 0 (all the other elements have already been initialized to 0).