#include <DHT.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h> // Include the LCD library
#include <Servo.h> // Include the Servo library
#define DHTPIN 2 // Pin where the DHT22 sensor is connected
#define DHTTYPE DHT22 // Define the DHT22 sensor type
DHT dht(DHTPIN, DHTTYPE); // Create DHT object
LiquidCrystal_I2C lcd(0x27, 16, 2); // Create LCD object with I2C address 0x27 (default)
// Define the number of LEDs in the Wokwi LED Bar Graph
const int ledPins[] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; // Connect the LED bar graph to these pins
const int numLEDs = 10; // Number of LEDs in the bar graph
Servo myServo; // Create servo object to control the servo motor
// Define the initial servo position and speed multiplier
int servoPosition = 0;
float speedMultiplier = 1.0;
// Define the Wokwi LED on pin 13
const int ledPin = 13; // Wokwi LED connected to pin 13
void setup() {
Serial.begin(9600); // Start serial communication at 9600 baud
Serial.println("DHT sensor test");
dht.begin(); // Initialize the DHT sensor
lcd.begin(16, 2); // Initialize the LCD screen (16x2)
lcd.print("DHT22 Sensor"); // Display initial message on LCD
delay(2000); // Wait for a while to show the initial message
lcd.clear(); // Clear the screen
// Initialize the LED bar graph pins
for (int i = 0; i < numLEDs; i++) {
pinMode(ledPins[i], OUTPUT); // Set each LED pin as an output
}
// Attach the servo to pin 13
myServo.attach(13);
// Initialize the Wokwi LED pin
pinMode(ledPin, OUTPUT); // Set the LED pin as an output
}
void loop() {
delay(2000); // Wait 2 seconds before reading again
// Read temperature and humidity from the DHT22 sensor
float h = dht.readHumidity(); // Read humidity
float t = dht.readTemperature(); // Read temperature
// Check if the readings are valid (returns NaN if invalid)
if (isnan(h) || isnan(t)) {
lcd.clear();
lcd.print("Error reading!");
Serial.println("Failed to read from DHT sensor!");
return; // Skip the rest of the loop and try again
}
// Display the temperature and humidity values on the LCD
lcd.clear();
lcd.setCursor(0, 0); // Set cursor to the first row
lcd.print("Temp: ");
lcd.print(t); // Print temperature on the LCD
lcd.print(" C");
lcd.setCursor(0, 1); // Set cursor to the second row
lcd.print("Humidity: ");
lcd.print(h); // Print humidity on the LCD
lcd.print(" %");
// Map the temperature to the LED bar graph
int tempLEDs = mapTemperatureToLED(t);
// Update the LED bar graph based on the temperature
updateLEDs(tempLEDs);
// Control the servo motor based on the temperature
if (t > 20) {
// Increase speed multiplier for every 5°C above 20°C
int speedLevel = (t - 20) / 5; // How many 5°C increments above 20°C
speedMultiplier = 1.0 + (speedLevel * 0.2);
// Rotate the servo continuously and increase speed
for (servoPosition = 0; servoPosition <= 180; servoPosition++) {
myServo.write(servoPosition); // Rotate servo to current position
delay(15 / speedMultiplier); // Delay adjusted by speedMultiplier
}
for (servoPosition = 180; servoPosition >= 0; servoPosition--) {
myServo.write(servoPosition); // Rotate servo back
delay(15 / speedMultiplier); // Delay adjusted by speedMultiplier
}
} else {
// If temperature is below or equal to 20°C, stop the servo
myServo.write(0); // Set servo to initial position (0 degrees)
}
// Blink the Wokwi LED if the temperature is above 40°C
if (t > 40) {
digitalWrite(ledPin, HIGH); // Turn on the LED
delay(500); // Wait for 500 milliseconds (0.5 seconds)
digitalWrite(ledPin, LOW); // Turn off the LED
delay(500); // Wait for another 500 milliseconds (0.5 seconds)
} else {
// If the temperature is below or equal to 40°C, keep the LED off
digitalWrite(ledPin, LOW); // Ensure the LED is off
}
// Print the temperature and humidity to the Serial Monitor as well
Serial.print("Temperature: ");
Serial.println(t);
Serial.print("Humidity: ");
Serial.println(h);
}
// Function to map temperature (-40 to 80°C) to LED range (0 to 10 LEDs)
int mapTemperatureToLED(float temp) {
// Map the temperature from the range of -40°C to 80°C to the range 0 to numLEDs
int mappedLED = map(temp, -40, 80, 0, numLEDs);
// Ensure that the value stays within the valid range (0 to numLEDs)
if (mappedLED < 0) {
mappedLED = 0;
}
if (mappedLED > numLEDs) {
mappedLED = numLEDs;
}
return mappedLED;
}
// Function to update the LED bar graph based on the mapped temperature
void updateLEDs(int numActiveLEDs) {
// Loop through all LEDs (0 to numLEDs - 1) and turn on the corresponding LEDs
for (int i = 0; i < numLEDs; i++) {
if (i < numActiveLEDs) {
digitalWrite(ledPins[i], HIGH); // Turn on the LED
} else {
digitalWrite(ledPins[i], LOW); // Turn off the LED
}
}
}