Sketch does not update LCD properly - Solved

I made the sketch below for a GPS clock.
It runs correctly on the Serial Monitor.

However, at the LCD display the seconds do not change smoothly. They sometimes stand still for a couple of seconds, then catch-up correctly.

As in this example with a number per second:
10 11 12 12 14 15 16 16 16 19 20
where it should be:
10 11 12 13 14 15 16 17 18 19 20

So it looks like the program is not updating the display every second, but I can't see why.

Any hint is highly appreciated.

Best regards,
Niels

#include <TinyGPSPlus.h> // by Mikal Hart
#include <SoftwareSerial.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //Arduino pins for communication

static const int RxPin = 8, TxPin = 9; // TxPin bruges ikke i dette projekt
static const uint32_t GPSBaud = 9600;

// Erklæring af tider og strenge
int day, month, year, hour, minute, second;
String dateStr, dayStr, monthStr, yearStr; 
String timeStr, hourStr, minuteStr, secondStr;

// The TinyGPSPlus object
TinyGPSPlus gps;

// The serial connection to the GPS device
SoftwareSerial ss(RxPin, TxPin);

// For stats that happen every 5 seconds
unsigned long last = 0UL;

void setup() {                  delay(3000);
	Serial.begin(115200);
	ss.begin(GPSBaud);

  // Display setup
  lcd.begin(16, 2); //start LCDlibrary and set display size
  lcd.clear(); // Position (0,0)

  //  Display test
  //  lcd.print("1. linje");
  //  lcd.setCursor(0,1);   // position 0-15, linje 0-1
  //  lcd.print("2. linje");
  //  lcd.clear();
}

void loop() {
	// Dispatch incoming characters
	while (ss.available() > 0) {
		gps.encode(ss.read()); 
	}
  
	if (gps.date.isUpdated()) {
    year = gps.date.year();
    month = gps.date.month();
    day = gps.date.day();
	}
  
  if (gps.time.isUpdated()) {
    hour = gps.time.hour();
    minute = gps.time.minute();
    second = gps.time.second();
	}
  
  // Konvertering af tider til strenge
  dayStr = String(day);
  monthStr = String(month);
  yearStr = String(year); 
  hourStr = String(hour);
  minuteStr = String(minute);
  secondStr = String(second);
  
  // Minimum 2 cifre i værdi
  if (day < 10) { dayStr = '0'+ dayStr; }
  if (month < 10) { monthStr = ' ' + monthStr; }
  if (hour < 10) { hourStr = '0' + hourStr; }
  if (minute < 10) { minuteStr = '0' + minuteStr; }
  if (second < 10) { secondStr = '0' + secondStr; }
  
  // Færdiggør display-strenge
  dateStr = dayStr + " " + monthStr + " " + yearStr; 
  timeStr = hourStr + ":" + minuteStr + ":" + secondStr;
  
  // Til monitor
  Serial.println( dateStr + "   " + timeStr );

  // To LCD. Cleared in setup. 
  lcd.setCursor(4,0); // (position,line)
  lcd.print(timeStr);
  lcd.setCursor(3,1); 
  lcd.print(dateStr);
  
}

I think you are updating the LCD too frequently. Is it updated each time loop() runs, even if the time has not changed.

Please always click Auto-Format in the IDE menu before you post your code, that makes it easier to spot errors like { or } in the wrong place.

#include <TinyGPSPlus.h> // by Mikal Hart
#include <SoftwareSerial.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //Arduino pins for communication

static const int RxPin = 8, TxPin = 9; // TxPin bruges ikke i dette projekt
static const uint32_t GPSBaud = 9600;

// Erklæring af tider og strenge
int day, month, year, hour, minute, second;
String dateStr, dayStr, monthStr, yearStr; 
String timeStr, hourStr, minuteStr, secondStr;

// The TinyGPSPlus object
TinyGPSPlus gps;

// The serial connection to the GPS device
SoftwareSerial ss(RxPin, TxPin);

// For stats that happen every 5 seconds
unsigned long last = 0UL;

void setup() {
  Serial.begin(115200);
  ss.begin(GPSBaud);

  // Display setup
  lcd.begin(16, 2); //start LCDlibrary and set display size
  lcd.clear(); // Position (0,0)

  //  Display test
  //  lcd.print("1. linje");
  //  lcd.setCursor(0,1);   // position 0-15, linje 0-1
  //  lcd.print("2. linje");
  //  lcd.clear();
}

void loop() {
  // Dispatch incoming characters
  if (ss.available() > 0) {
    gps.encode(ss.read()); 
  }
  
  if (gps.date.isUpdated()) {
    year = gps.date.year();
    month = gps.date.month();
    day = gps.date.day();
    hour = gps.time.hour();
    minute = gps.time.minute();
    second = gps.time.second();
  
    // Konvertering af tider til strenge
    dayStr = String(day);
    monthStr = String(month);
    yearStr = String(year); 
    hourStr = String(hour);
    minuteStr = String(minute);
    secondStr = String(second);
  
    // Minimum 2 cifre i værdi
    if (day < 10) { dayStr = '0'+ dayStr; }
    if (month < 10) { monthStr = ' ' + monthStr; }
    if (hour < 10) { hourStr = '0' + hourStr; }
    if (minute < 10) { minuteStr = '0' + minuteStr; }
    if (second < 10) { secondStr = '0' + secondStr; }
  
    // Færdiggør display-strenge
    dateStr = dayStr + " " + monthStr + " " + yearStr; 
    timeStr = hourStr + ":" + minuteStr + ":" + secondStr;
  
    // Til monitor
    Serial.println( dateStr + "   " + timeStr );

    // To LCD. Cleared in setup. 
    lcd.setCursor(4,0); // (position,line)
    lcd.print(timeStr);
    lcd.setCursor(3,1); 
    lcd.print(dateStr);
  }
}

Now let's make it shorter and more efficient

#include <TinyGPSPlus.h> // by Mikal Hart
#include <SoftwareSerial.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //Arduino pins for communication

static const int RxPin = 8, TxPin = 9; // TxPin bruges ikke i dette projekt
static const uint32_t GPSBaud = 9600;

// The TinyGPSPlus object
TinyGPSPlus gps;

// The serial connection to the GPS device
SoftwareSerial ss(RxPin, TxPin);

// For stats that happen every 5 seconds
unsigned long last = 0UL;

void setup() {
  Serial.begin(115200);
  ss.begin(GPSBaud);

  // Display setup
  lcd.begin(16, 2); //start LCDlibrary and set display size
  lcd.clear(); // Position (0,0)

  //  Display test
  //  lcd.print("1. linje");
  //  lcd.setCursor(0,1);   // position 0-15, linje 0-1
  //  lcd.print("2. linje");
  //  lcd.clear();
}

void loop() {
  // Dispatch incoming characters
  if (ss.available() > 0) {
    gps.encode(ss.read()); 
  }
  
  if (gps.date.isUpdated()) {
    char dateStr[17];
    char timeStr[17];

    sprintf(dateStr, "%02d %02d %02d", gps.date.day(), gps.date.month(), gps.date.year());
    sprintf(timeStr, "%02d:%02d:%02d", gps.date.hour(), gps.date.minute(), gps.date.second());
  
    // Til monitor
    Serial.print( dateStr );
    Serial.print("   ");
    Serial.println( timeStr );

    // To LCD. Cleared in setup. 
    lcd.setCursor(4,0); // (position,line)
    lcd.print(timeStr);
    lcd.setCursor(3,1); 
    lcd.print(dateStr);
  }
}
1 Like

@PaulRB
Thank you for your reply.

I think you are updating the LCD too frequently. Is it updated
each time loop() runs, even if the time has not changed.

Yes.
Now, when I had only seen the mail notification about your reply, I changed to:

if (timeStr != oldTimeStr) {  //Avoid unneeded display update
    lcd.setCursor(4, 0);  // (position,line)
    lcd.print(timeStr);
    lcd.setCursor(3, 1);
    lcd.print(dateStr);
    oldTimeStr = timeStr;
  }

and that shows that you are right.

Please always click Auto-Format in the IDE menu before
you post your code

Ok. I was not aware of that function.

I need more time to study the other suggestions you made.
Thank you.

However, I wonder why the changes on the display are slowed down by faster update.
?

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