Creating a multifunctional environmental monitoring system with Arduino is a rewarding project that combines temperature, humidity, air quality measurements, and light control. For temperature, humidity, and air quality, the BME680 sensor is an excellent choice as it provides a comprehensive data set including gas resistance readings indicative of air quality. To integrate light sensitivity, the BH1750 light sensor is a popular option due to its simplicity and effectiveness. Both sensors have libraries available in the Arduino IDE, which simplifies the coding process. Remember to calibrate the sensors, especially the air quality sensor, to ensure accurate readings. Adding a light sensor to automatically adjust desk lighting based on room brightness is a smart enhancement that not only improves comfort but also conserves energy. By utilizing the Arduino platform, you can create a custom solution tailored to your specific needs, learning valuable skills in electronics and programming along the way.

Materials Required:

  • Arduino Nano rev3 (builds fine with most arduino and clones)
  • LCD 16×4 SPI
  • DHT22
  • DST Module
  • MQ-2
  • Relay
  • 1 momentary button
  • 2 resistors

#include <Wire.h>                   // I2C communication
#include <LiquidCrystal_I2C.h>      // LCD
#include <RTClib.h>                 // RTC
#include <DHT.h>                    // TEMP & HUMID
//#include <MQ2.h>                  // Smoke sensor
LiquidCrystal_I2C lcd(0x27, 16, 4); // Create LCD with I2C address 0x27, 16 characters per line, 2 lines
RTC_DS3231 rtc;                     // Create rtc for the DS3231 RTC module, address is fixed at 0x68
#define DHTPIN 4                    // Digital pin connected to the DHT sensor
#define DHTTYPE DHT11               // DHT 11
DHT dht(DHTPIN, DHTTYPE);           //
float sensor = A0;                  //Air quality sensor setup mq2
float gas_value;                    //
int pbuttonPin = 2;                 //Push Button Relay 1 Control
int relayPin = 10;                  //
int val = 0;                        //
int lightON = 0;                    //
int pushed = 0;                     //
//int pbuttonPin2 = 3;                //Push Button Relay 2 Control
//int relayPin2 = 11;                 //
//int val2 = 0;                       //
//int lightON2 = 0;                   //
//int pushed2 = 0;                    //

/*
   function to update RTC time using user input
*/
void updateRTC()
{

  lcd.clear();  // clear LCD display
  lcd.setCursor(0, 0);
  lcd.print("Edit Mode...");

  // ask user to enter new date and time
  const char txt[6][15] = { "year [4-digit]", "month [1~12]", "day [1~31]",
                            "hours [0~23]", "minutes [0~59]", "seconds [0~59]"
                          };
  String str = "";
  long newDate[6];

  while (Serial.available()) {
    Serial.read();  // clear serial buffer
  }

  for (int i = 0; i < 6; i++) {

    Serial.print("Enter ");
    Serial.print(txt[i]);
    Serial.print(": ");

    while (!Serial.available()) {
      ; // wait for user input
    }

    str = Serial.readString();  // read user input
    newDate[i] = str.toInt();   // convert user input to number and save to array

    Serial.println(newDate[i]); // show user input
  }

  // update RTC
  rtc.adjust(DateTime(newDate[0], newDate[1], newDate[2], newDate[3], newDate[4], newDate[5]));
  Serial.println("RTC Updated!");
}
/*
   function to update LCD text
*/
void updateLCD()
{

  /*
     create array to convert digit days to words:
     0 = Sunday    |   4 = Thursday
     1 = Monday    |   5 = Friday
     2 = Tuesday   |   6 = Saturday
     3 = Wednesday |
  */
  const char dayInWords[7][4] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};

  /*
     create array to convert digit months to words:
     0 = [no use]  |
     1 = January   |   6 = June
     2 = February  |   7 = July
     3 = March     |   8 = August
     4 = April     |   9 = September
     5 = May       |   10 = October
     6 = June      |   11 = November
     7 = July      |   12 = December
  */
  const char monthInWords[13][4] = {" ", "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
                                    "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"
                                   };

  // get time and date from RTC and save in variables
  DateTime rtcTime = rtc.now();

  int ss = rtcTime.second();
  int mm = rtcTime.minute();
  int hh = rtcTime.twelveHour();
  int DD = rtcTime.dayOfTheWeek();
  int dd = rtcTime.day();
  int MM = rtcTime.month();
  int yyyy = rtcTime.year();

  // move LCD cursor to upper-left position
  lcd.setCursor(0, 0);

  // print date in dd-MMM-yyyy format and day of week
  if (dd < 10) lcd.print("0");  // add preceeding '0' if number is less than 10
  lcd.print(dd);
  lcd.print("-");
  lcd.print(monthInWords[MM]);
  lcd.print("-");
  lcd.print(yyyy);

  lcd.print("   ");
  lcd.print(dayInWords[DD]);

  // move LCD cursor to lower-left position
  lcd.setCursor(0, 1);

  // print time in 12H format
  if (hh < 10) lcd.print("0");
  lcd.print(hh);
  lcd.print(':');

  if (mm < 10) lcd.print("0");
  lcd.print(mm);
  lcd.print(':');

  if (ss < 10) lcd.print("0");
  lcd.print(ss);

  if (rtcTime.isPM()) lcd.print(" PM"); // print AM/PM indication
  else lcd.print(" AM");
}
void temph()
{
  // Wait a few seconds between measurements.
  delay(100);

  // 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);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    return;
  }
  // Compute heat index in Fahrenheit (the default)
  // float hif = dht.computeHeatIndex(f, h);
  // Compute heat index in Celsius (isFahreheit = false)
  // float hic = dht.computeHeatIndex(t, h, false);
  lcd.setCursor(10, 2);
  lcd.print(F("Humid: "));
  lcd.print(h, 0);
  lcd.print(F("%"));
  lcd.setCursor(0, 2);
  lcd.print(F("Temp: "));
  //  Serial.print(t);
  //  Serial.print(F("°C "));
  lcd.print((f - 10.2), 0);
  lcd.print(F("F"));
  //  Serial.print(F("°F  Heat index: "));
  //  Serial.print(hic);
  //  Serial.print(F("°C "));
  //  Serial.print(hif);
  //  Serial.println(F("°F"));
}
void mq2()
{
  lcd.setCursor(0, 3);
  lcd.print(F("MQ2: "));
  gas_value = analogRead(sensor);
  lcd.print((gas_value), 0);
  lcd.setCursor(10, 3);
  lcd.print(F("FAN: LOW"));
  delay(100);
}
void setup()
{
  Serial.begin(9600);     // initialize serial

  lcd.init();             // initialize lcd
  lcd.backlight();        // switch-on lcd backlight

  rtc.begin();            // initialize rtc
  dht.begin();            // init DHT11

  pinMode(sensor, INPUT); //mq2

  pinMode(pbuttonPin, INPUT_PULLUP); //Button 1
  pinMode(relayPin, OUTPUT);         //Relay 1
//  pinMode(pbuttonPin2, INPUT_PULLUP);//Button 2
//  pinMode(relayPin2, OUTPUT);        //Relay 2
}
void relay() {
  val = digitalRead(pbuttonPin);
//  val2 = digitalRead(pbuttonPin2);


  //Relay 1
  if (val == LOW && lightON == LOW) {

    pushed = 1 - pushed;
    delay(100);
  }
  lightON = val;

  if (pushed == HIGH) {
//    Serial.println("Light ON");
    digitalWrite(relayPin, LOW);

  } else {
//    Serial.println("Light OFF");
    digitalWrite(relayPin, HIGH);

  }



  //Relay 2


//  if (val2 == HIGH && lightON2 == LOW) {

//   pushed2 = 1 - pushed2;
//    delay(100);
//  }

//  lightON2 = val2;

//  if (pushed2 == HIGH) {
//    Serial.println("Light ON");
//    digitalWrite(relayPin2, LOW);

//  } else {
//    Serial.println("Light OFF");
//    digitalWrite(relayPin2, HIGH);

//  }


  delay(100);
}
void loop()
{
  updateLCD();            // update LCD
  temph();                // update temp & humidity
  mq2();                  // update mq2
  relay();                // update relays & control buttons

  if (Serial.available()) {
    char input = Serial.read();
    if (input == 'u') updateRTC();  // update RTC time
  }
}

Leave a Reply

SideMenu