LCD Screen Displaying Garbage When Printing/Writing Serial Data

Ok so this is one of my first big boy projects on arduino! and of course with that comes some issues I am not prepared for! so, I am trying to print serial data onto my lcd screen, specifically after a comma and before the next one, so that is a whole other issue I need to face later, but right now the issue is that when I try to display the serial data to the LCD screen it outputs this:

I have checked the serial monitor when it isnt displaying and, this is not what is on there

here is my code

#include <LiquidCrystal.h>

// Arduino Brain Library - Brain Serial Test

// Description: Grabs brain data from the serial RX pin and sends CSV out over the TX pin (Half duplex.)
// More info: https://github.com/kitschpatrol/Arduino-Brain-Library
// Author: Eric Mika, 2010 revised in 2014

#include <Brain.h>
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

// Set up the brain parser, pass it the hardware serial object you want to listen on.
Brain brain(Serial);
char val = ',';
void setup() {
    lcd.begin(16, 2); 
    // Start the hardware serial.
    Serial.begin(9600);
}

void loop() {
    // Expect packets about once per second.
    // The .readCSV() function returns a string (well, char*) listing the most recent brain data, in the following format:
    // "signal strength, attention, meditation, delta, theta, low alpha, high alpha, low beta, high beta, low gamma, high gamma"
    if (brain.update()) {
        Serial.println(brain.readErrors());
        Serial.println(brain.readCSV());
    }
   if (Serial.available()) {
    // wait a bit for the entire message to arrive
    delay(100);
    // clear the screen
    lcd.clear();
    // read all the available characters
    while (Serial.available() > 0) {
      // display each character to the LCD
      lcd.print(Serial.readStringUntil(val));
    }
  }
 
}

If you are unfamiliar with the brain library and what it is doing in this code, it is taking data from a mindflex toy (google if unfamiliar) and converting it to serial data, so I am pretty sure that block of code can be disregarded

Your image is not showing. How to post an image.

groundFungus:
Your image is not showing. How to post an image.

And use publicly accessible sites, which yours is not. :astonished:

thank you I will change that

Right, well, first thing is that the display is showing something so you appear to have the connections correct and code that is actually accessing the display.

So strip it back to a "Hello World" test example, and see if that prints correctly.

As to your current code, I see " lcd.clear();" as part of the direct loop() code. That is something that will have to be corrected later. :roll_eyes:

I have done that, It works, what is wrong with the lcd.clear();

The lcd.clear function is slow and can lead to screen flicker especially if done every time through loop(). Overwrite old data with spaces, reset the cursor position and print the new data and only update the screen when the data changes will help prevent flicker.

1 Like

thanks!!

I am trying to print serial data onto my lcd screen

What Serial data? What message from where?

Are you trying to parse the brain.readCSV() message?

groundFungus:
The lcd.clear function is slow and can lead to screen flicker especially if done every time through loop(). Overwrite old data with spaces, reset the cursor position and print the new data and only update the screen when the data changes will help prevent flicker.

Overwriting old data with spaces will still cause flicker. In fact it will likely be worse than using clear() on an AVR processor.
What causes flicker is erasing the characters before writing characters.
Using spaces still erases the characters on the display before updating them, which turns off the pixels that were there.
If you end up writing non space characters, particularly the same character to a position, the pixels were needless turned off then back on again.

Using the LiquidCrystal library in 4 bit mode on a 16Mhz AVR, a byte write to the display takes around 284 us.
284us x 17 characters to write full line (16 characters + 1 for set cursor position) is 4828 us. or just under 5ms.
That is 4.8ms of time wasted with the character position being blank vs a desired character.
The clear() command takes 2ms which is actually shorter than writing a 16 character line using the LiquidCrystal library.

Now if using the hd44780 library hd44780_pinIO class, the character time is only 91us on a 16mhz AVR.
which means writing a 16 character line takes 1547us or a bit over 1.5ms
So with the hd44780 library, writing 16 characters is faster than clear() while the LiquidCrystal library is slower than clear() - for a single 16 character line.
But with either library using clear() to erase the full screen is faster than writing spaces over the entire screen since clear() is 2ms and clearing the entire 16x2 display by writing spaces takes 9.66ms with the LiquidCrystal library and around 3ms with hd44780.

These numbers change if you jump up to a faster processor like the pic32, which can write a character to the display in 52us using the hd44780 library. (The liquidCrystal library is still slower than clear() at 238us per byte)

To remove as much flickering as possible, it is best to not clear the display and not clear a line by writing spaces, but rather format an entire line in a buffer, then write the buffer to the entire line on the display.
This avoids the issue and any time with blanked character positions as mentioned above.

3rd party cores like esp8266, teensy, and chipkit, have a printf() method in the Print class, so you don't' even have to use a buffer.
You can print nice a formatted full line to the LCD using lcd.printf() and skip having to create a local buffer.

--- bill

Thank you bperry! cattledog the data from the headset comes to the Arduino in the serial monitor

As I understand the brain library, all of the parsed values are available with these functions

// Individual pieces of brain data.
        uint8_t readSignalQuality();
        uint8_t readAttention();
        uint8_t readMeditation();
        uint32_t* readPowerArray();
        uint32_t readDelta();
        uint32_t readTheta();
        uint32_t readLowAlpha();
        uint32_t readHighAlpha();
        uint32_t readLowBeta();
        uint32_t readHighBeta();
        uint32_t readLowGamma();
        uint32_t readMidGamma();

I'm not certain how you want to display them on the lcd, but I would think that they would all be available with lcd.print(function you want to display). You have been given good advice about cursor management and how to overwrite.

I think you can have something like this

#include <LiquidCrystal.h>

// Arduino Brain Library - Brain Serial Test

// Description: Grabs brain data from the serial RX pin and sends CSV out over the TX pin (Half duplex.)
// More info: https://github.com/kitschpatrol/Arduino-Brain-Library
// Author: Eric Mika, 2010 revised in 2014

#include <Brain.h>
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

// Set up the brain parser, pass it the hardware serial object you want to listen on.
Brain brain(Serial);
char val = ',';
void setup() {
  lcd.begin(16, 2);
  // Start the hardware serial.
  Serial.begin(9600);
}

void loop() {
  // Expect packets about once per second.
  // The .readCSV() function returns a string (well, char*) listing the most recent brain data, in the following format:
  // "signal strength, attention, meditation, delta, theta, low alpha, high alpha, low beta, high beta, low gamma, high gamma"
  if (brain.update()) {
    Serial.println(brain.readErrors());
    Serial.println(brain.readCSV());
    lcd.setCursor(0,0);
    lcd.print("Sig Qual = ");
    lcd.print(brain.readSignalQuality());
    lcd.setCursor(0,1);
    lcd.print("Attention = ");
    lcd.print(brain.readAttention());
  }

  /*
     if (Serial.available()) {
      // wait a bit for the entire message to arrive
      delay(100);
      // clear the screen
      lcd.clear();
      // read all the available characters
      while (Serial.available() > 0) {
        // display each character to the LCD
        lcd.print(Serial.readStringUntil(val));
      }
    }
  */
}