2

Since I am an using I2C LCD backpack, I'm unable to call in for pinmode to set variables like #define BACKLIGHT_PIN 13. I know lcd.setBacklight(HIGH); and lcd.setBacklight(LOW); controls the I2C LCD backlight, but if I use delay in the loop it slows down the whole loop.

How do I flicker the LCD backlight without using delay? I tried for example to blink without delay, but I don't know how to assign a global variable to lcd.setbacklight so as to control it.

I want to use an if statement to warn the user that so and so has happened, eg:

#include <Ticker.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); 

//Ticker flashBacklight(toggleBacklight, 100);
// when I use ticker here am getting not declared in scope
const int buttonPin = 3;
int buttonState = 0;
// pls declare flashBacklight, long flashBacklight = 100; ??
// pls declare toggleBacklight

void toggleBacklight() {
  // lcd.setBacklight(!lcd.getBacklight());
  // !lcd.getbacklight() spelling mistake ? or it is setbacklight?
}

void setup() {
  lcd.begin(20, 4);
  lcd.setBacklight(HIGH);
  pinMode(buttonPin, INPUT);
 }

void loop() {
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH) {
    // if button goes high the back light must keep on flashing until it's released
    flashBacklight.start();
    //flash the lcd backlight
  } else {
    flashBacklight.stop(); // Stop flashing the backlight
  }
  flashBlacklight.update();
}

But delay slows down the whole loop, so how do I flash the backlight without it? Thank you.

2

Besides the standard 'compute a target millis() and compare' standard, which can get clunky when you have to handle more than 1 repeating or delayed event, there are also more than one decent library that abstract the concept, but also add features.

One example is the Ticker library.

With these methods, you create a callback function and pass that function name into the object constructor, along with the timing parameters.

So you might:

[various #include, #define, etc.]

Ticker flashBacklight(toggleBacklight, 100); //call toggleBacklight() every 100ms

// Create the callback function, which just toggles the backlight each call.
void toggleBacklight() {
  lcd.setBacklight( !lcd.getBacklight() );
}

setup() {
  [...]
}

loop() {
  // Start or stop the ticker based on your own situation. Once started, it will call your callback function at the specified interval until stopped.

  if (warningSituation) {
    flashBacklight.start();
  } else {
    flashBacklight.stop();
  }

  flashBlacklight.update();
}

Another related library is SimpleTimer

EDIT

Your code example, updated:

#include <Ticker.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); 

void toggleBacklight();

Ticker flashBacklight(toggleBacklight, 100); //when i use ticker here am getting not declared in scope

const int buttonPin = 3;
int buttonState = 0;    
                      // pls declare   flashBacklight   , long flashBacklight = 100;   ??
                      //   pls declare toggleBacklight   

void toggleBacklight() {
 // lcd.setBacklight( !lcd.getBacklight() );  // !lcd.getbacklight() spelling mistake ? or it is setbacklight?
}
void setup() {
   lcd.begin(20, 4);
 lcd.setBacklight(HIGH);
 pinMode(buttonPin, INPUT);
 }
void loop() {
      buttonState = digitalRead(buttonPin);
   if (buttonState == HIGH)          // if button goes high the back light must keep on flashing untill its released
   {
    flashBacklight.start();          //flash the lcd backlight
  } else {
    flashBacklight.stop();           // Stop flashing the backligh                      
 }                                  
   flashBacklight.update();
  }
| improve this answer | |
  • can you show me a example of flashing with button press example ? am getting compiler error "not declared in the scope " so if u can show me its complete usage it would be easy for me to learn , i want to put the code here,but if i do it exceed character left, how to put the code here? – ranjith Sep 6 '17 at 20:42
  • I linked to the Ticker library -- it has an example of how to use it. If you are using Arduino IDE, you will need to install the library, and #include it's header file. If you want to put a big block of code in, you can edit your original question, I believe. – jose can u c Sep 6 '17 at 20:59
  • oh.. ty library and all those installed correct,problem is global variable declaration..pls check the original question and pls help fill the gaps ..ty – ranjith Sep 6 '17 at 21:09
  • Yes sir, its global variable declaration.. pls see the above update code... – ranjith Sep 6 '17 at 21:27
  • You should move the flashBacklight function definition to before the Ticker Use. I will update my example soon. I don’t know which LCD library you are using. At least one has getBacklight(), but if yours doesn’t, you can keep track in another global. – jose can u c Sep 6 '17 at 21:38
1

You will need to alter the pin / bit tied to the backlight led.

To do that you will need to be able to read the state of all the pins on the i2c expander.

That can be done by reading back the pin state from the i2c expander or to hold the pin state in a buffer.

Once you know the pin state, you can OR or NEG it to clear or set the pin.

| improve this answer | |
  • well, this is easy method reading the state of A and k On the lcd pin, but wish to learn by using i2c and also saves digital pin, as of now every pins on my uno is used and nothing to spare :( .... – ranjith Sep 6 '17 at 21:15
  • " nothing to spare" - in that case, the answer is simple. you essentially want to change the state of a pin without having a pin connected to it. – dannyf Sep 6 '17 at 22:57
  • with that said, you can re-use one of the lcd pins, recognizing that those pins' state is only used when the state of the EN pin is going through a state change. So any other times, you can change the other pines freely without messing up the lcd display. – dannyf Sep 6 '17 at 22:58
  • ok ok, i under stood your point, for instance i define #define BACKLIGHT_PIN 2 when warning triggers pin A goes high and low , if i keep the pin A which is connected to digital pin 2 and digital write (2,high) and Low i can control its backlight, this way i must keep the pin connected always right? now from i2c point of view, lcd.setBacklight(HIGH); sets backlight high, how do i declare lcd.setBacklight(HIGH); to global variable and control it? – ranjith Sep 7 '17 at 9:43
-1

You record the timestamp when you want the LED to turn off again and then check that against millis in the loop()

  if ( level 1 > level 0) 
  {

     NewTone(4,1000,50); // initiate alarm
     blinking = true;
     lcd.setBacklight(HIGH);
     lcdToggleTime = millis();// this is a global 
     lcdOn = true;
  }else {
     blinking = false;
     lcd.setBacklight(LOW);
  }

  //at the start or end of loop(); make sure it's always checked.
if(blinking){
      if(millis() - lcdToggleTime>+100) {
         if(lcdOn)
             lcd.setBacklight(LOW);
         else
             lcd.setBacklight(HIGH);
         lcdOn = !lcdOn;
         lcdToggleTime = millis();// this is a global 
     }
}
| improve this answer | |
  • The background should turn on and off and on and off... just like the blink-without-delay example. When a value is added to millis(), then the rollover problem is introduced. See the blink-without-delay how to use millis(): arduino.cc/en/Tutorial/BlinkWithoutDelay – Jot Sep 6 '17 at 19:40
  • @jot fixed the code – ratchet freak Sep 6 '17 at 19:46
  • 3
    if (millis() > lcdToggleTime) will not work properly across a millis() rollover. The “Blink without delay” tutorial uses the idiom if (millis() - lcdLastToggle > 100), which is rollover-safe. – Edgar Bonet Sep 6 '17 at 19:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.