Go Down

Topic: I2C LCD toggle backlight (Read 161 times) previous topic - next topic

aussietom

Hi everyone,

So i've got a standard DHT temp/humidity monitor displaying to a 16x2 I2C lcd screen working no problems, but i want to add a momentary button to toggle the backlight on and off.

The problem im having is finding a way to impliment the backlight controls

lcd.backlight()
and
lcd.nobacklight()

Im using the NewLiquidCrystal library.


The compiler is seeing the lcd.*backlightstate* as a boolean value

exit status 1
could not convert 'lcd.LiquidCrystal_I2C::<anonymous>.LCD::backlight()' from 'void' to 'bool'

is there an easier way to do this?

I am aware the code is a mess, ive cut and pasted bits of code from other sketches and havent had a chance to tidy it up and make it logical yet. Hopefullt ive commented it enough for everyone to understand my train of thought though.

Code: [Select]
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
#include <Wire.h>


#define DHTTYPE DHT22   // DHT 22 (AM2301)
#define DHTPIN 2     // what digital pin we're connected to
DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal_I2C  lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

/***********************************************************************
                Digital pin 3 normaly low
  momentary button connected to toggle LCD backlight state when pressed.
  using millis() for debounce
 ***********************************************************************/

const int buttonPin = 3;   //digital pin button is connected to

int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin

// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 50;    // the debounce time; increase if the output flickers


void setup()   /*----( SETUP: RUNS ONCE )----*/
{

  pinMode(buttonPin, INPUT);  //initialise button pin as input


  lcd.begin(16, 2);       // initialize the lcd for 20 chars 4 lines, turn on backlight
  lcd.backlight();
  dht.begin();

}/*--(end setup )---*/

void loop()   /*----( LOOP: RUNS CONSTANTLY )----*/
{

  /********************************************************************
   *Read DHT sensor and display to I2C LCD screen
   ********************************************************************/
  {
    // Reading temperature or humidity takes about 250 milliseconds!
    // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
    float h = dht.readHumidity();
    // Read temperature as Celsius (the default)
    float t = dht.readTemperature();
    // Read temperature as Fahrenheit (isFahrenheit = true)
    float f = dht.readTemperature(true);




    lcd.setCursor(0, 0);    //Set cursor at start of first line

    lcd.print("Temp ");
    lcd.print(t);
    lcd.print((char)223);   //Degree symbol (°)
    lcd.print("C");


    lcd.setCursor(0, 1);    //Set cursor at start of second line
    lcd.print("Humidity ");
    lcd.print(h);
    lcd.print("%");
  }

  /*****************************************************************************
     Button debounce code
   *****************************************************************************/


  // read the state of the switch into a local variable:
  int reading = digitalRead(buttonPin);

  // check to see if you just pressed the button
  // (i.e. the input went from LOW to HIGH),  and you've waited
  // long enough since the last press to ignore any noise:

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer
    // than the debounce delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;

      // change the backlight state
      if (buttonState != lastButtonState) { //if buttonState is not equal to lastButtonState
      { if (lcd.backlight()) {
            lcd.nobacklight()
          };
          else if (lcd.nobacklight()) {
            lcd.backlight()
          };
        }
      }
    }
  }
}


/* --(end main loop )-- */

aarg

The compiler is seeing the lcd.*backlightstate* as a boolean value

Well, as it is an on/off function, does it not make sense for it to be a boolean value?
  ... with a transistor and a large sum of money to spend ...
Please don't PM me with technical questions. Post them in the forum.

aussietom

#2
Apr 16, 2016, 02:23 pm Last Edit: Apr 16, 2016, 02:29 pm by aussietom
Well, as it is an on/off function, does it not make sense for it to be a boolean value?
I suppose, but the library as far as i understand it only sees .backlight or .nobacklight. It cannot have a true false value when read like that, else it would be .backlight(true) or .backlight(false) wouldnt it?

here is the complete error message.
Code: [Select]

Arduino: 1.6.7 (Windows 7), Board: "Arduino Nano, ATmega328"

E:\Users\Tom\Documents\Arduino\working_temp_monitor_code\working_temp_monitor_code.ino: In function 'void loop()':

working_temp_monitor_code:96: error: could not convert 'lcd.LiquidCrystal_I2C::<anonymous>.LCD::backlight()' from 'void' to 'bool'

      { if (lcd.backlight()) {

                          ^

working_temp_monitor_code:97: error: 'class LiquidCrystal_I2C' has no member named 'nobacklight'

            lcd.nobacklight()

                ^

working_temp_monitor_code:98: error: expected ';' before '}' token

          };

          ^

working_temp_monitor_code:99: error: expected '}' before 'else'

          else if (lcd.nobacklight()) {

          ^

working_temp_monitor_code:99: error: expected '}' before 'else'

working_temp_monitor_code:99: error: 'class LiquidCrystal_I2C' has no member named 'nobacklight'

          else if (lcd.nobacklight()) {

                       ^

working_temp_monitor_code:101: error: expected ';' before '}' token

          };

          ^

E:\Users\Tom\Documents\Arduino\working_temp_monitor_code\working_temp_monitor_code.ino: At global scope:

working_temp_monitor_code:105: error: expected declaration before '}' token

  }

  ^

exit status 1
could not convert 'lcd.LiquidCrystal_I2C::<anonymous>.LCD::backlight()' from 'void' to 'bool'

 This report would have more information with
 "Show verbose output during compilation"
 enabled in File > Preferences.



I can see why it doesn't compile, but i cant see how else to give the command

aussietom

Well, as it is an on/off function, does it not make sense for it to be a boolean value?
Maybe the question should be,

how do i convert the bool (true/false) to the .backlight/ .nobacklight?

outsider

#4
Apr 16, 2016, 06:53 pm Last Edit: Apr 16, 2016, 07:16 pm by outsider
You need the LiquidCrystal_I2C2004V1 library. But first, make sure your backpack supports that, ones I have are externally controlled by an output pin.

From NewCrystalLibrary, LiquidCrystal_I2C.h:
Quote
/*!
    @function
    @abstract   Sets the pin to control the backlight.
    @discussion Sets the pin in the device to control the backlight. This device
    doesn't support dimming backlight capability.
   
    @param      0: backlight off, 1..255: backlight on.
    */
   void setBacklightPin ( uint8_t value, t_backlighPol pol );
   
   /*!
    @function
    @abstract   Switch-on/off the LCD backlight.
    @discussion Switch-on/off the LCD backlight.
    The setBacklightPin has to be called before setting the backlight for
    this method to work. @see setBacklightPin.
   
    @param      value: backlight mode (HIGH|LOW)
    */
   void setBacklight ( uint8_t value );

aarg

According to the error message, you are just calling a method that doesn't exist.
  ... with a transistor and a large sum of money to spend ...
Please don't PM me with technical questions. Post them in the forum.

aussietom

According to the error message, you are just calling a method that doesn't exist.
I get that, but what im saying is i cant see how to do it any other way. I think im using the if/else structure wrong.
You need the LiquidCrystal_I2C2004V1 library. But first, make sure your backpack supports that, ones I have are externally controlled by an output pin.

From NewCrystalLibrary, LiquidCrystal_I2C.h:
I can control it with a seperate pin, but i dont want to. I plan to keep the 4 wire interface in the final project. I tried to create an argument using the backlight mode and ended up with the same error, as well as not realy knowing how to use the void setBacklightPin function.

aussietom

Ok, so i got it to compile,

Code: [Select]
/*
 * Temperature monitor boards running DHT 11/22 temp/humidity sensor and I2C LCD screen (16x2 currently)
 * External momentary switch on pin 3 to toggle LCD backlight
 * switch debounce and sensor read interval using 'millis' timers
 *
 * AUSSIE_TOM
 */



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


#define DHTTYPE DHT22   // DHT 22 (AM2301)
#define DHTPIN 2     // what digital pin we're connected to
DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal_I2C  lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);   // addr, EN, RW, RS, D4, D5, D6, D7, BacklightPin, POLARITY

/***********************************************************************
                Digital pin 3 normaly low
  momentary button connected to toggle LCD backlight state when pressed.
  using millis() for debounce
 ***********************************************************************/

const int buttonPin = 3;   //digital pin button is connected to

int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin
int backlightValue = 255;
// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 50;    // the debounce time; increase if the output flickers
bool backlightState = true;


/***********************************************************************
   MILLIS timer for read sensor and display on LCD screen
 ***********************************************************************/

unsigned long previousMillis = 0;     //
const long interval = 1000;           //




void setup()   /*----( SETUP: RUNS ONCE )----*/
{

  pinMode(buttonPin, INPUT);  //initialise button pin as input


  lcd.begin(16, 2);       // initialize the lcd for 20 chars 4 lines, turn on backlight
  lcd.setBacklight(BACKLIGHT_ON);
  dht.begin();

  lcd.setCursor(0, 0);    //Set cursor at start of first line
  lcd.print ("TEMP/HUMIDITY");
  lcd.setCursor(0, 1);    //Set cursor at start of second line
  lcd.print ("AUSSIE TOM");

  delay(5000);


}/*--(end setup )---*/

void loop()   /*----( LOOP: RUNS CONSTANTLY )----*/
{
  {
    /*******************************************************************************
        TIMER code for sensor read

     *******************************************************************************/
    unsigned long currentMillis = millis();

    if (currentMillis - previousMillis >= interval) {
      // save the last time sensor was read
      previousMillis = currentMillis;

      /********************************************************************
        Read DHT sensor and display to I2C LCD screen
       ********************************************************************/
      {
        // Reading temperature or humidity takes about 250 milliseconds!
        // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
        float h = dht.readHumidity();
        // Read temperature as Celsius (the default)
        float t = dht.readTemperature();
        // Read temperature as Fahrenheit (isFahrenheit = true)
        float f = dht.readTemperature(true);



        lcd.clear();
        lcd.setCursor(0, 0);    //Set cursor at start of first line
        lcd.print("Temp ");
        lcd.print(t);
        lcd.print((char)223);   //Degree symbol (°)
        lcd.print("C");


        lcd.setCursor(0, 1);    //Set cursor at start of second line
        lcd.print("Humidity ");
        lcd.print(h);
        lcd.print("%");
      }
    }
  }
  /*****************************************************************************
     Button debounce code
   *****************************************************************************/


  // read the state of the switch into a local variable:
  int reading = digitalRead(buttonPin);

  // check to see if you just pressed the button
  // (i.e. the input went from LOW to HIGH),  and you've waited
  // long enough since the last press to ignore any noise:

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer
    // than the debounce delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;

      // change the backlight state
      if (buttonState != lastButtonState) { //if buttonState is not equal to lastButtonState, run 'change backlight state' code

        /*****************************************************************************
           END OF DEBOUNCE CODE
        *****************************************************************************/

        /****************************************************************************
           CHANGE BACKLIGHT STATE CODE
         ****************************************************************************/


        if (backlightState == true) {     //check to see state of backlight
          backlightState = false;         //flip state of backlight
        }
        else if (backlightState == false) {
          backlightState = true;
        }



        if ( backlightState == true) {        //the bool argument for backlight state (true/false)
          lcd.setBacklight(BACKLIGHT_ON);     //the statement that actualy changes the backlight state
        }
        else if ( backlightState == false) {
          lcd.setBacklight(BACKLIGHT_OFF);
        }
      }
    }
  }
}
/* --(end main loop )-- */


Seems like a convoluted way to achieve the desired result, but anyway, it works.

Thanks for the help

UKHeliBob

Quote
Seems like a convoluted way to achieve the desired result,
Try this (untested)
Code: [Select]

        /****************************************************************************
           CHANGE BACKLIGHT STATE CODE
         ****************************************************************************/

  backlightState = !backlightState;
  lcd.setBacklight(backlightState);
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy