LCD Backlight issue.

Hello Pro,

I am having a crazy issue with the LCD backlight. I modified a DHT22 I2C LCD sketch and have gotten the sketch to work with one exception.. THE LCD BACKLIGHT! I have tried placing it in multiple locations, the latest is highlighted in red... Can anyone help me. I need to see this through a plastic bin I am testing a dehumidifier in... it is terrible without backlight but will not stop me..

If you can point out what in the library I am defining incorrectly it would help grandly .. Thanks in advance.

/* How to use the DHT-22 sensor with Arduino uno
Temperature and humidity sensor
More info: Temperature and Humidity - DHT22 and Arduino - Ardumotive Arduino Greek Playground
Dev: Michalis Vasilakis // Date: 1/7/2015 // www.ardumotive.com
*/

//Libraries
#include <DHT.h>
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

//Constants
#define DHTPIN 7 // what pin we're connected to
#define DHTTYPE DHT22 // DHT 22 (AM2302)
DHT dht(DHTPIN, DHTTYPE); //// Initialize DHT sensor for normal 16mhz Arduino

//ALWAYS USE THIS WITH LCD I2C and Addres 0x3F
#define I2C_ADDR 0x27
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

//Variables
int chk;
float hum; //Stores humidity value
float temp; //Stores temperature value

void setup()
{
Serial.begin(9600);
dht.begin();
lcd.begin(16,2);

}

void loop()
{

delay(2000);
//Read data and store it to variables hum and temp
hum = dht.readHumidity();
temp = dht.readTemperature();
//Print temp and humidity values to serial monitor
Serial.print("Humidity: ");
Serial.print(hum);
Serial.print(" %, Temp: ");
Serial.print(temp);
Serial.println(" Celsius");
lcd.backlight(); // turn on backlight
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Temp: ");
lcd.print(temp);
lcd.print(" ");
lcd.print((char)223);
lcd.print("C");
lcd.setCursor(0,1);
lcd.print("Hum: ");
lcd.print(hum);
lcd.print(" %");

delay(2000); //Delay 2 sec.

}

Think of your program as a list of instructions that get run from top to bottom. First the setup portion gets run once and then the loop goes over and over. When do you want to turn the backlight on? Do you want to turn it on from the beginning and just leave it on? Or do you want to print a few things, then turn it on, then print the rest of your stuff over and over?

I had it right after lcd.begin and got nothing. Should it be before lcd.begin?
Like this:

void setup()
{
Serial.begin(9600);
dht.begin();
lcd.begin(16,2);
lcd.backlight(); // turn on backlight

To this:

void setup()
{
Serial.begin(9600);
dht.begin();
lcd.backlight(); // turn on backlight
lcd.begin(16,2);

Hi,
Welcome to the forum.

Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks.. Tom.. :slight_smile:

Hi,
How come your code is very similar to this?

http://forum.arduino.cc/index.php?topic=522065.0

Tom... :slight_smile:

I reviewed your post Tom. I can't upload the sketch ATM but I made changes and hopefully they will work.

/* How to use the DHT-22 sensor with Arduino uno
   Temperature and humidity sensor
   More info: http://www.ardumotive.com/how-to-use-dht-22-sensor-en.html
   Dev: Michalis Vasilakis // Date: 1/7/2015 // www.ardumotive.com 
*/

//Libraries
#include <DHT.h>
#include <Wire.h> 
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

//Constants
#define DHTPIN 7     // what pin we're connected to
#define DHTTYPE DHT22   // DHT 22  (AM2302)
DHT dht(DHTPIN, DHTTYPE); //// Initialize DHT sensor for normal 16mhz Arduino

//ALWAYS USE THIS WITH LCD I2C and Addres 0x3F
#define I2C_ADDR 0x27
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
LiquidCrystal_I2C lcd(0x27,16,2);

//Variables
int chk;
float hum;  //Stores humidity value
float temp; //Stores temperature value

void setup()
{
  Serial.begin(9600);
  dht.begin();
  lcd.init();
  lcd.backlight(); // turn on backlight
  lcd.begin(16,2);

}

void loop()
{
  
  delay(2000);
  //Read data and store it to variables hum and temp
  hum = dht.readHumidity();
  temp = dht.readTemperature();
  //Print temp and humidity values to serial monitor
  Serial.print("Humidity: ");
  Serial.print(hum);
  Serial.print(" %, Temp: ");
  Serial.print(temp);
  Serial.println(" Celsius");
  
  
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Temp: ");
  lcd.print(temp);
  lcd.print(" ");
  lcd.print((char)223);
  lcd.print("C");
  lcd.setCursor(0,1);
  lcd.print("Hum:  ");
  lcd.print(hum);
  lcd.print(" %");

  delay(2000); //Delay 2 sec.

}

ArduLost:
I had it right after lcd.begin and got nothing. Should it be before lcd.begin?

If you have initialized the library properly, the backlight will be on when begin() returns.
There is no need to call backlight()
If the library is not initialized properly, then calls to backlight() and noBacklight() will not work.
The sample code in the very first sketch has not told the library (fm's newLiquidCrystal) that backlight control is available and how it works.
The sample code in post #5 is using the headers from one library (fm's newLiquidCrystal) but then attempting to use API costructors and functions from a different library (IDE library manager LiquidCrystal_I2C).

There are many different libraries that use a LiquidCrystal_I2C class so it can be confusing since they are installed differently, initialized differently, and work slightly differently.
For using fm's new LiquidCrystal library you may see people doing this in setup() to set things up for backlight control:

lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
  lcd.setBacklight(HIGH);

This is not correct.
setBacklightPin(pin, polarity) is used to configure the library, but only if the constructor used was incomplete.
It is a leftover function from the very early days of the library before the library constructor was expanded to support to backlight control. It only still exists for backwards compatibility for sketches that were written for very old versions of the library.
setBacklightPin() should no longer be used.
And then setBacklight(HIGH) is completely wrong
The real prototype is setBacklight(dimlevel).
Using HIGH as a dimlevel is not telling the library to turn the backlight on but rather is telling the library to make the backlight as dim as possible.

If using fm's newLiquidCrystal library and you want backlight control, you should use the constructor that tells the library how to control the backlight.

LiquidCrystal_I2C(2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin,bl_pin,bl_polarity);

Where bl_pin is the PCF8574 Px pin or output port bit number that controls the backlight circuit, and bl_polarity is either POSITIVE or NEGATIVE depending on the particular backlight circuit used on the backpack.

So in the code in the first post, if you were to fill in the constructor with the backlight information, begin() will automatically turn on the backlight() and backlight() and noBacklight() would work.


Alternatively, I would suggest that you have a look at my hd44780 library.
It will automatically locate the backpack i2c address and will automatically determine the pin mappings and the backlight control parameters.
It can also be installed by using the IDE library manager.
This makes it much easier to use.
You can read more about it on the github page: GitHub - duinoWitchery/hd44780: Extensible hd44780 LCD library
Or its wiki: Home · duinoWitchery/hd44780 Wiki · GitHub

The i/o class for i2c LCD backpacks is hd44780_I2Cexp.
I would first recommend running the included I2CexpDiag sketch to verify that the library and the LCD are properly working.
Then, look at an hd44780_I2Cexp example sketch like HelloWorld to see the needed include files and how to declare the lcd object.

--- bill

Thanks Bill! You are awesome, and appreciate the work you did on the LCD!

Did you get it working?

Hi,
Bill can you explain this statement;

LiquidCrystal_I2C(2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin,bl_pin,bl_polarity);

If you are using I2C, why do you need to allocate pins to all the ones listed, I2C is used to minimise the pins being used?
The extras are the pins you would allocate to a 4bit parallel connection.

Tom... :slight_smile:

TomGeorge,
The short answer is that the pin #s in the constructor are not Arduino pins.
They are telling the library how the PCF8574 is wired up to the LCD.


Details:
A PCF8574 chip is an i2c i/o port expander. It has a single input/output port with 8 pins.
In the datasheet these are called the Pn (P0, P1, .... P7) pins.
The Arduino can control these pins over the i2c bus.

There is no standard for how the eight PCF8574 input/output port pins are wired up to the LCD and how the backlight is controlled.
Different manufacturers do it differently. Some ways are more popular than others.

The library must know which pins to wiggle the PCF8574 output port pins to control the hd44780 LCD signals as well as control the backlight circuit.

The LiquidCrystal_I2C library in the IDE (like most other "LiquidCrystal_I2C" libraries) hard codes the PCF8574 to LCD pin mappings and lcd backlight control.
This is why with that library you only have to specify the I2C address and LCD geometry.
This makes it fairly easy to use but it doesn't work with all LCD backpacks. So if you happen to have a backpack that uses a different pin mapping or backlight control than what the library assumes, this library will not work.

fm's newLiquidCrystal library, on the other hand, is designed to work with any i2c backpack.
But to do that, the library must be told how the PCF8574 pins are wired up to the hd44780 LCD.
The constructor is used to tell the library this information.

The LiquidCrystal_I2C constructor used in the LiquidCrystal_I2C class of the newLiquidCrystal library is used to tell the library how the PCF8574 output port pins are wired up to the LCD.
These pins have nothing to do with Arduino pins.
The early versions of the NewLiquidCrystal library did not support backlight control.
The later versions have it and the constructor was expanded to pass in the needed configuration parameters.

The hd44780 library is also designed to work with any i2c backpack but it is smart enough to locate the i2c address of the backpack as well as probe the backpack to learn how the PCF8574 pins are wired up to the LCD and how the backlight works.
There are a few backpack designs where the backlight active level is incorrectly determined because the i2c backpacks are not using a proper transistor circuit or in one case are using an FET insteand of a NPN or PNP transistor.
For those cases (which are quite rare) auto-detection of the pin mappings cannot be used and the user must manually specify the pin mapping information similar to fm's newLiquidCrystal LiquidCrystal_I2C class.

The advantage of using the hd44780_I2Cexp i/o class over the others is that the i2c address and pin mapping is determined runtime. This means that you can swap out the LCD with another LCD and the code does not have to be recompiled even if the i2c address or the pin mapping changed.
In fact you can swap out a PCF8574 based backpack for the Adafruit MCP23008 backpack and it still "just works" (after a reset) even though not only is the i2c address different, but the expander chip and the pin mappings used are different.

--- bill

bperrybap:
TomGeorge,
The short answer is that the pin #s in the constructor are not Arduino pins.
They are telling the library how the PCF8574 is wired up to the LCD.


No problems.. It is confusing because it looks like they are Arduino I/O pins being allocated.
Can I make a suggestion and you change the name of the library so we know when we are using yours?

Such as;

LiquidCrystal_I2C_Multifit

Tom.. :slight_smile:

my library is called hd44780 and the i/o class is hd44780_I2Cexp.
I think it is pretty obvious that it is a different library from any of the "LiquidCrystal".... libraries.

And that is why I recommend using hd44780 over any of the others.
There are simply too many "LiquidCrystal" libraries out there with the same and/or similar names and they don't install the same, intialize the same or work the same.

hd44780 is its own separate library.
It installs using the library manager and does not override or conflict with any other LCD/LiquidCrystal library.

--- bill

bperrybap:
Did you get it working?

Yes! I plugged DHT22 portions into the Hello World you said to reference. Thanks!

ArduLost:
Yes! I plugged DHT22 portions into the Hello World you said to reference. Thanks!

Hi,
Can you post your complete working code please?
This will make this thread worthwhile when others look in it with a similar problems.
Thanks..Tom... :slight_smile: