Arduino UNO too slow after using I2C LCD library

Hello guys,

So far I’ve been using LiquidCrystal.h library with normal LCD display and my code ran just fine.

Now I’m forced to use I2C with DFRobot DFR0063 display. Code remained the same, changed library and added lcd.backlight(), but that’s about it.

Problem: Arduino now reacts with about 1sec delay (somethimes less, it’s random), which is unacceptable in this project where I use values like 650ms or 800ms.

Is there any fix to it? Different library? (in code there is deliberate delay of turning on and of SolenoidPin, as well as 1sec update interval for display, BUT even MotorPin and VibratorPin react with this random delay when A2 is powered)

Thanks in advance!

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x20, 16, 2);

int VibratorPin = 12;
int MotorPin = 8;
int SolenoidPin = 9;
int GunPin = A2;
int Lbs = A3;

byte prevButtonGpin = 0;

unsigned long startDelayTime = 0;
unsigned long stopDelayTime = 0;
unsigned long delayOnInterval = 650;
unsigned long delayOffInterval = 800;



void setup() {
  lcd.init();
  pinMode(VibratorPin, OUTPUT);
  pinMode(MotorPin, OUTPUT);
  pinMode(SolenoidPin, OUTPUT);
  pinMode(GunPin, INPUT);
  pinMode(Lbs, INPUT);
  lcd.clear();
  lcd.backlight();
}




void loop()
{
    unsigned long currentTime = millis();
    byte buttonGpin = digitalRead(GunPin);

    if (buttonGpin != prevButtonGpin) {
      startDelayTime = currentTime;
      prevButtonGpin = buttonGpin;
    }

    static unsigned long Time;

    if (buttonGpin == LOW) {      
      digitalWrite(VibratorPin, LOW);
      digitalWrite(MotorPin, LOW);      
      if (currentTime - startDelayTime >= delayOnInterval) {
        digitalWrite(SolenoidPin, LOW);
        stopDelayTime = currentTime;

      }
      if (millis() - Time >= 1000)
      {

        Time += 1000;
        if (digitalRead(Lbs) == HIGH) {
          PotrosnjaLb();               
        }
        else {
          Potrosnja();
        }
      }
    }



    

    if (buttonGpin == HIGH)  {
      digitalWrite(VibratorPin, HIGH);
      digitalWrite(MotorPin, HIGH);
      if (currentTime - stopDelayTime >= delayOffInterval) {
        digitalWrite(SolenoidPin, HIGH);
        startDelayTime = currentTime;
      }
      
      if (millis() - Time >= 1000)
      {

        Time += 1000;
        if (digitalRead(Lbs) == HIGH) {
          WorkingLb();              
        }
        else {
          Working();
        }
      }
    }
  }


void Potrosnja() {
  lcd.backlight();
  lcd.begin(16,2);
  lcd.clear();
  lcd.setCursor(3, 0);
  lcd.print("SOMETHING");
  lcd.setCursor(0, 1);
  lcd.print("SOMETHING");
  lcd.setCursor(12, 1);
  lcd.print("SOMETHING");
  int Potenciometar = A1;
  int Pot1 = 0;
  int Pot2 = 0;
  Pot1 = analogRead(A1) / 11;
  Pot2 = Pot1 / 1.313;
  lcd.setCursor(9, 1);
  lcd.print(Pot2);
}

void Working() {
  lcd.backlight();
  lcd.begin(16,2);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("SOMETHING");
  lcd.setCursor(0, 1);
  lcd.print("SOMETHING");
  lcd.setCursor(12, 1);
  lcd.print("SOMETHING");
  int Potenciometar = A1;
  int Pot1 = 0;
  int Pot2 = 0;
  Pot1 = analogRead(A1) / 11;
  Pot2 = Pot1 / 1.313;
  lcd.setCursor(9, 1);
  lcd.print(Pot2);
}


void WorkingLb() {
  lcd.backlight();
  lcd.begin(16,2);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("SOMETHING");
  lcd.setCursor(0, 1);
  lcd.print("SOMETHING");
  lcd.setCursor(12, 1);
  lcd.print("SOMETHING");
  int Potenciometar = A1;
  int Pot1 = 0;
  int Pot2 = 0;
  Pot1 = analogRead(A1) / 6.572;
  Pot2 = Pot1 / 1.007;
  lcd.setCursor(9, 1);
  lcd.print(Pot2);
}


void PotrosnjaLb() {
  lcd.backlight();
  lcd.begin(16,2);
  lcd.clear();
  lcd.setCursor(3, 0);
  lcd.print("SOMETHING");
  lcd.setCursor(0, 1);
  lcd.print("SOMETHING");
  lcd.setCursor(12, 1);
  lcd.print("SOMETHING");
  int Potenciometar = A1;
  int Pot1 = 0;
  int Pot2 = 0;
  Pot1 = analogRead(A1) / 6.572;
  Pot2 = Pot1 / 1.007;
  lcd.setCursor(9, 1);
  lcd.print(Pot2);
}

I would start by taking the lcd.backlight() and lcd.begin() function calls out of your functions. They only need to be done once in setup()

1 Like

Greetings,

Is the reaction problem that you mentioned casused by the buttons?

Thank you UKHeliBob. This seems to be working.

lcd.begin() was used in every function in my previous code (without I2C) because during machine’s operation display would just show random characters and leave them displayed until restart. lcd.begin() helped resolve that issue and “reset” display when changing functions.

Any idea why that problem occurred in first place and will it happen with I2C also?
(Arduino controls VFD, solenoid, relay and works in extreme ESD environment).

Hi,
You can speed your code up further by only updating parts of your display if there is a change in data.
You do not have to use lcd.clear.
When you go to update part of your display, immediately before updating, place spaces over the old data to clear the info, then write the new.

Tom… :grinning: :+1: :coffee: :australia:

Greetings, thank you for taking time to reply.

What buttons? If you mean physical buttons that give signal to Arduino, they are the same as with previous code and there is no delay on them.

Thank you TomGeorge,

In future text and data to be displayed can be changed and can change it’s position on LCD display so this seemed like more of “universal” solution.

Greetings,

I totally missunderstood the problem. Sorry.

Yep, same problem again, without implementing lcd.begin display somethimes starts showing random symbols until restart of the machine, everything else works fine, it’s like it looses instruction it receives during setup()…
Any suggestion?

Thanks in advance!

The best and fastest library to use with the i2c lcd displays is Bill Perry’s hd44780.h

This library is available through the library manager.

Go to Library Manager (in the IDE menus, Sketch, Include Libraries, Manage Libraries) and in the Topics dropdown choose Display and in the Filter your search box enter hd44780. Select and install the hd44780.h library by Bill Perry.

The class that you want to use is the hd44780_I2Cexp class.

There are examples to show how to use the library. The nice thing about the hd44780.h library is that it will autodetect the I2C address and the I2C backpack to LCD pin mapping. It is plug and play for any of the possible display chip wiring configurations.

Get that library installed, and come back with your results on “reaction time”. We can work on optimizing the sketch when we know where you are at with the fastest display library.

Thanks @cattledog for your time and help.
This seems to be working fine even with lcd.begin(); in every function.
Problem I’m now having is backlight, can’t get it to turn on even with lcd.backlight() (although it should turn on automatically).

Idea how to turn on backlight with this library?

Thanks in advance!

backlight() and noBacklight() are supported commands by the library and I believe that it is on by default.

Could the backlight be turned on and off with the previous library?

There is a diagnostic sketch as part of the library I2CexpDiag. Run it and see if the backlight blinks during the test, and if the results indicate anything about the backlight.

Did the backlight blink when you ran the I2CexpDiag sketch from the hd44780 library?

Does your backpack have a 2 pin header on the side?
Many have a two pin header on them with a shunt connector on it that controls/affects backlight operation. Most of them disable the backlight (i.e. always off) if the jumper is removed. Some of them are reversed, in that installing the jumper forces the backlight to always be on.

Another possibility is that you have one the less common backpacks that either uses a an FET for backlight control or uses a bad backlight circuit. Either of those will cause the hd44780 library to improperly detect the backlight active level.
If that is the case, then noBacklight() will turn on the backlight and backlight() will turn off the backlight.

Can you post a photo of your backpack?

Yes, thanks for suggestion, finally tried it and noBacklight() did the job. First I've gave up on backlight control and soldered it directly, but this works now as intended.
Thanks again.

Also, THANK YOU EVERYONE, I hope this will help someone else in similar situation, all of the problems I've had with this library and display combo are now solved!