// ETECAF
// EMBEDDED SYSTEMS 2
// SEM2 - 3RD BIMESTER - 2024
// PROJECT LCD+I2C+DHT+POT+RGB+LED+MILLIS+AVERAGE
// SAVE THIS FILE AS:
// LCD+I2C+DHT+POT+RGB+LED+MILLIS+AVERAGE_(YOUR INITIALS)
// EXAMPLE - IF IT WERE MINE
// LCD+I2C+DHT+POT+RGB+LED+MILLIS+AVERAGE_CBSL
//****** WRITE YOUR FULL NAME BELOW ********
// Breno Correia Lociks
//************************************************
// EACH PART OF THE CODE MUST BE EXPLAINED.
// ESPECIALLY:
// ==> HOW THE AVERAGE WAS CALCULATED FOR EACH MEASUREMENT
// TEMPERATURE;
// HUMIDITY;
// POTENTIOMETER POSITION
// ==> ALSO EXPLAIN THE USE OF MILLIS
// GLOBAL VARIABLES
// REMEMBER TO EXPLAIN EACH ONE
// LIBRARIES
#include <LiquidCrystal_I2C.h> // Includes the library for I2C LCD control
#include <dht.h> // Includes the library for DHT sensor control
// DEFINITIONS
#define dataPin 8 // Defines digital pin 8 for the DHT sensor
#define Red 2 // Defines digital pin 2 for the red LED of RGB
#define Green 3 // Defines digital pin 3 for the green LED of RGB
#define Blue 4 // Defines digital pin 4 for the blue LED of RGB
#define led_var 5 // Defines digital pin 5 for the LED that indicates temperature variation
#define led_tmp 6 // Defines digital pin 6 for the LED that indicates high temperature
#define led_umd 7 // Defines digital pin 7 for the LED that indicates high humidity
// MILLISECOND VARIABLES FOR RGB AND LCD I2C
unsigned long previousMillisRGB = 0; // Creates variable "previousMillisRGB" to store the last RGB update time in milliseconds
unsigned long previousMillisLCD = 0; // Creates variable "previousMillisLCD" to store the last LCD update time in milliseconds
// SUM AND AVERAGE VARIABLES
float sumTemp = 0; // Creates variable "sumTemp" to store the sum of temperature readings
float sumHum = 0; // Creates variable "sumHum" to store the sum of humidity readings
float sumPot = 0; // Creates variable "sumPot" to store the sum of potentiometer readings
float avgTemp = 0; // Creates variable "avgTemp" to store the average of temperature readings
float avgHum = 0; // Creates variable "avgHum" to store the average of humidity readings
float avgPot = 0; // Creates variable "avgPot" to store the average of potentiometer readings
// COUNTER AND CURRENT SCREEN VARIABLES
int counter = 0; // Creates variable "counter" to store the count
int currentScreen = 0; // Creates variable "currentScreen" to store which screen is currently active on the I2C LCD
// CREATION OF OBJECTS FOR I2C LCD AND DHT SENSOR
LiquidCrystal_I2C lcd(0x27, 16, 2); // Creates "lcd" object for I2C LCD with address 0x27 and 16x2 character display
dht DHT; // Creates "DHT" object for the DHT sensor
void setup() {
// SETTINGS
// REMEMBER TO EXPLAIN EACH ONE
// PIN CONFIGURATION
pinMode(Red, OUTPUT); // Configures the RGB red LED pin as output
pinMode(Green, OUTPUT); // Configures the RGB green LED pin as output
pinMode(Blue, OUTPUT); // Configures the RGB blue LED pin as output
pinMode(led_var, OUTPUT); // Configures the temperature variation LED pin as output
pinMode(led_tmp, OUTPUT); // Configures the high temperature LED pin as output
pinMode(led_umd, OUTPUT); // Configures the high humidity LED pin as output
// LCD INITIALIZATION SETTINGS
lcd.init(); // Initializes the I2C LCD
lcd.setBacklight(HIGH); // Turns on the I2C LCD backlight
}
void loop() {
// MAIN PROGRAM
// REMEMBER TO EXPLAIN EACH PART
// CURRENT TIME IN MILLISECONDS
unsigned long currentMillis = millis(); // Creates variable "currentMillis" to store the current time in milliseconds since program start
// RGB LED READING
int redReading = digitalRead(Red); // Creates variable "redReading" to store the state reading of the RGB red LED
int greenReading = digitalRead(Green); // Creates variable "greenReading" to store the state reading of the RGB green LED
int blueReading = digitalRead(Blue); // Creates variable "blueReading" to store the state reading of the RGB blue LED
// POTENTIOMETER READING AND ANGLE MAPPING
int pot = analogRead(A3); // Creates variable "pot" to store the value read from the potentiometer connected to analog pin A3
int potAngle = map(pot, 0, 1023, 0, 270); // Creates variable "potAngle" to store the mapping of potentiometer reading to a range of 0 to 270 degrees
// DHT SENSOR READING
int readData = DHT.read22(dataPin); // Creates variable "readData" to store data read by the DHT sensor
float t = DHT.temperature; // Creates variable "t" to store the temperature read by the DHT sensor
float h = DHT.humidity; // Creates variable "h" to store the humidity read by the DHT sensor
// LED BRIGHTNESS MAPPING
int t_led = map(t, 10, 20, 0, 255); // Creates variable "t_led" to store the temperature mapping to an LED brightness range
// SUM AND COUNTER OPERATION
sumTemp += t; // Adds the current temperature value to the total sum variable "sumTemp"
sumHum += h; // Adds the current humidity value to the total sum variable "sumHum"
sumPot += pot; // Adds the current potentiometer reading value to the total sum variable "sumPot"
counter++; // Increments the counter variable "counter"
// COUNTER CONTROL
if (counter >= 100) { // Checks if the counter value is greater than or equal to 100
avgTemp = sumTemp / 100.0; // Calculates the temperature average by dividing the sum of readings by 100 and stores the result in variable "avgTemp"
avgHum = sumHum / 100.0; // Calculates the humidity average by dividing the sum of readings by 100 and stores the result in variable "avgHum"
avgPot = sumPot / 100.0; // Calculates the potentiometer reading average by dividing the sum of readings by 100 and stores the result in variable "avgPot"
sumTemp = 0; // Resets the temperature sum
sumHum = 0; // Resets the humidity sum
sumPot = 0; // Resets the potentiometer reading sum
counter = 0; // Resets the counter
}
// AVERAGE MAPPING TO ANGLE
int avgAngle = map(avgPot, 0, 1023, 0, 270); // Creates variable "avgAngle" to store the mapping of the potentiometer reading average to a range of 0 to 270 degrees
// RGB CONTROL
if (potAngle >= 90) { // Checks if the potentiometer angle is greater than or equal to 90 degrees
if ((currentMillis - previousMillisRGB) > 1000) { // Checks if 1000 milliseconds have passed since the last RGB color change
previousMillisRGB = currentMillis; // Updates the RGB timer to the current time in milliseconds
if (redReading == LOW && greenReading == LOW && blueReading == LOW) { // Checks if all three RGB LEDs are off
digitalWrite(Red, HIGH); // Turns on the RGB red LED
}
if (redReading == HIGH) { // Checks if the RGB red LED is on
digitalWrite(Red, LOW); // Turns off the RGB red LED
digitalWrite(Green, HIGH); // Turns on the RGB green LED
}
if (greenReading == HIGH) { // Checks if the RGB green LED is on
digitalWrite(Green, LOW); // Turns off the RGB green LED
digitalWrite(Blue, HIGH); // Turns on the RGB blue LED
}
if (blueReading == HIGH) { // Checks if the RGB blue LED is on
digitalWrite(Blue, LOW); // Turns off the RGB blue LED
}
}
}
else { // Otherwise
digitalWrite(Red, LOW); // Turns off the RGB red LED
digitalWrite(Green, LOW); // Turns off the RGB green LED
digitalWrite(Blue, LOW); // Turns off the RGB blue LED
}
// LED CONTROL
if (avgTemp >= 10 && avgTemp <= 20) { // Checks if the temperature average is between 10 and 20 degrees Celsius
analogWrite(led_var, t_led); // Sets the brightness intensity of the temperature variation LED
}
if (avgTemp > 20) { // Checks if the temperature average is greater than 20 degrees Celsius
digitalWrite(led_var, HIGH); // Turns on the temperature variation LED
}
if (avgTemp < 10) { // Checks if the temperature average is less than 10 degrees Celsius
digitalWrite(led_var, LOW); // Turns off the temperature variation LED
}
if (avgTemp >= 40) { // Checks if the temperature average is greater than or equal to 40 degrees Celsius
digitalWrite(led_tmp, HIGH); // Turns on the high temperature LED
}
else { // Otherwise
digitalWrite(led_tmp, LOW); // Turns off the high temperature LED
}
if (avgHum >= 75) { // Checks if the humidity average is greater than or equal to 75%
digitalWrite(led_umd, HIGH); // Turns on the high humidity LED
}
else { // Otherwise
digitalWrite(led_umd, LOW); // Turns off the high humidity LED
}
// I2C LCD CONTROL
if ((currentMillis - previousMillisLCD) > 1000) { // Checks if 1000 milliseconds have passed since the last LCD screen update
previousMillisLCD = currentMillis; // Updates the LCD timer to the current time in milliseconds
if (currentScreen == 0) { // Checks if it's the first screen of the LCD
lcd.clear(); // Clears the display
lcd.setCursor(0, 0); // Sets the cursor to the first column and first row
lcd.print("Temp = "); // Displays the temperature text
lcd.print(avgTemp); // Displays the temperature average value
lcd.print(" "); // Space
lcd.print((char)223); // Displays the degree symbol
lcd.print("C"); // Displays the Celsius symbol
lcd.setCursor(0, 1); // Sets the cursor to the first column and second row
lcd.print("Hum = "); // Displays the humidity text
lcd.print(avgHum); // Displays the humidity average value
lcd.print((char)37); // Displays the percentage symbol
currentScreen = 1; // Changes to the next screen
}
else if (currentScreen == 1) { // Otherwise, checks if it's the second screen of the LCD
lcd.clear(); // Clears the display
lcd.setCursor(0, 0); // Sets the cursor to the first column and first row
lcd.print("Angle = "); // Displays the potentiometer angle text
lcd.print(avgAngle); // Displays the potentiometer angle value
lcd.print((char)223); // Displays the degree symbol
currentScreen = 0; // Changes back to the previous screen
}
}
}