loading

Problem with LCD backlight

Hello everybody, 
I'm here to ask a question I'm not able to solve on my own. I'm not good at programming, so it may be a silly question, but I can't find a solution. I'm building an Arduino based humidity and temperature monitoring system, with three DHT-11 sensors and a display to show readings from them. I'd like to be able to toggle LCD's backlight on with a pushbutton and have the code switch it off after a while. I can't  figure out how to make Arduino do it. All I could make till now is Arduino switching backlight ON at the beginning of the code regardless of the buton being pressed or not. 
Here is the code I wrote, I bolded the part relative to the pushbutton. Can anyone help me, please?

#include "DHT.h"                    // include DHT sensor library code

#include <LiquidCrystal.h>          // include lcd display library code

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);     // Initialize lcd on these pins

#define DHTPIN A0          // sensor1 1
#define DHTPIN2 A1         // sensor 2
#define DHTPIN3 A2         // sensor 3

// Uncomment whatever sensor type you're using!
#define DHTTYPE DHT11   // DHT 11
//#define DHTTYPE DHT22   // DHT 22  (AM2302)
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

// Initialize DHT sensor for normal 16mhz Arduino
DHT dht(DHTPIN, DHTTYPE);
DHT dht2(DHTPIN2, DHTTYPE);
DHT dht3(DHTPIN3, DHTTYPE);

#define light_button 8
#define backlight_pin 13
int val;
int state;


void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2); // set up the LCD's number of columns and rows:
  dht.begin(); // enable DHT sensors
  pinMode(light_button, INPUT);
  pinMode(backlight_pin, OUTPUT);
  state = 0;

}

void loop() {
  val = digitalRead(light_button);
    Serial.println(val);
  
    if(light_button != state){
      digitalWrite (backlight_pin, HIGH);
    }
    else {
      digitalWrite (backlight_pin, LOW);
    }

     
  // READING SENSOR 1
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)

  float h1 = dht.readHumidity();
  float t1 = dht.readTemperature(); // Read temperature as Celsius

  float hi = dht.computeHeatIndex(t1, h1); // Compute heat index

lcd.setCursor(5, 0);           // Print values from sensor 1 on lcd
  lcd.print("Teca 1");

lcd.setCursor(0,1);
  lcd.print("Umidita': ");
  lcd.print(h1);
  lcd.print("%");
delay(3000);                 // Show humidity value for 3 seconds

lcd.setCursor(0,1);          // Switch to temperature visualization
  lcd.print("Temperat: ");
  lcd.print(t1);
  lcd.print("C");
delay(3000);                // Show temperature value for 3 seconds


// READING SENSOR 2

  float h2 = dht2.readHumidity();      // Read humidity
  float t2 = dht2.readTemperature();   // Read temperature as Celsius
 
  float hi2 = dht.computeHeatIndex(t2, h2);  // Compute heat index
 
lcd.setCursor(5, 0);            // Print values from sensor 2 on lcd
  lcd.print("Teca 2");
 
lcd.setCursor(0,1);
  lcd.print("Umidita': ");
  lcd.print(h2);
  lcd.print("%");
delay(3000);                      // Show humidity value for 3 seconds

lcd.setCursor(0,1);              // Switch to temperature visualization
  lcd.print("Temperat: ");
  lcd.print(t2);
  lcd.print("C");
delay(3000);                    // Show temperature value for 3 seconds


// READING SENSOR 3
 
  float h3 = dht3.readHumidity();
  float t3 = dht3.readTemperature();      // Read temperature as Celsius
 
  float hi3 = dht.computeHeatIndex(t3, h3);    // Compute heat index
 
  lcd.setCursor(5, 0);                      // Print values from sensor 3 on lcd
  lcd.print("Teca 3");
 
lcd.setCursor(0,1);
  lcd.print("Umidita': ");
  lcd.print(h3);
  lcd.print("%");
delay(3000);                      // Show humidity value for 3 seconds

lcd.setCursor(0,1);                // Switch to temperature visualization
  lcd.print("Temperat: ");
  lcd.print(t3);
  lcd.print("C");
delay(3000);                      // Show temperature value for 3 seconds

}

sort by: active | newest | oldest
verence2 years ago

You compare the number of the pin (light_button =8 ) against the value in state.

That number never changes!

You have to compare the value you read as the pins state.

if(val != state){ ...

BTW: you never change the value of state.

As long as you don't do something automatically in the background, your way is much to complicated. Why not do something like:

val = digitalRead(light_button);
digitalWrite (backlight_pin, val);

or even:
digitalWrite (backlight_pin, digitalRead(light_button));

Or just wire the backlight directly to the button.


ade angelis (author)  verence2 years ago

Oh what a silly error! Thanks verence, you're completely right, my coding was far too complex. Yours is much simpler and it works, but it's still not what I'm after: now it only lights up if I press the button in the exact moment the loop starts, otherwise it won't.

> Oh what a silly error!

Sometimes you can't see the forest because of all the trees. First time I read your code, I thought that everything looks correct too.

Sorry, I didn't notice that you want to toggle the backlight. The following code should toggle the light on/off by the button and switch it off after some time without a button press. (Pseudo code, does compile, but not tested - don't have an Arduino here)

#define backlight_pin 13

#define light_button 8

int lightOnCtr = 0;
int buttonWasPressed = 0;
int buttonIsPressed;

void setup()
{
pinMode(backlight_pin, OUTPUT);
digitalWrite(backlight_pin, LOW);
pinMode(light_button, INPUT);
}

void loop()
{
// get current buttonstate (invert if low=active)
buttonIsPressed = digitalRead(light_button);
// you might need some kind of debouncing here if the loop is fast

if (!buttonWasPressed & buttonIsPressed)
// react only if the button is active now but was not last time
if (lightOnCtr > 0)
// light was on -> switch off
lightOnCtr = 0;
else
// light was off -> switch on
lightOnCtr = 1000; // adjust value for time of light on
else
// no button press, but if light is on ...
if (lightOnCtr>0)
// decrease counter so light will switch off after some time
lightOnCtr--;

buttonWasPressed = buttonIsPressed; // remember button state

digitalWrite (backlight_pin, lightOnCtr > 0); // switch light pin
}


ade angelis (author)  verence2 years ago

thanks, Verence, as I told iceng I've made it work. It's incredible how much time a small problem can cost you!! :)

iceng2 years ago

Use a single flag and a multy word down counting interrupt routine.

When you detect a key press, Set the LED on, set the flag which stops testing the key, load the down counter and enable the interrupt decrement delay.

When the count reaches zero, halt the interrupt, Clear the LED and Clear the flag which allows testing for the next key press :)

iceng iceng2 years ago

A flag is a one Bit variable that you can Set, Clear, Read and Branch from that is very much like a Carry Bit.

Not knowing how often your micro generates a self interrupt.

You make multi word decrementing counter by loading 255 into integer variable K and variable L.

Then every interrupt decrement K

When K == 0 decrement L

Continue decrementing K 256 times as often as L

When K == L == 0 IMMEDIATELY turn off interrupt path, Clear Flag, Turn Off LED and return from interrupt.

With the Flag Cleared, Now resume testing the button press on each loop.

ade angelis (author)  iceng2 years ago

ok, I've finally managed to make it work, but code wasn't the problem. I've been struggling on it for two days, only to discover that the button that triggers lcd's backlight wasn't making a good contact: the 10k resistor between it and GND didn't make pin2 go LOW, so it kept switching the backlight on!

I'd like to thank both of you for answering me! :)

ade angelis (author)  iceng2 years ago

Iceng, thank you very much for your advice. Before reading your answer I didn't even know of an interrupt function, but I've done a bit of research and came up with something. I managed to introduce a timer to decide how long the backlight has to stay on (I'd like it to stay on for 3 loop cycles), and it seems to work: after 3 cycles backlight turns off. The problem is it doesn't seem to to care about the pushbutton: as soon as loop starts, somehow it flips backlight on, regardless of the button being pressed or not, and I can't understand why.

Here's the code I'm now using:

#include
"DHT.h" //
include DHT sensor library code

#include
<LiquidCrystal.h> //
include lcd display library code

LiquidCrystal
lcd(12, 11, 6, 5, 4, 3); //
Initialize lcd on these pins

#define DHTPIN A0
// sensor1 1

#define DHTPIN2 A1
// sensor 2

#define
DHTPIN3 A2 // sensor 3

//
Uncomment whatever sensor type you're using!

#define
DHTTYPE DHT11 // DHT 11

//#define
DHTTYPE DHT22 // DHT 22 (AM2302)

//#define
DHTTYPE DHT21 // DHT 21 (AM2301)

//
Initialize DHT sensor for normal 16mhz Arduino

DHT
dht(DHTPIN, DHTTYPE);

DHT
dht2(DHTPIN2, DHTTYPE);

DHT
dht3(DHTPIN3, DHTTYPE);

#define
backlight_pin 13

int interrCount=0;

int tempo =
1000;

void
setup() {

Serial.begin(9600);

lcd.begin(16, 2); // set up the LCD's number
of columns and rows:

dht.begin(); // enable DHT sensors

pinMode(backlight_pin, OUTPUT);

digitalWrite(backlight_pin, LOW);;

attachInterrupt(0,
backlight, RISING);

}

void loop()
{


interrCount++;

// READING SENSOR 1

// Reading temperature or humidity takes
about 250 milliseconds!

// Sensor readings may also be up to 2
seconds 'old' (its a very slow sensor)

float h1 = dht.readHumidity();

float t1 = dht.readTemperature(); // Read
temperature as Celsius

float hi = dht.computeHeatIndex(t1, h1); //
Compute heat index

lcd.setCursor(5,
0); // Print values from sensor
1 on lcd

lcd.print("Teca 1");

lcd.setCursor(0,1);

lcd.print("Umidita': ");

lcd.print(h1);

lcd.print("%");

delay(tempo); // Show humidity value for 3
seconds

lcd.setCursor(0,1); // Switch to temperature
visualization

lcd.print("Temperat: ");

lcd.print(t1);

lcd.print("C");

delay(tempo); // Show temperature value for 3
seconds

// READING
SENSOR 2

float h2 = dht2.readHumidity(); // Read humidity

float t2 = dht2.readTemperature(); // Read temperature as Celsius

float hi2 = dht.computeHeatIndex(t2,
h2); // Compute heat index

lcd.setCursor(5,
0); // Print values from
sensor 2 on lcd

lcd.print("Teca 2");

lcd.setCursor(0,1);

lcd.print("Umidita': ");

lcd.print(h2);

lcd.print("%");

delay(tempo); // Show humidity value
for 3 seconds

lcd.setCursor(0,1); // Switch to temperature
visualization

lcd.print("Temperat: ");

lcd.print(t2);

lcd.print("C");

delay(tempo); // Show temperature value
for 3 seconds

// READING
SENSOR 3

float h3 = dht3.readHumidity();

float t3 = dht3.readTemperature(); // Read temperature as Celsius

float hi3 = dht.computeHeatIndex(t3,
h3); // Compute heat index

lcd.setCursor(5, 0); // Print values from
sensor 3 on lcd

lcd.print("Teca 3");

lcd.setCursor(0,1);

lcd.print("Umidita': ");

lcd.print(h3);

lcd.print("%");

delay(tempo); // Show humidity value
for 3 seconds

lcd.setCursor(0,1); // Switch to temperature
visualization

lcd.print("Temperat: ");

lcd.print(t3);

lcd.print("C");

delay(tempo); // Show temperature value
for 3 seconds

if
(interrCount = 3)

{


interrCount = 0;


digitalWrite(backlight_pin, LOW);

}

}

void backlight()

{


digitalWrite(backlight_pin, HIGH);

}

Could you please give me some more help with this?

Many thanks