LCD 2004 display, I2C and brightness

I have a set of 20x4 LCD screens with the i2c module attached. As one is going in a bedroom I'm trying to use a pair of photoresistors in parallel connected to the ba klight jumper pins so when dark - the screen is very dim but when the light is on it's bright enough to read.

The issue is that the resistance with ambient light is still too high even with 2 photoresistors unless I shine a bright light directly on them.

Has anyone else approached this issue or might there be a way by integrating a photoresistor to control the screen brightness?

The way that the backlight works on my 20x4 is that 5V connects to the lower LED jumper pin and the upper pin goes through the backlight LEDs and to the expander chip pin 3. When the backlight is enabled, expander pin 3 sinks current and lights the backlight. You can gain control of the backlight brightness by removing the jumper marked LED on the backpack and connecting a PWM output to the upper pin of the jumper pins (on my backpack, examine yours to see if it is the same). Enable backlight in code and use analogWrite to adjust the PWM to give the brightness required. Connect one photoresistor to an analog port (with a voltage divider). Read the photoresistor voltage and use that to set the PWM for the backlight control pin. There is no way that I know of to use a photoresistor(s) to control current to the backlight. So measure the light with photoresistor and control backlight with PWM based on light reading.

code to illustrate PWM backlight control

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

//#define I2C_ADDR    0x3f
#define I2C_ADDR    0x27  // Define I2C Address where the PCF8574A is
#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

const byte backlitePin = 3;

LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

void setup(){
  lcd.begin (20,4);
  analogWrite(backlitePin, 128);
  delay(2000);  
  // Switch on the backlight
  lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
  lcd.setBacklight(HIGH);  // some controllers allow brightness control (mine does not).
  lcd.clear();
  lcd.write(48);
  lcd.setCursor(0,1);
  lcd.print(48);
  delay(2000);
  analogWrite(backlitePin, 64);
  delay(2000);
  analogWrite(backlitePin, 255);
}

void loop() {
  
}

Just to clarify: 5V > Photoresistor > Pin A7 for example?

Wired like attached, the voltage at the analog input will be near 0V when dark and the voltage will increase toward 5V with more light. You can make it more "sensitive" by lowering the value of R2. I would go no lower than 1K.

CDS.jpg

EDIT: I have been informed that the photo resistor is wired wrong and I agree. The photoresistor should be wired between an input and ground and the internal pull up enabled. No external resistor required.

Hrm, LDR's are in K-Ohm so in darkness it's close to 120K Ohm (36K Ohm in room light) and the Arduino isn't picking up a reliable Analog reading..
I'm going to get some Arduino 5528 Modules instead.

How is the photo resistor wired, now? Can you post the code that gives unreliable output and an example of the output?

Here is the new circuit following the suggestion of Paul__B and test code. The output is very stable. Around 40 counts under my desk lamp and 800 in darkness. The capacitor is optional but will help with noise on longer wires.

const byte anaIn = A0;

void setup()
{
  Serial.begin(115200);
  pinMode(anaIn, INPUT_PULLUP);
}

void loop() 
{
  static unsigned long timer = 0;
  unsigned long interval = 500;
  if(millis() - timer > interval)
  {
    timer = millis();
    int anaVal = analogRead(anaIn);
    Serial.println(anaVal);
  }
}

ldr.jpg

Currently by manually setting the below I can dim it slightly, 64 is pretty much off.

  pinMode(analogLCDpower, OUTPUT);
  analogWrite(analogLCDpower, 128);

I'm simply connecting to the LCD backlight power input pin as shown in attached.

Code:

int analogPhotoR = A7;
int analogLCDpower = A6;
int digitalLCDpower = 29; //unused

......
void setup {
// LCD Brightness
  pinMode(analogPhotoR, INPUT);
  pinMode(analogLCDpower, OUTPUT);
  analogWrite(analogLCDpower, 128);
//   digitalWrite(digitalLCDpower, HIGH);
....
}

void loop {
.....
// LCD PhotoR
   float photoR = analogPhotoR * (5.0 / 1023.0);


Serial.println("");
Serial.print("PhotoResistance: ");
Serial.print(analogPhotoR);
Serial.print(" - ");
Serial.println(photoR);
.....

Serial Output:
PhotoResistance: 61 - 0.30

Note: As specified, I have 2 Photoresistors in parallel to reduce the total resistance but still give a usable reading.

*** Edit ***
Correction: Serial.print(analogRead(analogPhotoR)); Now reads correctly.

Which pin are you using for analogLCDpower? Are you sure that the analogLCDpower pin is PWM capable? I have the same YwRobot backpack. When I run the attache code I can see the backlight come on at 10 (dim) and by 60 it is probably 1/2 bright. After about 160 the brightness changes little.

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

//#define I2C_ADDR    0x3f
#define I2C_ADDR    0x27  // Define I2C Address where the PCF8574A is
#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

const byte backLightPwmPin = 6;

LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

void setup()
{
  lcd.begin (20,4);
  // Switch on the backlight
  lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
  lcd.setBacklight(HIGH);
  lcd.print("BRIGHTNESS");
}

void loop() 
{
  lcd.setCursor(14,0); // clear old numbers
  lcd.print("       ");
  for(int n = 0; n < 255; n = n + 10)
  {
    analogWrite(backLightPwmPin, n);
    lcd.setCursor(14,0);
    lcd.print(n);
    delay(1000);  
  }
}

EDIT:

int analogLCDpower = A6;

A6 is not a PWM capable pin. If you are using an Uno, the PWM pins are 3, 5, 6, 9, 10, 11 (look for the ~ by the pin number). AnalogWrite to a non PWM pin will just turn it on if PWM > 127 and off if PWM < 128.

Using Arduino Mega.
Have switched to Digital/PWM 3 and now have it working :slight_smile:
Thanks :slight_smile:

Yay. Glad to hear.