Weird Characters on LCD 1602 I2C

I'm having weird characters on my LCD Display that I wanted to use for debugging LDR Values. Here's what it looks like in Serial Monitor:

[left]ldr_value [0-???]:
110
ldr_adjusted [0-1023]:
321
ldr:
40
light_level:
15[/left]

Here's a picture of what it looks like on the LCD:

And this is the code I'm using:

#include <FastLED.h>
#include <RCSwitch.h>
// Adafruits RTClib from https://github.com/adafruit/RTClib
#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F, 16, 2);
RTC_DS3231 RTC;
RCSwitch mySwitch = RCSwitch(); // send wireless Data
String inString = "";
DateTime now;
char daysOfTheWeek[7][12] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};

#define NUM_LEDS 60
#define LED_TYPE WS2812B
#define DATA_PIN 6
#define COLOR_ORDER GRB

CRGB leds[NUM_LEDS];

// Filter averaging factor - higher value means more sluggish response to changes in ambient brightness
#define FILTER_LEN 8
// Brightness level initial value
int level=15;
// Brightness correction for Leds
unsigned char bright[] = {0, 2, 4, 7, 11, 18, 30, 40, 50, 65, 80, 96, 125, 160, 200, 255};

void setup()
{
  mySwitch.enableTransmit(10);  // Der Sender wird an Pin 10 angeschlossen
  // init RTClib
  Wire.begin();
  RTC.begin();
  // Following line sets the RTC to the date & time this sketch was compiled
  // every time I upload to the arduino, it resets this time. After initial
  // setup, this line needs to be removed.
  //RTC.adjust(DateTime(__DATE__, __TIME__)); last: 8:24

  // LCD Display
  lcd.init(); //Im Setup wird der LCD gestartet
  lcd.backlight();

  // Setup FastLED Lib
  FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds,NUM_LEDS).setCorrection(TypicalLEDStrip);

  // setup measurement for LDR
  digitalWrite(A0, HIGH);  // set pullup on analog pin 0
  pinMode(A1, OUTPUT);
  digitalWrite(A1, LOW);

  Serial.begin(57600); //was 57600
}

unsigned int ldr=0;

void doLDR() {
  unsigned int ldr_value = analogRead(0);          //reads the LDR values

  //Adjust for LDR variations.
  //dark = 1023
  //light = 0
  //If your LDR for example reaches a max analogRead value of 350 instead of 1023 for 100% dark.
  unsigned int ldr_adjusted=map(ldr_value,0,350,0,1023); //was map(ldr_value,0,700,0,1023);
                                                        //the level for the original LDR by Freenove
                                                       // was 400

  //set max limit (to avoid potential 'divide-by-zero's).
  if (ldr_adjusted >= 1023) ldr_adjusted = 1023; //was 1023

  //ldr follows ldr_adjusted, but is averaged so that values only change gradually
  ldr = ((unsigned long)(FILTER_LEN-1)*ldr+ldr_adjusted)/FILTER_LEN;

  unsigned int light_level=15; // was 15

  //translate [0-1023] to [15-0]
  //light_level = (1024-ldr)>>6;
  light_level=map(ldr,0,1023,15,0);
  if (light_level >= 15) light_level = 15; // was (light_level >= 15)
  if (light_level <= 1) light_level = 1;

  //DEBUG SPI
  // /*
  Serial.println("ldr_value [0-???]:");
  Serial.println(ldr_value);
  Serial.println("ldr_adjusted [0-1023]:");
  Serial.println(ldr_adjusted);
  Serial.println("ldr:");
  Serial.println(ldr);
  Serial.println("light_level:");
  Serial.println(light_level);
  // */

//DEBUG LCD-LDR BEGINN

  lcd.setCursor(0, 0);
  lcd.print(ldr_value);
  lcd.println(" ");
  lcd.println(ldr_adjusted);
//  lcd.println("LDR:");
//  lcd.println(ldr);
//  lcd.println(" ");
//  lcd.println(light_level);

//DEBUG LCD-LDR END


  //level=2;
  level = light_level;

}

DateTime old;

void loop() {
  // get time
  DateTime now = RTC.now();


/* // Begin LCD Time
  lcd.setCursor(0, 1);
  lcd.print(now.hour());
  lcd.print(":");
  lcd.print(now.minute());
  lcd.print(" ");
//  lcd.print(now.second());
  lcd.print(now.day());
  lcd.print('.');
  lcd.print(now.month());
  lcd.print('.');
  lcd.print(now.year());
//  lcd.print("  Uhr");
// END LCD
*/
  // send serial Data
  if (mySwitch.available()) {
     int value = mySwitch.getReceivedValue();
     if (value == 0) {
       Serial.println("Unknown encoding");
     } else {
         Serial.println( mySwitch.getReceivedValue() );


     }
     mySwitch.resetAvailable();

 }

   // Read serial input:
   while (Serial.available() > 0) {
     int inChar = Serial.read();
     if (isDigit(inChar)) {
       inString += (char)inChar;
     }
     if (inChar == '#') {
       long code = inString.toInt();
       mySwitch.send(code, 24);

       Serial.println(code);
       inString = "";
     }
   }


  // send serial Data


  // DEBUG RTC
   /*
  Serial.print(now.year(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.day(), DEC);
  Serial.print(' ');
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.println();
   */

  if (now.second()!=old.second()) {
    old = now;
    doLDR();
  }

  // clear LED array
  memset(leds, 0, NUM_LEDS * 3);

if(level == 1){
  // this is the night mode
  // set LED background
  for (int i=0; i<NUM_LEDS; i++) {
    leds[i].r = bright[level];
    leds[i].g = (bright[level]+1)/2;
    leds[i].b = 0;
  }
...
    leds[((59+hourpos)%60)%60].g = bright[level/2];
    leds[(hourpos)%60].g = bright[level];
    leds[((hourpos+1))%60].g = bright[level/2];
  }
  // update LEDs
  //FastLED.setBrightness(100);
  FastLED.show();
  FastLED.delay(500);

  // wait some time
  //delay(500);
}

How can they be removed? I can't fit everything on the display, these are stealing my lcd real estate

You have used lcd.println() which sends a carriage return (CR) and a line feed (LF) to the LCD display.
The hd44780 LCD does not support line endings. (CR and LF)
Also, currently, "LiquidCrystal" type libraries don't support line endings in software to support them.
This means that the code values for those characters (0xd and 0xa) get interpreted as custom characters
and since you have not defined those custom characters they show up as "garbage" custom characters.

If you were to use the hd44780 library, it would have issued a compile error when attempting to use println().

Note that at some point in the future I will be adding a mode to support line endings to the hd44780 library so that println() will work
similar to the way it works on a terminal.

--- bill

bperrybap:
Note that at some point in the future I will be adding a mode to support line endings to the hd44780 library so that println() will work
similar to the way it works on a terminal.

--- bill

I'm looking forward to that. It is something that I have been trying to do myself, but not got very far. I would like continuous data to fill each line in order starting at 0,0, clear at the end of line 4 (20x4) and then move to "home" to display the rest of the incoming data stream.

My efforts are not worth posting currently! The idea is to have a continuous display of incoming RTTY.

AJLElectronics:
I'm looking forward to that. It is something that I have been trying to do myself, but not got very far. I would like continuous data to fill each line in order starting at 0,0, clear at the end of line 4 (20x4) and then move to "home" to display the rest of the incoming data stream.

That capability is already available in the hd44780 library.
All you have to do is turn on line wrapping by calling lineWrap()
It is documented in the included documentation and the library also includes an example to show how to use it.

--- bill

I'm currently using the NewLiquidCrystal library, so am I right in thinking that I need to remove that one and install one called HD44780? If so, does it also handle I2C backpacks?

Thanks for your input so far, it's really useful.

AJLElectronics:
I'm currently using the NewLiquidCrystal library, so am I right in thinking that I need to remove that one and install one called HD44780? If so, does it also handle I2C backpacks?

Thanks for your input so far, it's really useful.

See the github page for more information: GitHub - duinoWitchery/hd44780: Extensible hd44780 LCD library

bperrybap:
See the github page for more information: GitHub - duinoWitchery/hd44780: Extensible hd44780 LCD library

You are very kind, that helps greatly.

I can recommend bperrybap's library, read the docs too, it's a very thoughtfully designed library.

I have the library in and see the linewrap working, very satisfying. Next step for me is to make it clearer where the new text is, so I am thinking of either clearing the line about to start writing, or maybe write a few spaces in front of the characters appearing. I think it might be good to clear the lot every time it returns to home. My head hurts at the moment so will have to think about it over the next few days.

I have been busy trying to RF proof everything tonight. It's a bit like pushing down the corner of a cushion... it just pops up somewhere else. :slight_smile: The connection to this thread is that the symptoms are "Wierd characters appearing on the LCD" whenever it goes into transmit.

After pondering, I think that the best method would be to clear the LCD once it has written to position 80. My thinking is to count the incoming characters and issue an lcd.clear at position 80?

AJLElectronics:
After pondering, I think that the best method would be to clear the LCD once it has written to position 80. My thinking is to count the incoming characters and issue an lcd.clear at position 80?

I would recommend starting a new thread to continue this discussion as it is not the original topic.

Yes I will do if I can’t sort it for myself. Apologies for the thread hijack.

I occasionally get the same weird characters as the original post. I'm using a 4x20 lcd display and the LiquidCrystal.h library. I do not use lcd.println(), only lcd.print(). For me it's be an intermittent issue that seems to get worse if the program does more string floating point processing. So it may be a memory issue.

Robert