#include <LiquidCrystal.h>
#include <Wire.h>
#include <RTClib.h>
#include <DHT.h>
#include <Servo.h>
// Define the pins for the first LCD
const int rs1 = 22, en1 = 23, d4_1 = 24, d5_1 = 25, d6_1 = 26, d7_1 = 27;
LiquidCrystal lcd1(rs1, en1, d4_1, d5_1, d6_1, d7_1);
// Define the pins for the second LCD
const int rs2 = 28, en2 = 29, d4_2 = 30, d5_2 = 31, d6_2 = 32, d7_2 = 33;
LiquidCrystal lcd2(rs2, en2, d4_2, d5_2, d6_2, d7_2);
// Define the pins for the pushbuttons
const int buttonPin1 = 35;
const int buttonPin2 = 36;
const int buttonPin3 = 37;
const int buttonPin4 = 38;
const int buttonPin5 = 39;
bool buttonState1 = false;
bool buttonState2 = false;
bool buttonState3 = false;
bool buttonState4 = false;
bool buttonState5 = false;
// Initialize the RTC
RTC_DS3231 rtc;
// Define the pins for the DHT sensors
const int DHT1_PIN = 40; // Pin for first DHT sensor
const int DHT2_PIN = 41; // Pin for second DHT sensor
const int DHT3_PIN = 42; // Pin for third DHT sensor
#define DHTTYPE DHT22 // Change this to DHT22 if using DHT22 sensors
DHT dht1(DHT1_PIN, DHTTYPE);
DHT dht2(DHT2_PIN, DHTTYPE);
DHT dht3(DHT3_PIN, DHTTYPE);
// Define servo objects and pins
Servo servo1;
const int servoPin1 = 43; // Pin for first servo motor
Servo servo2;
const int servoPin2 = 44; // Pin for second servo motor
// Variable to store temperature unit (0 = Celsius, 1 = Fahrenheit)
int temperatureUnit = 0;
// Variable to track servo angles
int servo1Angle = 0;
int servo2Angle = 0;
void setup() {
// Set up the first LCD
lcd1.begin(20, 4);
lcd1.print("Avg Temp: ");
lcd1.setCursor(0, 1);
lcd1.print("Avg Humidity: ");
lcd1.setCursor(0, 2);
lcd1.print("Time: ");
lcd1.setCursor(0, 3);
lcd1.print("Date: ");
// Set up the second LCD
lcd2.begin(20, 4);
lcd2.print("Sensor 1 Temp: ");
lcd2.setCursor(0, 1);
lcd2.print("Sensor 1 Humidity: ");
lcd2.setCursor(0, 2);
lcd2.print("Sensor 2 Temp: ");
lcd2.setCursor(0, 3);
lcd2.print("Sensor 2 Humidity: ");
// Set up the pushbutton pins
pinMode(buttonPin1, INPUT_PULLUP);
pinMode(buttonPin2, INPUT_PULLUP);
pinMode(buttonPin3, INPUT_PULLUP);
pinMode(buttonPin4, INPUT_PULLUP);
pinMode(buttonPin5, INPUT_PULLUP);
// Initialize the I2C communication
Wire.begin();
// Check if the RTC is working
if (!rtc.begin()) {
lcd1.print("RTC not detected!");
lcd2.print("RTC not detected!");
while (1);
}
// If the RTC lost power, set the time to the compiled time
if (rtc.lostPower()) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
// Initialize DHT sensors
dht1.begin();
dht2.begin();
dht3.begin();
// Attach servo objects to pins
servo1.attach(servoPin1);
servo2.attach(servoPin2);
}
void loop() {
// Read state of the pushbuttons
buttonState1 = digitalRead(buttonPin1);
buttonState2 = digitalRead(buttonPin2);
buttonState3 = digitalRead(buttonPin3);
buttonState4 = digitalRead(buttonPin4);
buttonState5 = digitalRead(buttonPin5);
// Check if Button 1 is pressed to toggle temperature unit
if (buttonState1 == LOW) {
temperatureUnit = 1 - temperatureUnit; // Toggle between 0 and 1
delay(200); // Debounce delay
}
// Clear previous values on LCD
lcd1.setCursor(10, 0);
lcd1.print(" ");
lcd1.setCursor(15, 1);
lcd1.print(" ");
lcd1.setCursor(6, 2);
lcd1.print(" ");
lcd1.setCursor(6, 3);
lcd1.print(" ");
// Read and display temperature and humidity from DHT sensors
float temperature1 = dht1.readTemperature();
float humidity1 = dht1.readHumidity();
float temperature2 = dht2.readTemperature();
float humidity2 = dht2.readHumidity();
float temperature3 = dht3.readTemperature();
float humidity3 = dht3.readHumidity();
// Calculate average temperature and humidity
float avgTemp = (temperature1 + temperature2 + temperature3) / 3.0;
float avgHumidity = (humidity1 + humidity2 + humidity3) / 3.0;
// Print sensor readings on the first LCD
lcd1.setCursor(10, 0);
lcd1.print(convertTemperature(avgTemp), 1);
lcd1.print(getTemperatureUnit());
lcd1.setCursor(15, 1);
lcd1.print(avgHumidity, 1);
lcd1.print("%");
// Read the current time from RTC
DateTime now = rtc.now();
// Print time on the first LCD
lcd1.setCursor(6, 2);
if (now.hour() > 12) {
lcd1.print(now.hour() - 12);
} else if (now.hour() == 0) {
lcd1.print(12);
} else {
lcd1.print(now.hour());
}
lcd1.print(':');
if (now.minute() < 10) lcd1.print('0');
lcd1.print(now.minute());
lcd1.print(':');
if (now.second() < 10) lcd1.print('0');
lcd1.print(now.second());
lcd1.print(now.hour() >= 12 ? " PM" : " AM");
// Print date on the first LCD
lcd1.setCursor(6, 3);
lcd1.print(now.year(), DEC);
lcd1.print('/');
lcd1.print(now.month(), DEC);
lcd1.print('/');
lcd1.print(now.day(), DEC);
// Control servo motors based on button presses
if (buttonState2 == LOW) {
rotateServo1();
delay(200); // Debounce delay
}
if (buttonState3 == LOW) {
rotateServo2();
delay(200); // Debounce delay
}
// Print sensor readings on the second LCD
lcd2.setCursor(15, 0);
lcd2.print(temperature1, 1);
lcd2.print(" C");
lcd2.setCursor(19, 1);
lcd2.print(humidity1, 1);
lcd2.print(" %");
lcd2.setCursor(15, 2);
lcd2.print(temperature2, 1);
lcd2.print(" C");
lcd2.setCursor(19, 3);
lcd2.print(humidity2, 1);
lcd2.print(" %");
// Add some delay to make the display readable
delay(1000);
}
// Function to convert temperature to Fahrenheit if needed
float convertTemperature(float tempCelsius) {
if (temperatureUnit == 1) {
return (tempCelsius * 9.0 / 5.0) + 32.0; // Convert Celsius to Fahrenheit
}
return tempCelsius; // Return Celsius if already in Celsius
}
// Function to get temperature unit string
String getTemperatureUnit() {
if (temperatureUnit == 1) {
return "F";
}
return "C";
}
// Function to rotate servo1 to 90° and back to 0°
void rotateServo1() {
if (servo1Angle == 0) {
servo1.write(90); // Rotate servo1 to 90°
servo1Angle = 90;
} else {
servo1.write(0); // Rotate servo1 back to 0°
servo1Angle = 0;
}
}
// Function to rotate servo2 to 45° and back to 0°
void rotateServo2() {
if (servo2Angle == 0) {
servo2.write(45); // Rotate servo2 to 45°
servo2Angle = 45;
} else {
servo2.write(0); // Rotate servo2 back to 0°
servo2Angle = 0;
}
}