LCD with Weird Characters in the Right Places - RESOLVED

I’m using a 16x4 LCD screen with an Arduino Mega. I’ve been using it for a school project for the last couple of semesters, the screen works fine for a while and then I move a while for something else on the board and the screen gets all mess up.

Yesterday, I moved the circuit to a new board and now the characters display in the right location, but they characters are all weird - I have included a picture. It’s supposed to say
“Total Time”
00:00 % increments with the Arduino’s internal clock, millis() %

Touches

touch counter % increments in response to feedback %

Like I said above, from what I can tell, the clock is working, and the display puts the numbers in the correct spot, but the characters are all messed up and I can’t figure out why these vertical lines are popping up. Any suggestions as to what pin I should be trying to troubleshoot to fix this?

I believe the code should be OK, since I’ve had it working for about a year. I’m pretty sure there is a problem with the circuit, but I don’t know which wire would be controlling my issue since everything on the screen looks like it’s lined up.

EDIT: Looks like the conclusion was that my screen was broken and needed to be replaced. I ordered another 1604 LCD on ebay. Feel free to make more suggestions on decent places to buy these screens.

_402ProjectCode.ino (5.83 KB)

/////////////////////////////////////////////////////
// Project code for Orotracheal Injection Simulator//
// BME 400 - Biomedical Engineering Design         //
// JJ Lamb, 2018 (BME 400) Version 2               //
/////////////////////////////////////////////////////

#include <LiquidCrystal.h>
// LiquidCrystal lcd(RS, E , D4, D5, D6, D7);
LiquidCrystal lcd(33, 31, 29, 27, 25, 23);

int successPin = A12;   // Green light
int tongue = A13;       // blue light
int tonsils = A14;      // orange light
int uvula = A15;        // red light
int button = 41;        // reset button

int LEDsuccess = 7;     // green LED
int LEDtongue = 8;      // blue LED
int LEDtonsils = 9;     // orange LED
int LEDuvula = 10;      // red LED

// Vibrators
int vibration = 2;

// Pin variables
float READsuccess = 0;
float Svoltage = 0;
float READtongue = 0;
float Vvoltage = 0;
float READtonsils = 0;
float H1voltage = 0;
float READuvula = 0;
float H2voltage = 0;

int touches = 0;  // touch count
int offset = 0;   // timer offset
int LED = 0;      // 0 or 1 used to help touch count

void setup() {

  // Set up the LCD Screen
  lcd.begin(16, 4);
  lcd.print("Total Time");
  lcd.setCursor(0, 2);
  lcd.print("# Touches");

  // Initialize the pins
  // Input pins
  pinMode(successPin, INPUT);
  pinMode(tongue, INPUT);
  pinMode(tonsils, INPUT);
  pinMode(uvula, INPUT);
  pinMode(button, INPUT);

  // Output pins
  pinMode(LEDsuccess, OUTPUT);
  pinMode(LEDtongue, OUTPUT);
  pinMode(LEDtonsils, OUTPUT);
  pinMode(LEDuvula, OUTPUT);

  pinMode(vibration, OUTPUT);

  Serial.begin(9600);

}

void loop() {

  // Set up time variable
  // Reads the arduinos internal clock every iteration
  int times = millis() / 1000;
  //int timer = times/1000;
  times = times - offset;
  // this subtracts an offset because can't reset the internal clock
  int seconds = times % 60;
  int minutes = (times - seconds) / 60;

  ///////////////////////
  // Printing the time //
  // print minutes
  lcd.setCursor(0, 1);
  if (minutes < 10) {
    lcd.print(0);
    lcd.setCursor(1, 1);
    lcd.print(minutes);
  } else {
    lcd.print(minutes);
  }

  lcd.setCursor(2, 1);
  lcd.print(':');

  // print seconds
  lcd.setCursor(3, 1);
  if (seconds < 10) {
    lcd.print(0);
    lcd.setCursor(4, 1);
    lcd.print(seconds);
  } else {
    lcd.print(seconds);
  }
  // end time printer //
  //////////////////////

  //////////////////////////////
  // analogRead the variables //
  READsuccess = analogRead(successPin);
  Svoltage = READsuccess * 5 / 1023;
  if (Svoltage > 0.05) {
    READsuccess = HIGH;
  } else {
    READsuccess = LOW;
  }

  READtongue = analogRead(tongue);
  Vvoltage = READtongue * 5 / 1023;
  if (Vvoltage > 0.05) {
    READtongue = HIGH;
  } else {
    READtongue = LOW;
  }

  READtonsils = analogRead(tonsils);
  H1voltage = READtonsils * 5 / 1023;
  if (H1voltage > 0.05) {
    READtonsils = HIGH;
  } else {
    READtonsils = LOW;
  }

  READuvula = analogRead(uvula);
  H2voltage = READuvula * 5 / 1023;
  if (H2voltage > 0.05) {
    READuvula = HIGH;
  } else {
    READuvula = LOW;
  }
  // end of variable readings //
  //////////////////////////////


  ////////////////////////
  // Tunn Lights On/Off //
  digitalWrite(LEDsuccess, READsuccess);  // Green light
  digitalWrite(LEDtongue, READtongue);    // Blue light
  digitalWrite(LEDtonsils, READtonsils);  // Orange light
  digitalWrite(LEDuvula, READuvula);      // Red light
  // end lights //
  ////////////////


  //////////////////
  // Failure Text //
  lcd.setCursor(8, 3);
  if (READtongue == HIGH) {
    lcd.print("Tongue");
  } else if (READtonsils == HIGH) {
    lcd.print("Tonsils");
  } else if (READuvula == HIGH) {
    lcd.print("Uvula");
  } else {
    lcd.print("          ");
  }
  // end failure text //
  //////////////////////

  ////////////////
  // Vibration //
  if (READtongue == HIGH || READtonsils == HIGH || READuvula == HIGH) {
    digitalWrite(vibration, HIGH);
  }else{
    digitalWrite(vibration, LOW);
  }
  // end vibration //
  ///////////////////

  /////////////////////////////////////////
  // Activate vibration through 1 output //
  if (READtongue == HIGH || READtonsils == HIGH || READuvula == HIGH) {
    digitalWrite(vibration, HIGH);
  } else {
    digitalWrite(vibration, LOW);
  }
  ////////////////////////////////////////

  //////////////////////////////
  // Increase the touch count //
  int timer = millis();
  if (timer % 7 == 0) {       // this line helps with "switch debouncing"
    if (READtongue == HIGH || READtonsils == HIGH || READuvula == HIGH) {
      if (LED == 0) {
        LED = 1;
        touches++;
        lcd.setCursor(0, 3);
        lcd.print(touches);
      }
    } else {
      LED = 0;
    }
  }
  // end touch count //
  /////////////////////


  //////////////////////////
  // Response for success //
  if (READsuccess == HIGH) {
    lcd.setCursor(8, 3);
    lcd.print("Success");

    digitalWrite(vibration, LOW);

    // Freeze the screen until you push the button
    int buttonReset = LOW;
    while (buttonReset == LOW) {
      buttonReset = digitalRead(button);
    }

    // Reset variables after success
    touches = 0;
    lcd.setCursor(0, 3);
    lcd.print("               "); // Prints a bunch of blank spaces to clear the last line
    offset = millis() / 1000;
  }
  // end success response //
  //////////////////////////


  //////////////////////////////
  // Read the button component//
  // if button is pushed, reset the variables
  if (digitalRead(button) == 1) {
    offset = millis() / 1000; // will be used to reset timer to 0
    // can't reset Arduino internal clock
    touches = 0;
    lcd.setCursor(0, 3);
    lcd.print("               "); // Print a bunch of blank space

    lcd.clear();
    // Set up the LCD Screen
    lcd.begin(16, 4);
    lcd.print("Total Time");
    lcd.setCursor(0, 2);
    lcd.print("# Touches");
  }
  // end of reset button //
  /////////////////////////
}

// THEnd

The grounds should be RSS, RW, and LEDK correct?

Do your troubleshooting with simple routines such as:

  • A program that writes a message to one or more display rows in setup() and does nothing in loop.

  • A program that sequentially writes a different printable ASCII code to each of the 80 memory locations in the LCD controller memory.

Don

I have tried code to print “Hello World” into the top line. The code is included here and I’ve attached a picture of the result.

#include <LiquidCrystal.h>
// LiquidCrystal lcd(RS, E , D4, D5, D6, D7);
LiquidCrystal lcd(33, 31, 29, 27, 25, 23);

void setup() {
  lcd.begin(16,4);
  lcd.print("Hello World");

}

void loop() {
  // put your main code here, to run repeatedly:

}

I also tried printing a line of “aaaaaaaaaaaaaaaa” on each line (16 characters for my 16x4 LCD). I did this one line at a time by changing where the lcd.setCursor(0,n) was. I attached pictures of the lines. The first and second lines seemed to be “connected” and the third and fourth lines the same.

#include <LiquidCrystal.h>
// LiquidCrystal lcd(RS, E , D4, D5, D6, D7);
LiquidCrystal lcd(33, 31, 29, 27, 25, 23);

void setup() {
  lcd.begin(16,4);
  lcd.setCursor(0,0);
  lcd.print("aaaaaaaaaaaaaaaa");

}

void loop() {
  // put your main code here, to run repeatedly:

}

It seems like the code is outputting to the screen correctly, but there is a pin wrong somewhere. I had this working the other day and haven’t changed the pins, so I’m trying to figure out if I potentially shorted something. I’m working on a project that is due at the end of month and we’re on a limited budget, so I’m trying to decide if I need to spend the money on a new screen or if I can stick with the one I have.

a9adbac74ca23ff17ec973ab755dccda08b8d90d.jpg

8c6993f5b7cee0d014a937de73d795751080aceb.jpg

111231d4861679ee6af49640e3fa6ef950fb1d3b.jpg

a5409ecf95f758e5d11c5bbaa49dee4b71278627.jpg

New display. :astonished:

I cannot find any pattern in the characters which would indicate one “stuck” bit, and none of the spurious characters matches the character set.

I was afraid that was going to be the answer.

Anyone have any suggestions for decent 16x4 screens (~$10)? I've been seeing a lot of 20x4 screens, but I think I need one that is 16x4 so that the screen size stays the same and it will fit into the space I have it in currently.