Need Help with Arduino Code Not Displaying Correctly on LCD

I need help with this Arduino code. I am currently using an Arduino Uno r3 with the Grover-LCD RGB Backlight, and the text does not display the void setup code, but instead displays the void loop code, and it doesn't preform properly. Any Ideas?

The code comes from this website, which I am using for a project: The Brachistochrone Curve : 18 Steps (with Pictures) - Instructables

#include <DFRobot_RGBLCD1602.h>
#include <rgb_lcd.h>
#include <Wire.h>
#include "rgb_lcd.h"

rgb_lcd lcd;

const int colorR = 0;
const int colorG = 100;
const int colorB = 150;

const int startButtonMain = 6;
const int startButton = 5;
const int b1 = 4;
const int b2 = 3;
const int b3 = 2;

bool started = false;
bool time1Taken = false;
bool time2Taken = false;
bool time3Taken = false;


unsigned long initTime, timer1, timer2, timer3 = 0;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  lcd.begin(16, 2);

  lcd.setRGB(colorR, colorG, colorB);
  
  pinMode(startButtonMain, INPUT_PULLUP);
  pinMode(startButton, INPUT_PULLUP);
  pinMode(b1, INPUT_PULLUP);
  pinMode(b2, INPUT_PULLUP);
  pinMode(b3, INPUT_PULLUP);

  lcd.setCursor(0, 0);
  lcd.print("Brachistochrone");
  lcd.setCursor(0, 1);
  lcd.print("Experiment");

}

void loop() {
  // put your main code here, to run repeatedly:
  if (((digitalRead(startButtonMain) == 1) || (digitalRead(startButton) == 0)) && (!started)){
    Serial.println("timer started");
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("timer started");
    initTime = millis();
    started = true;
  }

  if (started && (digitalRead(b1) == 0) && (!time1Taken)){
    timer1 = millis();
    time1Taken = true;
  }

  if (started && (digitalRead(b2) == 0) && (!time2Taken)){
    timer2 = millis();
    time2Taken = true;
  }

  if (started && (digitalRead(b3) == 0) && (!time3Taken)){
    timer3 = millis();
    time3Taken = true;
  }

  if (time1Taken && time2Taken && time3Taken){

    lcd.clear();
    
    delay(1000);
    
    lcd.setCursor(1, 0);
    lcd.print("t1");
    lcd.setCursor(7, 0);
    lcd.print("t2");
    lcd.setCursor(13, 0);
    lcd.print("t3");
    
    lcd.setCursor(0, 1);
    lcd.print((float)(timer1-initTime)/1000);
    lcd.setCursor(6, 1);
    lcd.print((float)(timer2-initTime)/1000);
    lcd.setCursor(12, 1);
    lcd.print((float)(timer3-initTime)/1000);
    
    Serial.print((float)(timer1-initTime)/1000);
    Serial.print("\t");
    Serial.print((float)(timer2-initTime)/1000);
    Serial.print("\t");
    Serial.println((float)(timer3-initTime)/1000);
    started = false;
    time1Taken = false;
    time2Taken = false;
    time3Taken = false;
  }
}

Put a delay after that line and the setup prints should show up. The setup prints are happening but very shortly thereafter the loop code starts and clears the display because the first if structure is true.

1 Like

Thank for the help, however now it cannot display the times when it hits the power switch shown in the picture. Is there any idea that could help with this?

So after the LCD displays the "timer started", it doesn't display the times on the LCD when I press the power switch on the picture below.

Is the power switch the one connected to pin 5 (startButton)?

If you make changes to your code, even small changes, please post the new version of the code so that we can keep up.

Your code has a switch connected to pin 6 however the diagram does not have anything connected to pin 6.

Here is the current code. What should I switch the pin 6 to?

#include <DFRobot_RGBLCD1602.h>
#include <rgb_lcd.h>
#include <Wire.h>
#include "rgb_lcd.h"

rgb_lcd lcd;

const int colorR = 0;
const int colorG = 100;
const int colorB = 150;

const int startButtonMain = 6;
const int startButton = 5;
const int b1 = 4;
const int b2 = 3;
const int b3 = 2;

bool started = false;
bool time1Taken = false;
bool time2Taken = false;
bool time3Taken = false;


unsigned long initTime, timer1, timer2, timer3 = 0;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  lcd.begin(16, 2);

  lcd.setRGB(colorR, colorG, colorB);
  
  pinMode(startButtonMain, INPUT_PULLUP);
  pinMode(startButton, INPUT_PULLUP);
  pinMode(b1, INPUT_PULLUP);
  pinMode(b2, INPUT_PULLUP);
  pinMode(b3, INPUT_PULLUP);

  lcd.setCursor(0, 0);
  lcd.print("Brachistochrone");
  lcd.setCursor(0, 1);
  lcd.print("Experiment");
delay(10000);
}

void loop() {
  // put your main code here, to run repeatedly:
  if (((digitalRead(startButtonMain) == 1)|| (digitalRead(startButton) == 0)) && (!started)){
    Serial.println("timer started");
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("timer started");
    initTime = millis();
    started = true;
  }

  if (started && (digitalRead(b1) == 0) && (!time1Taken)){
    timer1 = millis();
    time1Taken = true;
  }

  if (started && (digitalRead(b2) == 0) && (!time2Taken)){
    timer2 = millis();
    time2Taken = true;
  }

  if (started && (digitalRead(b3) == 0) && (!time3Taken)){
    timer3 = millis();
    time3Taken = true;
  }

  if (time1Taken && time2Taken && time3Taken){

    lcd.clear();
    
    delay(1000);
    
    lcd.setCursor(1, 0);
    lcd.print("t1");
    lcd.setCursor(7, 0);
    lcd.print("t2");
    lcd.setCursor(13, 0);
    lcd.print("t3");
    
    lcd.setCursor(0, 1);
    lcd.print((float)(timer1-initTime)/1000);
    lcd.setCursor(6, 1);
    lcd.print((float)(timer2-initTime)/1000);
    lcd.setCursor(12, 1);
    lcd.print((float)(timer3-initTime)/1000);
    
    Serial.print((float)(timer1-initTime)/1000);
    Serial.print("\t");
    Serial.print((float)(timer2-initTime)/1000);
    Serial.print("\t");
    Serial.println((float)(timer3-initTime)/1000);
    started = false;
    time1Taken = false;
    time2Taken = false;
    time3Taken = false;
  }
}

Change the above to:

if (((digitalRead(startButtonMain) == 0)|| (digitalRead(startButton) == 0)) && (!started)){

The way that you had it is that the first if is true when the start button is not pressed. The timer stats unconditionally. At the end of the sequence when you print to the LCD the information gets printed but then loop() starts over right away and the LCD gets cleared because that if executes. If you change to both switches unpressed, the first if is not true until one of the switches is pressed. You then must press one of the switches (startButtonMain or startButton) to initiate timing.

The code has a switch (startButtonMain) connected to pin 6 but there is nothing connected to pin 6 in the diagram. Which is right?

Yes. Here are the minor changes in the code. What should I use instead?

#include <DFRobot_RGBLCD1602.h>
#include <rgb_lcd.h>
#include <Wire.h>
#include "rgb_lcd.h"

rgb_lcd lcd;

const int colorR = 0;
const int colorG = 100;
const int colorB = 150;

const int startButtonMain = 6;
const int startButton = 5;
const int b1 = 4;
const int b2 = 3;
const int b3 = 2;

bool started = false;
bool time1Taken = false;
bool time2Taken = false;
bool time3Taken = false;


unsigned long initTime, timer1, timer2, timer3 = 0;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  lcd.begin(16, 2);

  lcd.setRGB(colorR, colorG, colorB);
  
  pinMode(startButtonMain, INPUT_PULLUP);
  pinMode(startButton, INPUT_PULLUP);
  pinMode(b1, INPUT_PULLUP);
  pinMode(b2, INPUT_PULLUP);
  pinMode(b3, INPUT_PULLUP);

  lcd.setCursor(0, 0);
  lcd.print("Brachistochrone");
  lcd.setCursor(0, 1);
  lcd.print("Experiment");

}

void loop() {
  // put your main code here, to run repeatedly:
  if (((digitalRead(startButtonMain) == 0) || (digitalRead(startButton) == 0)) && (!started)){
    Serial.println("timer started");
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("timer started");
    initTime = millis();
    started = true;
  }

  if (started && (digitalRead(b1) == 0) && (!time1Taken)){
    timer1 = millis();
    time1Taken = true;
  }

  if (started && (digitalRead(b2) == 0) && (!time2Taken)){
    timer2 = millis();
    time2Taken = true;
  }

  if (started && (digitalRead(b3) == 0) && (!time3Taken)){
    timer3 = millis();
    time3Taken = true;
  }

  if (time1Taken && time2Taken && time3Taken){

    lcd.clear();
    
    delay(1000);
    
    lcd.setCursor(1, 0);
    lcd.print("t1");
    lcd.setCursor(7, 0);
    lcd.print("t2");
    lcd.setCursor(13, 0);
    lcd.print("t3");
    
    lcd.setCursor(0, 1);
    lcd.print((float)(timer1-initTime)/1000);
    lcd.setCursor(6, 1);
    lcd.print((float)(timer2-initTime)/1000);
    lcd.setCursor(12, 1);
    lcd.print((float)(timer3-initTime)/1000);
    
    Serial.print((float)(timer1-initTime)/1000);
    Serial.print("\t");
    Serial.print((float)(timer2-initTime)/1000);
    Serial.print("\t");
    Serial.println((float)(timer3-initTime)/1000);
    started = false;
    time1Taken = false;
    time2Taken = false;
    time3Taken = false;
  }
}

I wired up a circuit with an Uno, 4 momentary push button switches and an I2C LCD as closely copying your circuit as I could. I do not have a RGB display, I used a 20 x 4 (2004) character LCD and the excellent hd44780 library. Using the latest version of your code, the project seems to be working as one would expect.

What is the problem? Using my circuit (made from your diagram) and the latest code seems to work fine.

On restart the LCD reads

Brachistochrone
Experiment

Press the startButton (connected to pin 5). The display reads:

timer started

Press b1 (pin 4), b2 (pin 2), b3 (pin 2) in succession. Right after the 3rd switch, the display will change to something like:

t1 t2 t3
2.12 4.10 5.86

Press the startButton again. The display goes back to:

timer started

b1, b2, b3 can be pressed in any order.

If the above is not what your circuit is doing then there seems to be a hardware problem. Please describe, in detail, the problems that you have.

Or I am misunderstanding your requirements. In that case, please describe what the code is supposed to do.

Post some clear photos of your project wiring and layout. That is often helpful.

Thanks! I believe it might be a wiring issue, can I have a picture of the circuit to make sure?

I still do not know what the issue is. What is wrong?

Here is a photo though it can't show very much.

And here is a schematic showing my wiring. Note that the capacitors on the switches are not required. They do add hardware debounce and some noise immunity. Debounce can be done in software and there are those that would insist that software debounce is the best way.

Here is my setup. Doesn’t look nice, probably the best pic I can take. Is there anything wrong?

There is nothing wrong that i can see.

The micro-switches have 3 terminals, NO, NC and C. The C and NO terminals should be eired to the Arduino. The NC terminal should be left unconnected.

Now the problem is that the Arduino Uno doesn't turn on when the orange wire goes into the 5V and the GMD wire connects to the LCD. Is there any problem here?

I can't tell much at all by the photo. It is hard to see where the wires go and the LCD nnd the switches are not in the photo. It would be much better if you would draw a schematic showing exactly how the wiring is done.

Draw the schematic with pencil and paper, photograph it and post.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.