Serial LCD Very slow updating

Serial LCD is connected to an DUE via WIRE.

Removed pull up from board and not using Serial LCD pull ups.

Pull up on interface board are 4.7K.

The Init code is this

  Wire.begin();
  Wire.setClock(400000); //Optional - set I2C SCL to High Speed Mode of 400kHz
  lcd.begin(Wire);
  lcd.disableSystemMessages(); 
  lcd.setBacklight(255, 255, 255); //Set backlight to bright white
  lcd.setContrast(5); //Set contrast. Lower to 0 for higher contrast.

The code updating the display is:

lcd.clear();
  bout << dec << setw(2) << setfill('0') << (uint16_t)OutputData.hour << F(":") << dec << setw(2) << setfill('0') << (uint16_t)OutputData.min << F(":") << dec << setw(2) << setfill('0') << (uint16_t)OutputData.sec;
  BuffLCDOutput (obuffer, LCDOutColumn[LCDEntry], LCDOutRow[LCDEntry]);
  bout.seekp(0);
  LCDEntry++;
  bout << dec << setw(2) << setfill('0') << (uint16_t)OutputData.month << F("/") << dec << setw(2) << setfill('0') << (uint16_t)OutputData.day << F("/") << dec << setw(4) << setfill('0') << (uint16_t)OutputData.year;
  BuffLCDOutput (obuffer, LCDOutColumn[LCDEntry], LCDOutRow[LCDEntry]);
  bout.seekp(0);
  LCDEntry++;
  bout <<F("Spd:") << dec << setw(4)<< setfill(' ') << (((uint32_t)OutputData.gSpeed * 36) / 10000);
  BuffLCDOutput (obuffer, LCDOutColumn[LCDEntry], LCDOutRow[LCDEntry]);
  bout.seekp(0);
  LCDEntry++;
  bout << F("Alt:") << dec << setw(4)<< setfill(' ') << ((uint32_t)OutputData.height / 1000);
  BuffLCDOutput (obuffer, LCDOutColumn[LCDEntry], LCDOutRow[LCDEntry]);
  bout.seekp(0);
  LCDEntry++;
  bout << F("Fix: ") << dec << (uint16_t)OutputData.gpsFix;
  BuffLCDOutput (obuffer, LCDOutColumn[LCDEntry], LCDOutRow[LCDEntry]);
  bout.seekp(0);
  LCDEntry++;
  bout << F("Dir:") << dec << setw(4)<< setfill(' ') << ((uint32_t)OutputData.headMot / 100000);
  BuffLCDOutput (obuffer, LCDOutColumn[LCDEntry], LCDOutRow[LCDEntry]);
  bout.seekp(0);
  LCDEntry++;
  if (GPS_calibrated)
  {
    bout << F("xAcl:") << dec << setw(4)<< setfill(' ') << (((uint32_t)OutputData.xAccel) / 100);
    BuffLCDOutput (obuffer, LCDOutColumn[LCDEntry], LCDOutRow[LCDEntry]);
    bout.seekp(0);
    LCDEntry++;
    bout << F("Ptch:") << dec << setw(4)<< setfill(' ') << ((uint32_t)OutputData.pitch / 100000);
    BuffLCDOutput (obuffer, LCDOutColumn[LCDEntry], LCDOutRow[LCDEntry]);
    bout.seekp(0);

According to micros(), the code runs in 0.48ms, repeatably but it take the disply 2 seconds to update.

Why?

To be complete, the subroutine called here is:

void BuffLCDOutput (char abuffer[], const uint8_t column, const uint8_t row)
{
  lcd.setCursor(column, row);
  lcd.write(abuffer);
}

Thanks for any help in advance.

Update on the above. My math was incorrect. It was 480002 micro seconds which is 0.48 seconds! It is taking 1/2 a second to run this?

Why?

I also tried the sprintf method of doing this:

char buf[21];
  uint32_t lapsetime;
  lapsetime = micros();
  lcd.clear();
  lcd.home();
  sprintf(buf, "%02d:%02d:%02d", (uint16_t)OutputData.hour,(uint16_t)OutputData.min,(uint16_t)OutputData.sec);
  lcd.print(buf);
  sprintf(buf, "%02d/%02d/%04d", (uint16_t)OutputData.month,(uint16_t)OutputData.day ,(uint16_t)OutputData.year);
  lcd.setCursor(10,0);
  lcd.print(buf);
  sprintf(buf, "Spd:%5d",(((uint32_t)OutputData.gSpeed * 36) / 10000));
  lcd.setCursor(0,1);
  lcd.print(buf);
  sprintf(buf, "Alt:%5d", ((uint32_t)OutputData.height / 1000));
  lcd.setCursor(10,1);
  lcd.print(buf);
  sprintf(buf, "Fix:%5d",(uint16_t)OutputData.gpsFix);
  lcd.setCursor(0,2);
  lcd.print(buf);
  sprintf(buf, "Hed:%5d",((uint32_t)OutputData.headMot / 100000));
  lcd.setCursor(10,2);
  lcd.print(buf);
  if (GPS_calibrated)
  {
    sprintf(buf, "xAcl:%5d", (((uint32_t)OutputData.xAccel) / 100));
    lcd.setCursor(0,3);
    lcd.print(buf);
    sprintf(buf, "Ptch:%5d",((uint32_t)OutputData.pitch / 100000));
    lcd.setCursor(10,3);
    lcd.print(buf);
  }
  Serial<<(micros() - lapsetime)<<F("\n");

Takes same time to execute as the “obustream” method. I think it must be the “lcd.print”?

Help!

On more update. If I remove the LCD overhead I complete the same calc in 20ms which still seems like a long time but much shorter than 500 ms like with the serial LCD writes.

Why are the serial LCD writes so slow?

Thanks

Bruce

Well, I know one thing I am changing…sprintf does the same calcs in 200 ms so I guess that is the winner! There but that still does not fix the LCD write issues.

Hitachi HD44780 based LCD’s are pretty old technology and a lot of instructions require delays when processing commands. 1/2 a second does sound excessive though, if you just write out 32 characters of text, does that speed things up? You may need to experiment with your code to write any static text to the display and then just update the the areas that need updating with dynamic data.

I2C on the Due is known to be a bit buggy, have you tried using the SPI interface to rule out some I2C wackiness?

I switched to the nano 33 iot and it is really no better.

The problem is the display needs to update everywhere because new data comes in continuously.

The real big problem is that is just slows every thing down.

How do I just write on continuous set of data? what I need to switch between lines?

Is there a way to put this in the text to get is to switch from one line to the other without using the set cursor command?

The biggest issue is the writes are blocking the program from executing so nothing else can run at the same time.

I was thinking of trying UART as the DUE as a lot of them.

OK, now I am really stumped.

I converted to UART Serial3, which I was just streaming 30 hz GPS data (130 bytes per message).

The formatting and calcs takes 200 micro seconds.

When I add the LCD print statements in there it takes 0.5 seconds!

The only thing that makes since is something in the library takes for ever to output the data?

Does that make since?

Any ideas?

Thanks

Bruce

Ok, it is the library…if I print the commands/text directly via serial3 the reduced the overheat by 1000+ times.

The library is causing the very slow IO performance.

Don’t know why as I did not right it.

Thanks

I made a quick and dirty LCD commands only my own using direct Serial prints and update the whole LCD take ~ 100 micro with no issues.

The delays are not needed for serial input what so every.

This is 100% a library issue. I have not messed around with the QWIIC implementation because I have plenty of UART ports. But basically if the delays are needed for I2C then the LCD is useless for any real time application because of the delays.

Thanks

Bruce