LCD screen blinks

Hello,

I've built an LCD display on Arduino, that should show variety of text depending on which pin shows voltage. However, when one of the pins is active the text will remain true on the screen for a couple of seconds and then start blinking just to show text from the other if statements. It should remain true all the time, I don't know why it does this. Can anyone notice why? This is the code I've used:
#include <LiquidCrystal.h>

// Constants for LCD and pins
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
const int LCD_COLS = 16;
const int LCD_ROWS = 2;

// LCD object initialization
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

// Function declarations
void initializePins();
void updateLCD(const String& line1, const String& line2);
void checkSensorStates();
void displayAllInfo();

// Store the last displayed message
String lastLine1 = "";
String lastLine2 = "";

void setup() {
Serial.begin(9600);
lcd.begin(LCD_COLS, LCD_ROWS);
initializePins();
displayAllInfo(); // Initial display to avoid blank start
}

void loop() {
checkSensorStates();
delay(1200); // Delay between reads, adjust as needed
}

void initializePins() {
// Setup pin modes
pinMode(6, INPUT);
pinMode(7, INPUT);
pinMode(8, INPUT);
pinMode(9, INPUT);
pinMode(10, OUTPUT);
pinMode(13, OUTPUT);
digitalWrite(10, HIGH); // Fans on initially
digitalWrite(13, HIGH);
}

void updateLCD(const String& line1, const String& line2) {
if (line1 != lastLine1 || line2 != lastLine2) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(line1);
lcd.setCursor(0, 1);
lcd.print(line2);
lastLine1 = line1;
lastLine2 = line2;
}
}

void displayAllInfo() {
updateLCD("TEMP BALANCE", "Current SoC");
}

void checkSensorStates() {
int val_0 = analogRead(A0);
int val_1 = analogRead(A1);
int val_2 = analogRead(A3);
int val_3 = analogRead(A5);

if (val_0 >= 1023) {
    updateLCD("TEMP HIGH", "CHECK SYS");
} else if (val_1 >= 1023) {
    digitalWrite(10, LOW);  
    digitalWrite(13, LOW);
    updateLCD("Shade needed", "Fan rest");
} else if (val_2 >= 1023) {
    updateLCD("Levels uneven", "Align cells");
} else if (val_3 >= 1023) {
    updateLCD("Energy warning", "Seek charge");
} else {
    displayAllInfo();
}

}

This is the schematics that I've tried IRL that still fails:

It might help to see a schematic diagram of your circuit and a clear photo of how you have everything wired together.

Note that you test with analogRead and set a limit of 1023. This means that if there is only a very slight dip in the voltage on the pin, your test condition becomes false and you'll get a different output. In the sketch as it is now, it's more sensible to use a normal digitalRead.

We've more or less done this configuration: Login - Tinkercad

And if that link doesn't work here's a picture:

Note that the circuit works in TinkerCad, but when we make the same configuration in real life this problem occurs

If you are drawing power for two motors from the Arduino board 5 volt pin, don't do that.

Use a power supply with adequate current oh wait, it looks like you are running the motors directly from the output pins.

That is a bigger don't do that.

IRL you need a motor driver circuit. Matched to the exact motors you are using so

post the specs on the real motos and provide a link to where you got them.

A few transistors or MOSFETs and some resistors and a real power supply will fix you up.

a7

As said, it's likely the approach with analogRead and a lower limit of 1023 is part of your problem. Use digitalRead instead.

I have no account on Tinkercad.

We tried with digitalRead first, but that didn't work. This is our original code (we used digital pins 6-9 on arduino):
#include <LiquidCrystal.h>

// Constants for LCD and pins
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
const int LCD_COLS = 16;
const int LCD_ROWS = 2;

// LCD object initialization
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

// Function declarations
void initializePins();
void updateLCD(const String& line1, const String& line2);
void checkSensorStates();

void setup() {
Serial.begin(9600);
lcd.begin(LCD_COLS, LCD_ROWS);
initializePins();
}

void loop() {
checkSensorStates();
delay(1200); // Delay between reads, adjust as needed
lcd.clear();
}

void initializePins() {
// Inputs
pinMode(6, INPUT);
pinMode(7, INPUT);
pinMode(8, INPUT);
pinMode(9, INPUT);
// Outputs
pinMode(10, OUTPUT);
pinMode(13, OUTPUT);
digitalWrite(10, HIGH); // Fans on initially
digitalWrite(13, HIGH);
}

void updateLCD(const String& line1, const String& line2) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(line1);
lcd.setCursor(0, 1);
lcd.print(line2);
}

void displayAllInfo() {
digitalWrite(10, HIGH);
digitalWrite(13, HIGH);

lcd.clear();
lcd.setCursor(8,0);
lcd.print("BALANCE"); //Dessa fyra texter visas inget simuleras (standard text)
lcd.setCursor(1,0);
lcd.print("TEMP");
lcd.setCursor(1,1);
lcd.print("Current");
lcd.setCursor(10,1);
lcd.print("SoC");

}

void checkSensorStates() {
int PIN_6 = digitalRead(6);
int PIN_7 = digitalRead(7);
int PIN_8 = digitalRead(8);
int PIN_9 = digitalRead(9);

if (PIN_6 == HIGH) { 
    updateLCD("TEMP HIGH", "CHECK SYS"); //Svetsad kontaktor
} else if (PIN_7 == HIGH) {
    digitalWrite(10, LOW);  
    digitalWrite(13, LOW);
    updateLCD("Shade needed", "Fan rest"); //Hög temperatur
} else if (PIN_8 == HIGH) {
    updateLCD("Levels uneven", "Align cells"); //Spänning ur balans
} else if (PIN_9 == HIGH) {
    updateLCD("Energy warning", "Seek charge");  //Låg laddning
} else {
    displayAllInfo();
}

}

We haven't connected the motors yet in real life, we're trying to configure the screen first so we don't know how that affects the circuit.

The motors that we're going to use has 5v operating voltage, which pins should we use instead for them?

  1. you need a power supply
  2. you need a motor driver
  3. re-read how to use code tags to format your code in a message on the forum. What you did wasn't it.

For the same reason as you discussed before, i.e. the erratic display output?

What's not entirely clear to me, also not from your Tinkercad diagram, is what drives the four inputs. If there's any jitter on those signals, you might see this reflected in erratic changes on the display. Where do your inputs come from? How are these signals generated and delivered to the microcontroller?

Here's the logic:

The 4 inputs are suppose to represent 4 different simulations, therefour we use 4 power sources that "represents" them. Only one of them can be active at once (in real life), when we turn up the voltage on one of the power sources, text output should occur on the LCD that correlates to the simulation. What happens is that the correct output comes first and after a few seconds it starts to blink and show texts that would occur if another simulation (or pin) was true (or high).

The inputs, are simply a 5v digital signals. We tried to use analogRead instead to see if it would fix the blink but it doesn't.

Generated how, by what? In real life I mean, not the virtual simulation.

This suggests a gradual rise in voltage. This would result in a boundary condition where the state of an input port flips (when using digitalRead) or varies (analogRead).

Q1 - why is a display routine turning on both fan outputs? Would seem like misplaced code.

They should do that, the fans should be HIGH all the time except for when pin 7 is HIGH, then they should turn of. Is there any other way to configure this or?

What @camsysca says is more about structuring your code in a logical fashion. In principle your approach would work, but it's confusing, especially if your codebase grows. See e.g. here Model–view–controller - Wikipedia

Rewrite your code. Be methodical, be consistent. Use IPO
I - read all your inputs
P - process your input states, using internal variables for all results
O - output to your pins and display

You'll find that doing it that way greatly simplifies your code.

You're an engineer - I'm not going to re-write it for you, like some 12 year old with a homework assignment. You'll benefit more from doing it yourself.

1 Like

The blinking is because you're doing a screen clear in loop() - why?

The power is drawn from the breadboard, that is connected to 5v on Arduino (the + pool), that's what we use to test the simulations

I tried removing the lcd.clear(); from the loop function, but that didn't change anything as well.

Something as simple as an imperfect contact of a jumper wire in your breadboard can result in the behavior you're seeing.

Try debouncing those inputs and see if the problem goes away.

Well, if you're powering the LCD and the motors from your poor little Arduino, all bets are off. Even perfect code can't cope with disaster.

1 Like