Need help with displaying Serial Monitor onto LCD Screen

Hello! So, I need some help with displaying what my Serial Monitor says onto my LCD screen. Every time I do it, it does display on my LCD screen, it's just that instead of displaying the proper letters, it shows random letters (not symbols, just letters), and also the incorrect numbers. I'm completely new to Arduino, and I'm doing this for a school project that's due tomorrow (very terrible time to do this, I know). I'm practically done with my school project, this is the last thing I need to do.

I'm using example code from the MH-Z CO2 Sensors library, and modifying it a little bit. The code displays perfectly fine when untouched (on the Serial Monitor). I've been reading up on other forums, but nothing's helped me as much. Please let me know if I need to display the code!

By the way, I'm using an Arduino Uno R3 (in case you needed to know).

Yes that would definitely help. To do that, start a reply, press a Return key to start a new paragraph, click the CODE icon in the toolbar that appears above your reply text (picture below) then paste the code.

It will look like this:

#include <LiquidCrystal_I2C.h>

  // LCD Initialization

lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Hello");

… etc.

Until then all we can do is guess, but I happen to know lcd.print("Hello"); won’t do anything useful unless lcd.init(); is called first.

I am pretty new to the Arduino too, but I have been doing lots of things with that popular two line LCD display, so it’s fresh in my mind and I’d love to help you.

Ah, okay! Thanks!

#include <SoftwareSerial.h>
#include <MHZ.h>
#include <LiquidCrystal.h>

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

// pin for pwm reading
#define CO2_IN 10

// pin for uart reading
#define MH_Z19_RX 4  // D7
#define MH_Z19_TX 0  // D6

MHZ co2(MH_Z19_RX, MH_Z19_TX, CO2_IN, MHZ19B);

void setup() {
  Serial.begin(9600);
  pinMode(CO2_IN, INPUT);
  delay(100);
  Serial.println("MHZ 19B");

  // enable debug to get addition information
  // co2.setDebug(true);

  if (co2.isPreHeating()) {
    Serial.print("Preheating");
    while (co2.isPreHeating()) {
      Serial.print(".");
      delay(5000);
    }
    Serial.println();
  }
}

void loop() {
  Serial.print("\n----- Time from start: ");
  lcd.print(millis() / 1000);
  Serial.println(" s");


  int ppm_pwm = co2.readCO2PWM();
  lcd.print("PPMpwm:");
  lcd.print(ppm_pwm);

  Serial.println("\n------------------------------");
  delay(5000);
}

In the original code, there was UART and some temperature thing, but the PPM is the only one that really works so I'm focusing on that (I deleted the other two).

Assuming this is the correct library: https://docs.arduino.cc/libraries/liquidcrystal/

… then you have to add the line lcd.begin() before it will do anything.

From the above, it “Initializes the interface to the LCD screen, and specifies the dimensions (width and height) of the display. begin() needs to be called before any other LCD library commands.

(I added the boldface)

Try this. I only added the few lines with ***** characters in the comments.

#include <SoftwareSerial.h>
#include <MHZ.h>
#include <LiquidCrystal.h>

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

// pin for pwm reading
#define CO2_IN 10

// pin for uart reading
#define MH_Z19_RX 4  // D7
#define MH_Z19_TX 0  // D6

MHZ co2(MH_Z19_RX, MH_Z19_TX, CO2_IN, MHZ19B);

void setup() {
  Serial.begin(9600);
  pinMode(CO2_IN, INPUT);
  delay(100);
  Serial.println("MHZ 19B");

  lcd.begin(16,1);             // ***** 16 columns, 1 row
  lcd.clear();                 // ***** clear the display, cursor upper left
  lcd.print("hello, world!");  // ***** print something so we know it's working
  delay(5000);                 // ***** allow time to read it before proceeding
              // ***** get rid of the delay() when everything is working *****

  // enable debug to get addition information
  // co2.setDebug(true);

  if (co2.isPreHeating()) {
    Serial.print("Preheating");
    while (co2.isPreHeating()) {
      Serial.print(".");
      delay(5000);
    }
    Serial.println();
  }
}

void loop() {
  Serial.print("\n----- Time from start: ");
  lcd.home();                  // ***** position the cursor at upper left
  lcd.print(millis() / 1000);
  Serial.println(" s");


  int ppm_pwm = co2.readCO2PWM();
  lcd.print("PPMpwm:");        // ***** these will go right after the " s"
  lcd.print(ppm_pwm);

  Serial.println("\n------------------------------");
  delay(5000);
}

See if that gets you any closer.

It works! Thank you so much!

:sweat_smile:

Glad I could help!

So, not long after I tested the code, it started getting all weird (the text was starting to become gibberish), and now the text won't display on the screen at all. It used to work well, not sure what happened..

  • Always show us a good schematic of your proposed circuit.
    Show us good images of your ‘actual’ wiring.

This is the best image I could get. It's a little disastrous..

  • Yes :woozy_face:

  • It appears you might be doubling up wires in the Arduino header.
    If you are don’t do this.

  • You may have a bad/intermittent wire, swap some of them out with new wires to see it there are any bad wires.

I replaced a few wires (and stopped doubling-up wires) and the text still doesn't show up on my LCD screen. The serial monitor shows that the code is working, but I guess the screen isn't taking the input? I can send some more pictures if you need me to.

  • Upload one of the example sketches found in the LCD library to see if it works.

  • Properly focused images showing where wires start to where they end up is what needs to be seen.

I rewired everything (apparently my wiring was wrong), and now the screen works. Also, super duper sorry about the image quality.. My phone camera is baaad. Testing out the code again, it.. err..
This is my first attempt trying out the code, it randomly did this:

And then this is my second attempt:


Writing this now, it just got as bad as the first image. (by it, i mean the second image..)

  • Double check the all solder connections on the LCD PCB.

  • Looks like you are still doubling up wires on the power header.
    Doing so will damage that header pin.

  • Note: On the Arduino Uno Rev 3, ioref is connected to 5V.
    You can use it in place of or as well as the 5v pin.

  • lcd.home(); does not clear the line, lcd.clear(); does clear the line !

So, I'm testing the code again. Starting off, it's looking like this.

Now, it looks like this. I want to see if I can remove the random numbers at the start, but that would be a bit of a hassle and I don't want to wreck it again, now that it's the due day for my project..

Also, I moved the 3.5V to IOREF for my LCD.

A little tip: always use I2C LCD displays. You'll save a few pins (only two are used!) and a few connections. Simply buy LCDs with a pre-soldered I2C backpack, so you won't have to solder the pins (current LCDs have very poor quality soldering...).

PS: and since you have a breadboard to make multiple connections, no more doubling up on wires!

  • You might have some residual characters on the display.

  • Did you change:
    lcd.home();
    To
    lcd.clear();
    ?

  • Show us your latest software sketch version.

  • If you have access to a new LCD display does it act the same ?

Are either of these your random characters?

  • Examine the controller pins to make sure they are not bent and fully inserted in the I.C. socket.