Display with messy characters

Hi all

I'm working on a LED altimeter to be used on a multirotor; Everything works perfectly, but I have a problem with the standard Hitachi 2x16 display used the project: after a few seconds from start it shows messy characters. Here you can find some more informations:

  • In the setup part of the sketch i "prepare" the display; in the loop section i continuosly update text showing content of some variables
  • I have power leds driven by a 540 MOSFET, never hot never even warm
  • The program starts normally, led blinks, variables are shown, but after 15-20 seconds strange characters start to be shown, and soon all the display becomes a mess
  • If i put the "digitalWrite(PinLed, Led)" command in the program leds blinks and problem happen; if I change the line as a comment with // no problems at all, even for half an hour
  • Arduino ONE is powered by an USB3.0 port of my pc; Leds have a 12v dedicated battery
  • If I keep the "digitalWrite(PinLed, Led)" command in the sketch, but i disconnect the 12v Led battery the problem persist
  • At the beginning I had display and other components on the same breadboard and the problem started after 3-4 seconds; now i moved the display on another separate board and the problem takes around 12-15 seconds to start

Some images:

The messy display

The good one (first 12-15 running seconds)

Two breadboards (and messy display)

Does anyone have some ideas to deal with? Thank you very much and ciao.

Please post your code.

Here it is:

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

String Ver = "0.239";
int TotalFlash = 0;
int CtrFlash = 1;
long FlashON = 0;
long FlashOFF = 0;
long Pause = 1500;
int Led = LOW;
long TimeTarget = 0;
long CurrentTime = 0;
int ButtonDelay = 500;
int Altitude=0;
int PrevAltitude=0;
int AltitudeRangeInf=0;
int AltitudeRangeSup=0;
int StartAltitude=0;
int SensorValue=0;
int SampleInterval=2500;
long NextSample=0;
int PercError=5;
int InFlightFlag = 0;
String Status = "PF"; // Status PF=preflight, UP=ascending, DN=descending, LV=leveled, TG=alti target, LN=Landing, LD=Landed, OF=Off
int TargetAlti = 50;
int VariAlti = 10;

int PinLed = 6;
int PinPiu = 8;
int PinMeno = 7;
int PressPiu = 0;
int PressMeno = 0;

void setup() {
  TimeTarget = Pause;
  pinMode(PinLed, OUTPUT);
  pinMode(PinPiu, INPUT);
  pinMode(PinMeno, INPUT);  
  lcd.begin(16, 2);
  lcd.print("AltiLight v"+Ver);
  delay(2500);
  lcd.clear();
  SensorValue = analogRead(A0);
  Altitude=150-SensorValue/10;
  lcd.setCursor(0, 0);
  lcd.print("Altitude init");
  lcd.setCursor(0, 1);
  lcd.print("Quota OSL:");
  lcd.setCursor(10, 1);
  lcd.print(Altitude);
  delay(2500);
  PrevAltitude = 0;
  StartAltitude=Altitude;
  NextSample=SampleInterval;
  Altitude=0;
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("St:   Alti:");
  lcd.setCursor(0, 1);
  lcd.print("Trg:    S:");
  lcd.setCursor(3, 0);
  lcd.print(Status);
  lcd.setCursor(11, 0);
  lcd.print(Altitude);
  lcd.setCursor(4, 1);
  lcd.print(TargetAlti);
  Serial.begin(9600);
}

void loop() {
  PressPiu=digitalRead(PinPiu);
  PressMeno=digitalRead(PinMeno);
  if(PressPiu == HIGH) {
    TargetAlti = TargetAlti + VariAlti;
    if (TargetAlti>250) {
      TargetAlti = 250;
    }
    lcd.setCursor(4, 1);
    lcd.print(TargetAlti);
    delay(ButtonDelay);      
  }
  if(PressMeno == HIGH) {
    TargetAlti = TargetAlti - VariAlti;
    if (TargetAlti<0) {
      TargetAlti = 0;
    }
    lcd.setCursor(4, 1);
    lcd.print(TargetAlti);
    if(TargetAlti == 90) {
      lcd.setCursor(6, 1);
      lcd.print(" ");
    }
    delay(ButtonDelay);
  }
  
  if(Status=="PF") {
    TotalFlash = 1;
    FlashON = 100;
    FlashOFF = 100;
  }
  if(Status=="UP") {
    TotalFlash = 3;
    FlashON = 100;
    FlashOFF = 250;
  }
  if(Status=="DN") {
    TotalFlash = 5;
    FlashON = 100;
    FlashOFF = 250;
  }
  if(Status=="LV") {
    TotalFlash = 5;
    FlashON = 500;
    FlashOFF = 500;
  }
  if(Status=="TG") {
    TotalFlash = 15;
    FlashON = 50;
    FlashOFF = 100;
  }
  if(Status=="LN") {
    TotalFlash = 3;
    FlashON = 1500;
    FlashOFF = 200;
  }
  if(Status=="LD") {
    TotalFlash = 50;
    FlashON = 25;
    FlashOFF = 50;
  }
  if(Status=="OF") {
    TotalFlash = 0;
    FlashON = 25;
    FlashOFF = 50;
  }

  unsigned long CurrentTime = millis();
  if (CurrentTime>=TimeTarget) {
    if (Led == LOW) {
      Led = HIGH;
      TimeTarget=TimeTarget+FlashON;
      CtrFlash++;
    }
    else {
      Led = LOW;
      if (CtrFlash<=TotalFlash) {
        TimeTarget=TimeTarget+FlashOFF;
      }
      else {
        TimeTarget=TimeTarget+Pause;
        CtrFlash=1;
        if (Status=="LD") {
          Status="OF";
        }
      }
    }  
    if (Status != "OF") {
      digitalWrite(PinLed, Led);
    }
    else {
      digitalWrite(PinLed, LOW);
    }
  }
  
  if (CurrentTime>=NextSample) {
    SensorValue = analogRead(A0);
    Serial.println(Altitude);    
    Serial.println(Status);    
    Serial.println(InFlightFlag);    
    Altitude=102-SensorValue/10;
    lcd.setCursor(11, 0);
    lcd.print(Altitude);
    if (Altitude<100) {
      lcd.setCursor(13, 0);
      lcd.print(" ");
    }
    if (Altitude<10) {
      lcd.setCursor(12, 0);
      lcd.print(" ");
    }
    if (Altitude>25) {
      InFlightFlag=1;
    }
    AltitudeRangeInf=PrevAltitude-PrevAltitude*PercError/100;
    AltitudeRangeSup=PrevAltitude+PrevAltitude*PercError/100;
    if (Altitude<AltitudeRangeInf) {
      Status="DN";
    }
    if (Altitude>AltitudeRangeSup) {
      Status="UP";
    }
    if (Altitude>1&&AltitudeRangeInf<=Altitude && Altitude<=AltitudeRangeSup) {
      Status="LV";
    }
    if (AltitudeRangeInf<=TargetAlti && TargetAlti<=AltitudeRangeSup) {
      Status="TG";
    }
    if (InFlightFlag==1 && 1<=Altitude && Altitude<=5) {
      Status="LN";
    }
    if (InFlightFlag==1 && Altitude<1 && Status != "OF") {
      Status="LD";
    }
    if (InFlightFlag==0 && Altitude<1) {
      Status="PF";
    }
    
    lcd.setCursor(3, 0);
    lcd.print(Status);
    NextSample=NextSample+SampleInterval;
    PrevAltitude = Altitude;
  }
  lcd.setCursor(10, 1);
  lcd.print(millis()/1000);
}

Behaviour changes with the physical layout?

Put a 100 nF capacitor on the breadboard directly between pins 1 and 2 of your LCD.

Paul__B:
Behaviour changes with the physical layout?

Put a 100 nF capacitor on the breadboard directly between pins 1 and 2 of your LCD.

you mean, joining pins 1 & 2? Which should be + - on the display?

No, it goes between, a capacitor doesn't join signals, its an open circuit (at DC).

Hope that's clearer.

Thank you very much Paul__B & MarkT
Added capacitor and now it works perfectly

great suggestion, thank you very much
(and thank you very much to Paolo in FabLab_Milano for his support in phisical implementation).

Bingo!

Ciao