Go Down

Topic: Bathroom FAN Automation Project (Read 3679 times) previous topic - next topic

lmsvvavr

Nov 29, 2013, 08:18 pm Last Edit: Nov 29, 2013, 09:12 pm by lmsvvavr Reason: 1
Hi everyone!

I am quite new to Arduino, and although I have set up two "thermoduino" projects at my home, (Thanks to marque developing work...) this is the first project I am developing on my own...

As the title says, the project is to have my bathroom extractor fan to come on depending on the humidity...
For that I have put together:

1 x Arduino Uno //the board
1 x DHT22  //Temperature and humidity sensor
1 x LCD and keypad display //To give visual information and to change set point using the keypad.
1 x 5v relay board //to turn on and off the fan.

Now, from what I have learned reading, and looking at other sketches I managed to write my code, pretty much to what I want...
Although there is one thing that I do not know why is not working, and your help will be welcome!

This is my code:
Code: [Select]
/*******************************************************************Bathroom Extractor FAN Automation - By lmsvvavr v.1.0.0 ********************************/
/* Bathroom extractor FAN automation, based on humidity readings.
What you need:
One Arduino Board, this has been based on the UNO, you can use other boards, you might need however to adapt the sketch and connections.
One LCD, this has been based on the DFROBOT 16X2, the LCD is however optional, the system will work just on its own.
One DHT humidity and temperature sensor, you need to adapt the sketch if not using the DHT22.
One single relay board, capable of handling with your FAN load, please make the necessary research to ensure of that.
*/



#include "DHT.h"          //DHT library, google to download it and install if you don't have it already.
#include <LiquidCrystal.h>//LCD library, google to download it and install if you don't have it already.
#define DHTPIN 2         //Defines the pin where the DATA is connected.
#define DHTTYPE DHT22   // DHT 22  (AM2302), if you use DHT11 or DHT23 change it accondingly.
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

DHT dht(DHTPIN, DHTTYPE);

const int FAN = 11;  //Defines the pin where the relay is connected.
float hm;  // Measured humidity
int hd = 67;  // Desired humidity
int lcd_key     = 0;
int adc_key_in  = 0;
int count       = 0;
int read_LCD_buttons()
{
 adc_key_in = analogRead(0);      // read the value from the sensor
 // my buttons when read are centered at these valies: 0, 144, 329, 504, 741
 // we add approx 50 to those values and check to see if we are close
 if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
 // For V1.1 us this threshold
 if (adc_key_in < 50)   return btnRIGHT;  
 if (adc_key_in < 250)  return btnUP;
 if (adc_key_in < 450)  return btnDOWN;
 if (adc_key_in < 650)  return btnLEFT;
 if (adc_key_in < 850)  return btnSELECT;  
 return btnNONE;  // when all others fail, return this...
}

LiquidCrystal lcd(8, 9, 4, 5, 6, 7); //Pins where the lcd is connected, change it accordingly if you are using different pin assignment.

/************************************************ SETUP *************************************/

void setup() {

 pinMode(FAN, OUTPUT);  //Defines the pin as an output.
 Serial.begin(9600); //Serial port speed.
 Serial.println("FAN Humidity System"); //Serial message.
 lcd.begin(16, 2);      //Defines how many rows and columns the lcd has.
 lcd.setCursor(0,0);
 lcd.print("Bathroom FAN ATM");  //Start-Up message line 0 (Top Line)
 lcd.setCursor(0,1);
 lcd.print("By      lmsvvavr");  //Start-Up message line 1 (Bottom Line)
 delay(3000);
 lcd.setCursor(0,0);
 lcd.print("System is now   ");
 lcd.setCursor(0,1);
 lcd.print("Starting        ");
 delay(250);
 lcd.setCursor(0,1);
 lcd.print("Starting.       ");
 delay(250);
 lcd.setCursor(0,1);
 lcd.print("Starting..      ");
 delay(500);
 lcd.setCursor(0,1);
 lcd.print("Starting...     ");
 delay(250);
 lcd.setCursor(0,1);
 lcd.print("Starting....    ");
 delay(500);
 lcd.setCursor(0,1);
 lcd.print("Starting.....   ");
 delay(500);
 lcd.setCursor(0,1);
 lcd.print("Starting......  ");
 delay(200);
 lcd.setCursor(0,1);
 lcd.print("Starting....... ");
 delay(200);
 lcd.setCursor(0,1);
 lcd.print("Starting........");
 dht.begin();
}

/********************************************** LOOP ***************************************/

void loop() {

 adc_key_in = lcd_key;
 lcd_key = read_LCD_buttons();  // read the buttons
 float hm = dht.readHumidity();
 float t = dht.readTemperature();
 if (isnan(t) || isnan(hm))

 {
   Serial.println("Failed to read from DHT");
   lcd.setCursor(1,1);
   lcd.print(" Check sensor!  ");
 }
 else
 {
   Serial.print("Humidity: ");
   Serial.print(hm);
   Serial.print(" %\t");
   Serial.print("Temperature: ");
   Serial.print(t);
   Serial.println(" *C");
   delay (1500);
   lcd.setCursor(0,0);              //Set where about on the lcd you want to print the values.
   lcd.print(hd);                   //To print on the lcd the desired humidity.
   lcd.print(" RH% Fan ON At");     //Message in front of the desired humidity.
   lcd.setCursor(0,1);              //Set where about on the lcd you want to print the values.
   lcd.print(hm);                   //To print on the lcd the measured humidity.
   lcd.print("RH% In Room");        //Message in front of the measured humidity.
 }

 if (hm > hd)
 {
   digitalWrite(FAN, LOW);
 }  
 else

 {
   digitalWrite(FAN, HIGH);
 }
 if (adc_key_in != lcd_key)
   switch (lcd_key)               // depending on which button was pushed, we perform an action
   {
   case btnRIGHT:
     {
       lcd.setCursor(0,0);
       lcd.print("Reset RH% to its ");
       lcd.setCursor(0,1);             //Reset the changes to the FAN set point.
       lcd.print("default value...");
       hd = (hd);
       break;
     }
   case btnLEFT:
     {  
       lcd.setCursor(0,0);
       lcd.print(t);
       lcd.print(" *C             ");
       lcd.setCursor(0,1);            //Display the temperature.
       lcd.print("Room Temperature");
       delay(15000);
       break;
     }
   case btnUP:
     {
       lcd.setCursor(7,0);
       lcd.print("Increase ");  //Increase the Fan set point.
       hd = (hd + 1);
       break;
     }
   case btnDOWN:
     {
       lcd.setCursor(7,0);  
       lcd.print("Decrease ");  //Decrease the Fan set point.
       hd = (hd - 1);  
       break;
     }
   case btnSELECT:
     {
       lcd.setCursor(0,0);
       lcd.print("Uptime       Min");
       lcd.setCursor(7,0);
       lcd.print(millis()/60000);       //Display the Uptime since last Start/Reset and System version.
       lcd.setCursor(0,1);
       lcd.print("Sys Ver. v1.0.0 ");
       delay(15000);
       break;
     }
   case btnNONE:
     {
       break;
     }
   }
}


Everything works, except the "Right" key on the keypad.
I have set it to reset any changes on the set point of the relay, but the button does nothing!!!
All other ones work perfectly.
Sure is right in front of my nose... but I can see it!
I have tried another lcd/keypad... same result!

Thank you in advance for your help!

wildbill

This doesn't do anything:
Code: [Select]

        hd = (hd);


Perhaps it should be
Code: [Select]

        hd = 67;

lmsvvavr


This doesn't do anything:
Code: [Select]

        hd = (hd);


Perhaps it should be
Code: [Select]

        hd = 67;



Thank you for your reply...
I have tried that, does no work!...

wildbill

Can you use serial.print to prove to yourself that the button press is correctly detected?

lmsvvavr

#4
Nov 30, 2013, 06:06 am Last Edit: Nov 30, 2013, 06:08 am by lmsvvavr Reason: 1

Can you use serial.print to prove to yourself that the button press is correctly detected?


Hi
Thank you for your suggestion...
Definitely yes...
After using the following code I get values from all buttons, getting 14 for the right one, so on the original code the <50 should work!
Although serial.print on the original code return no value????
Code: [Select]
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int a=0;

void setup()
{
 lcd.begin(16, 2);
 Serial.begin(9600);
 Serial.print("Keys Test Mode");
 pinMode(A0, INPUT_PULLUP);
}

void loop()
{
 a = analogRead(0);
 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print("  analogRead() ");
 lcd.setCursor(0,1);
 lcd.print("  value is :");
 lcd.print(a);
 Serial.print(a);
 delay(250);
}


What can be wrong?

wildbill

I'd put a serial.print of hd in the code that handles the btnRIGHT case, after you reset Hd, to verify that the execution flow actually goes there.

BobbyD

could you give it a range of   (>10 && <50) in your code?
BobbyD

lmsvvavr


I'd put a serial.print of hd in the code that handles the btnRIGHT case, after you reset Hd, to verify that the execution flow actually goes there.


If I change the btnRIGHT values as below, the button works, but as the "UP" button...

Code: [Select]
  if (adc_key_in <= 14 >=13)   return btnRIGHT; 
  if (adc_key_in < 250)  return btnUP;
  if (adc_key_in < 450)  return btnDOWN;
  if (adc_key_in < 650)  return btnLEFT;
  if (adc_key_in < 850)  return btnSELECT; 
  return btnNONE;


wildbill

In this fragment:
Code: [Select]

  adc_key_in = lcd_key;
  lcd_key = read_LCD_buttons();  // read the buttons


You're using arc_key_in for two different purposes - read_LCD_buttons uses it to hold the reading from the ADC, but you're also trying to use it to see if a new key has been pressed. Separate them out - put the ADC reading in a different (new) variable.

Also, I'm not sure what your expectation is of this piece of code:
Code: [Select]

  if (adc_key_in <= 14 >=13)   return btnRIGHT; 

But I doubt it does what you were hoping - it was better as it was.

lmsvvavr


In this fragment:
Code: [Select]

  adc_key_in = lcd_key;
  lcd_key = read_LCD_buttons();  // read the buttons


You're using arc_key_in for two different purposes - read_LCD_buttons uses it to hold the reading from the ADC, but you're also trying to use it to see if a new key has been pressed. Separate them out - put the ADC reading in a different (new) variable.

Also, I'm not sure what your expectation is of this piece of code:
Code: [Select]

  if (adc_key_in <= 14 >=13)   return btnRIGHT; 

But I doubt it does what you were hoping - it was better as it was.


Thank you for the suggestion... will try that and report!

My expectation with that last line you mentioned was, because the analog reading of the RIGHT button is 13/14 I thought I could just try to be more specific about the button value... just playing around anyway...

lmsvvavr

Hi
Hope you all have had a nice holidays... A nice new year to everyone...

Despite all my efforts I can get the right button to work, I will not need it anyway, as I wrote the code differently.
Anyway, the whole thing is now also set up to control some lights, depending on the room light (using a LDR for that...) and movement.
Everything is working, but having a problem... every time the relay for the FAN is switched on by the arduino, the readings from the DHT22 sensor fails, the relay switches off the reading comes back the relay is switched on again, and the reading fails again and stays like that until the whole thing kind of freezes...
The Relay module VCC and GND are from an external source, to not overload the arduino...
If I disconnect the relay switch pins the system works ok...???
Does any one have an idea about what is causing this issue?
Below is the code I wrote...
Code: [Select]

#include "DHT.h"             //DHT library, google to download it and install if you don't have it already.
#include <LiquidCrystal.h>   //LCD library, google to download it and install if you don't have it already.
#define DHTPIN (A1)          //Defines the pin where the DATA is connected.
#define DHTTYPE DHT22        // DHT 22  (AM2302), if you use DHT11 or DHT23 change it accordingly.
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

DHT dht(DHTPIN, DHTTYPE);

const int FAN = 3;      //Defines the pin where the Fan relay is connected.
const int LEDs = 2;     //Defines the pin where the LEDs relay is connected.
const int LDR = (A2);   //Defines the pin where the LDR is connected.
int PIR = 11;            //Dedines the pin where the PIR is connected.
float hm;                // Measured humidity
int hd = 69;             // Desired humidity
int lcd_key      = 0;
int adc_key_in   = 0;
int adc_key_prev = 0;
int count        = 0;
int LDRvalue     = 0;
int LDRsetpoint  = 500;  //Desired LDR trigger value
int PIRstatus;

LiquidCrystal lcd(8, 9, 4, 5, 6, 7); //Pins where the lcd is connected, change it accordingly if you are using different pin assignment.

/************************************************ SETUP *************************************/

void setup() {

  pinMode(FAN, OUTPUT);     //Defines the pin as an output.
  pinMode(LEDs, OUTPUT);    //Defines the pin as an output.
  pinMode(PIR, INPUT);      //Defines the pin as input.0
  digitalWrite(LEDs, HIGH); //Keep LEDs relay off while the system is booting.
  Serial.begin(9600);       //Serial port and speed started.
  Serial.println("Bathroom Automation System by lmsvvavr"); //Serial message.
  lcd.begin(16, 2);         //Defines how many rows and columns the lcd has.
  lcd.setCursor(0,0);
  lcd.print("    Bathroom    ");  //Start-Up message line 0 (Top Line)
  lcd.setCursor(0,1);
  lcd.print("   Automation   ");  //Start-Up message line 1 (Bottom Line)
  delay(5000);
  lcd.setCursor(0,0);
  lcd.print("Created & Wroted");  //Start-Up message line 0 (Top Line)
  lcd.setCursor(0,1);
  lcd.print("  By lmsvvavr   ");  //Start-Up message line 1 (Bottom Line)
  delay(5000);
  lcd.setCursor(0,0);
  lcd.print("System Starting!");
  lcd.setCursor(0,1);
  lcd.print("Init Modules.   ");
  delay(500);
  lcd.setCursor(0,1);
  lcd.print("Init Modules..  ");
  delay(500);
  lcd.setCursor(0,1);
  lcd.print("Init Modules... ");
  delay(500);
  lcd.setCursor(0,1);
  lcd.print("Init Modules....");
  delay(250);
  lcd.setCursor(0,1);
  lcd.print("Init Temp Sensor");
  delay(2000);
  lcd.setCursor(0,1);
  lcd.print("Init RH% Sensor ");
  delay(2000);
  lcd.setCursor(0,1);
  lcd.print("Init LDR Sensor ");
  delay(2000);
  lcd.setCursor(0,1);
  lcd.print("Init PIR Sensor ");
  delay(2000);
  lcd.setCursor(0,0);
  lcd.print(" Initialization ");
  lcd.setCursor(0,1);
  lcd.print("   Completed!   ");
  delay(2000);
  Serial.println("System Initialization Completed!");
  dht.begin();
}

/********************************************** LOOP ***************************************/

void loop() {
 
  float hm = dht.readHumidity();     // Read the humidity.
  float t = dht.readTemperature();   // Read the temperature.
  LDRvalue = analogRead(LDR);        // Read the light sensor value.   
  PIRstatus = digitalRead(PIR);      // Read the movement sensor - digital values (zero or one)
  delay(1000);

 
 
  if (isnan(t) || isnan(hm))
 
  {
    Serial.println("Failed to read from DHT - Check sensor!");
    lcd.setCursor(0,0);
    lcd.print("Check RH% Sensor");
  }
   
  else
  {
    Serial.print("Humidity: ");
    Serial.print(hm);
    Serial.print(" %\t");
    Serial.print("Temperature: ");
    Serial.print(t);
    Serial.println(" *Celcius");
    Serial.println("Light Sentitiveness: ");
    Serial.println(LDRvalue);
    Serial.println("PIR Status: ");
    Serial.println(PIRstatus);
    Serial.println("Buttons Analog Read: ");
    Serial.print(adc_key_in);
    delay (1500);
    lcd.setCursor(0,0);              //Set where about on the lcd you want to print the values.
    lcd.print(hm);                   //To print on the lcd the measured humidity.
    lcd.print("RH% FAN ");           //Message in front of the desired humidity.
    lcd.print(hd);                   //To print on the lcd the desired humidity.
    lcd.print("%");
    lcd.setCursor(0,1);              //Set where about on the lcd you want to print the values.
    lcd.print(LDRvalue);             //To print on the lcd the measured light.
    lcd.print(" Light ");            //Message in front of the measured light.
    lcd.print(LDRsetpoint);          //To print in the lcd the desired light.
    lcd.print(" M");                 
    lcd.print(PIRstatus);            //To print on the lcd the movement sensor status.
  }
 
  if (hm > hd) //When the humidity measured is above the humidity desired, fan is turned on.
 
  {
    digitalWrite(FAN, LOW);
  }
  else        //Anything else, fan is off.
  {
    digitalWrite(FAN, HIGH);
  }
 
  if (LDRvalue > LDRsetpoint && PIRstatus==HIGH) //Light measured above setpoint (lighter) and movement not detected, lights off.
  {
    digitalWrite(LEDs, LOW);
  }
 
  if (LDRvalue < LDRsetpoint || PIRstatus==LOW) //Light measured below setpoint (darker) and movement detected, lights on.
  {
    digitalWrite(LEDs, HIGH);
  }
 
    adc_key_in = lcd_key;
    lcd_key = read_LCD_buttons();      // Read the buttons.
   
    if (adc_key_prev != lcd_key)
    switch (lcd_key)                   // Depending on which button was pushed, we perform an action
    {
    case btnRIGHT:
      {
        break;
      }
    case btnLEFT:
      { 
        lcd.setCursor(0,0);
        lcd.print(LDRvalue);
        lcd.print(" Light Sensor");
        lcd.setCursor(0,1);
        LDRsetpoint = (LDRsetpoint + 10); // Increase light setpoint.
        lcd.print(LDRsetpoint);           // Print on the LCD the now light setpoint.
        lcd.print(" Light Set To");
        break;
      }
    case btnUP:
      {
        lcd.setCursor(0,0);
        lcd.print(hm); 
        lcd.print("RH% In Room");
        lcd.setCursor(0,1);   
        hd = (hd + 1);                   // Increase the FAN humidity setpoint.
        lcd.print(hd);
        lcd.print(" RH% Desired  ");   
        break;
      }
    case btnDOWN:
      {
        lcd.setCursor(0,0);
        lcd.print(hm); 
        lcd.print("RH% In Room");
        lcd.setCursor(0,1);   
        hd = (hd - 1);                    // Decrease the FAN humidity setpoint.
        lcd.print(hd);
        lcd.print(" RH% Desired  ");   
        break;
      }
    case btnSELECT:
      {
        lcd.setCursor(0,0);
        lcd.print(LDRvalue);
        lcd.print(" Light Sensor");
        lcd.setCursor(0,1);
        LDRsetpoint = (LDRsetpoint - 10);   // Decrease the light setpoint.
        lcd.print(LDRsetpoint);             // Print on the LCD the now light setpoint.
        lcd.print(" Light Set To");
        break;
      }
    case btnNONE:
      {
        break;
      }
    }
}   

int read_LCD_buttons()
{
  adc_key_in = analogRead(0);      // read the value from the sensor
  delay(5); //switch debounce delay. Increase this delay if incorrect switch selections are returned.
  int k = (analogRead(0) - adc_key_in); //gives the button a slight range to allow for a little contact resistance noise
  if (5 < abs(k)) return btnNONE;  // double checks the keypress. If the two readings are not equal +/-k value after debounce delay, it tries again.
  // my buttons when read are centered at these valies: 0, 144, 329, 504, 741
  // we add approx 50 to those values and check to see if we are close
  if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
  if (adc_key_in < 50)   return btnRIGHT; 
  if (adc_key_in < 250)  return btnUP;
  if (adc_key_in < 450)  return btnDOWN;
  if (adc_key_in < 650)  return btnLEFT;
  if (adc_key_in < 850)  return btnSELECT;   
  return btnNONE;  // when all others fail, return this...
}

I have a couple of DHT22 running in a project. One of them gives wrong readings once in a while, so I had to add some code to deal with that. The error handling in the DHT22 library is good, so you can just filter out the readings that went wrong.

I had issues too, when turning on and off some sprinklers (for the same project): The arduino kept crashing randomly when  the pumps went on or off. I'm not an expert, but I guess it could be some kind of voltage transients in the line caused by the inductance of the motors turning on and off (like you are doing with your fan), even if the relays were opto-isolated and the power lines were independent. Anyway, I fixed it plugging the pumps to a filtered power bar, but I guess that just a cheap EMI filter would do the trick too.

Hope it helps,

lmsvvavr


I have a couple of DHT22 running in a project. One of them gives wrong readings once in a while, so I had to add some code to deal with that. The error handling in the DHT22 library is good, so you can just filter out the readings that went wrong.

I had issues too, when turning on and off some sprinklers (for the same project): The arduino kept crashing randomly when  the pumps went on or off. I'm not an expert, but I guess it could be some kind of voltage transients in the line caused by the inductance of the motors turning on and off (like you are doing with your fan), even if the relays were opto-isolated and the power lines were independent. Anyway, I fixed it plugging the pumps to a filtered power bar, but I guess that just a cheap EMI filter would do the trick too.

Hope it helps,



Hi

Funny your conclusion... as I got to the same one...
The cable that feeds the fan also connects the DHT22...
So that says it all!
Today after a few tests I have reached the same conclusion...
Luckily I can move the sensor to another place, and away from the 220volts... and the relays away from the arduino...

lmsvvavr

Ferrite filters did not solved the issue.
So I am now planning to use two secondary relays activated by the first set of relays of the arduino.
Hopefully that will solve the problem.

lmsvvavr

Hi everyone!

Has been awhile since my last post in this thread, i am back for one last update...
The whole system is now working, a few changes in the code an got it all running fine...
Here is the code:
Code: [Select]


/*******************************************************************Bathroom Automation - By lmsvvavr v.1.9.3 ********************************/
/* Bathroom automation, based on humidity, light and movement (PIR) readings.
 What you need:
 One Arduino Board, this has been based on the MEGA, you can use other boards, you need however to adapt the sketch and connections.
 One LCD, this has been based on the DFROBOT 16X2, the LCD is however optional, the system will work just on its own, (possible adjustments required!).
 One DHT humidity and temperature sensor, you need to adapt the sketch if not using the DHT22.
 One LDR (Light Dependent Resistor) sensor.
 One PIR movement sensor.
 One dual relay board, capable of handling with your FAN load, please make the necessary research to ensure of that.
 */



#include "DHT.h"             //DHT library, google to download it and install if you don't have it already.
#include <LiquidCrystal.h>   //LCD library, google to download it and install if you don't have it already.
#define DHTPIN 50            //Defines the pin where the DATA is connected.
#define DHTTYPE DHT22        // DHT 22  (AM2302), if you use DHT11 or DHT23 change it accordingly.
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

DHT dht(DHTPIN, DHTTYPE);

const int FAN = 20;      //Defines the pin where the Fan relay is connected.
const int LEDs = 16;     //Defines the pin where the LEDs relay is connected.
const int LDR = (A8);   //Defines the pin where the LDR is connected.
const int PIR = 18;            //Dedines the pin where the PIR is connected.
float hm;                // Measured humidity
int hd = 85;             // Desired humidity
int lcd_key      = 0;
int adc_key_in   = 0;
int adc_key_prev = 0;
int count        = 0;
int LDRvalue     = 0;
int LDRsetpoint  = 750;  //Desired LDR trigger value
int PIRstatus;

LiquidCrystal lcd(8, 9, 4, 5, 6, 7); //Pins where the lcd is connected, change it accordingly if you are using different pin assignment.

/************************************************ SETUP *************************************/

void setup() {

  pinMode(FAN, OUTPUT);     //Defines the pin as an output.
  pinMode(LEDs, OUTPUT);    //Defines the pin as an output.
  pinMode(PIR, INPUT);      //Defines the pin as input.0
  digitalWrite(LEDs, HIGH); //Keep LEDs relay off while the system is booting.
  digitalWrite(FAN, HIGH);  //Keep FAN relay off while the system is booting.
  lcd.begin(16, 2);         //Defines how many rows and columns the lcd has.
  lcd.setCursor(0,0);
  lcd.print("    Bathroom    ");  //Start-Up message line 0 (Top Line)
  lcd.setCursor(0,1);
  lcd.print("   Automation   ");  //Start-Up message line 1 (Bottom Line)
  delay(5000);
  lcd.setCursor(0,0);
  lcd.print("Created & Wroted");  //Start-Up message line 0 (Top Line)
  lcd.setCursor(0,1);
  lcd.print("  By lmsvvavr   ");  //Start-Up message line 1 (Bottom Line)
  delay(5000);
  lcd.setCursor(0,0);
  lcd.print("System Starting!");
  lcd.setCursor(0,1);
  lcd.print("Init Modules.   ");
  delay(500);
  lcd.setCursor(0,1);
  lcd.print("Init Modules..  ");
  delay(500);
  lcd.setCursor(0,1);
  lcd.print("Init Modules... ");
  delay(500);
  lcd.setCursor(0,1);
  lcd.print("Init Modules....");
  delay(250);
  lcd.setCursor(0,1);
  lcd.print("Init RH% Sensor ");
  delay(2000);
  lcd.setCursor(0,1);
  lcd.print("Init LDR Sensor ");
  delay(2000);
  lcd.setCursor(0,1);
  lcd.print("Init PIR Sensor ");
  delay(2000);
  lcd.setCursor(0,0);
  lcd.print(" Initialization ");
  lcd.setCursor(0,1);
  lcd.print("   Completed!   ");
  delay(2000);
  dht.begin();
}

/********************************************** LOOP ***************************************/

void loop() {
  
  hm = dht.readHumidity();           // Read the humidity.
  
  if (hm > hd) //When the humidity measured is above the humidity desired, fan is turned on.
  
  {
    digitalWrite(FAN, LOW);
  }
  else        //Anything else, fan is off.
  {
    digitalWrite(FAN, HIGH);
  }
  
  LDRvalue = analogRead(LDR);        // Read the light sensor value.  
  PIRstatus = digitalRead(PIR);      // Read the movement sensor - digital values (zero or one)
  
  if (LDRvalue > LDRsetpoint && PIRstatus==HIGH) //Light measured above setpoint (lighter) and movement not detected, lights off.
  {
    digitalWrite(LEDs, LOW);
  }
  
  if (LDRvalue < LDRsetpoint || PIRstatus==LOW) //Light measured below setpoint (darker) and movement detected, lights on.
  {
    digitalWrite(LEDs, HIGH);
  }
  
    {
    lcd.setCursor(0,0);              //Set where about on the lcd you want to print the values.
    lcd.print(hm);                   //To print on the lcd the measured humidity.
    lcd.print("RH% FAN ");           //Message in front of the desired humidity.
    lcd.print(hd);                   //To print on the lcd the desired humidity.
    lcd.print("%");
    lcd.setCursor(0,1);              //Set where about on the lcd you want to print the values.
    lcd.print(LDRvalue);             //To print on the lcd the measured light.
    lcd.print(" Light ");            //Message in front of the measured light.
    lcd.print(LDRsetpoint);          //To print in the lcd the desired light.
    lcd.print(" M");                
    lcd.print(PIRstatus);            //To print on the lcd the movement sensor status.
  }
  
    adc_key_in = lcd_key;
    lcd_key = read_LCD_buttons();      // Read the buttons.
    
    if (adc_key_prev != lcd_key)
    switch (lcd_key)                   // Depending on which button was pushed, perform an action
    {
    case btnRIGHT:
      {
        break;
      }
    case btnLEFT:
      {  
        lcd.setCursor(0,0);
        lcd.print(LDRvalue);
        lcd.print(" Light Sensor");
        lcd.setCursor(0,1);
        LDRsetpoint = (LDRsetpoint + 10); // Increase light setpoint.
        lcd.print(LDRsetpoint);           // Print on the LCD the now light setpoint.
        lcd.print(" Light Set To");
        break;
      }
    case btnUP:
      {
        lcd.setCursor(0,0);
        lcd.print(hm);  
        lcd.print("RH% In Room");
        lcd.setCursor(0,1);  
        hd = (hd + 1);                   // Increase the FAN humidity setpoint.
        lcd.print(hd);
        lcd.print(" RH% Desired  ");  
        break;
      }
    case btnDOWN:
      {
        lcd.setCursor(0,0);
        lcd.print(hm);  
        lcd.print("RH% In Room");
        lcd.setCursor(0,1);  
        hd = (hd - 1);                    // Decrease the FAN humidity setpoint.
        lcd.print(hd);
        lcd.print(" RH% Desired  ");  
        break;
      }
    case btnSELECT:
      {
        lcd.setCursor(0,0);
        lcd.print(LDRvalue);
        lcd.print(" Light Sensor");
        lcd.setCursor(0,1);
        LDRsetpoint = (LDRsetpoint - 10);   // Decrease the light setpoint.
        lcd.print(LDRsetpoint);             // Print on the LCD the now light setpoint.
        lcd.print(" Light Set To");
        break;
      }
    case btnNONE:
      {
        break;
      }
    }
    delay(1000);
}  

int read_LCD_buttons()
{
  adc_key_in = analogRead(0);      // read the value from the sensor
  delay(5); //switch debounce delay. Increase this delay if incorrect switch selections are returned.
  int k = (analogRead(0) - adc_key_in); //gives the button a slight range to allow for a little contact resistance noise
  if (5 < abs(k)) return btnNONE;  // double checks the keypress. If the two readings are not equal +/-k value after debounce delay, it tries again.
  // my buttons when read are centered at these valies: 0, 144, 329, 504, 741
  // we add approx 50 to those values and check to see if we are close
  if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
  if (adc_key_in < 50)   return btnRIGHT;  
  if (adc_key_in < 250)  return btnUP;
  if (adc_key_in < 450)  return btnDOWN;
  if (adc_key_in < 650)  return btnLEFT;
  if (adc_key_in < 850)  return btnSELECT;  
  return btnNONE;  // when all others fail, return this...
}

Here is a short video of the system...

Bathroom Automation System

Go Up