#include <WiFi.h>
#include <PubSubClient.h>
#include "DHT.h"
#include "Wire.h"
#include "LiquidCrystal_I2C.h"
#include <math.h>
// Pin Definitions
#define POWER_PIN 32 // ESP32's pin GPIO32 that provides the power to the rain sensor
#define DO_PIN 13 // ESP32's pin GPIO13 connected to DO pin of the rain sensor
#define DHT_SENSOR_PIN 21 // ESP32 pin GPIO21 connected to DHT22 sensor
#define BUZZER_PIN 25 // ESP32 pin GPIO25 connected to Buzzer
#define LIGHT_SENSOR_PIN 32 // ESP32 pin GIOP36 (ADC0)
// Define WiFi credentials
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// Define ThingsBoard connection details
const char* mqttServer = "cloud.thingsboard.io";
const int mqttPort = 1883;
const char* deviceAccessToken = "JNKGjoIlHNMcfRFELGdw";
// Create a WiFiClient and PubSubClient objects
WiFiClient espClient;
PubSubClient client(espClient);
// Create an LCD object
LiquidCrystal_I2C lcd(0x27, 20, 2);
// DHT Sensor Object
DHT dht_sensor(DHT_SENSOR_PIN, DHT22);
float GAMMA = 0.7;
float RL10 = 85;
void setup() {
// Initialize Serial Communication
Serial.begin(9600);
// Connect to WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(3000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi");
// Set up MQTT connection
client.setServer(mqttServer, mqttPort);
// Initialize the Arduino's pins as input/output pins
pinMode(POWER_PIN, OUTPUT);
pinMode(DO_PIN, INPUT);
pinMode(BUZZER_PIN, OUTPUT);
// Initialize the DHT sensor
dht_sensor.begin();
lcd.begin(20, 2);
lcd.init();
lcd.backlight();
lcd.print(" Magic Sensor"); // First part of the message
lcd.setCursor(0, 1); // Move cursor to the start of the second line
lcd.print(" Weatherman"); // Second part of the message
delay(100); // Delay for 3 seconds to keep the initial message on the screen
}
void loop() {
// Connect to MQTT server
if (!client.connected()) {
reconnect();
}
// Read humidity and temperature from DHT sensor
float humi = dht_sensor.readHumidity();
float tempC = dht_sensor.readTemperature();
// Calculate temperature in Fahrenheit
float tempF = tempC * 9.0 / 5.0 + 32;
// Print temperature and humidity to LCD - Sequence 1
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Temp: ");
lcd.print(tempC);
lcd.print("C");
lcd.setCursor(0, 1);
lcd.print("Humidity: ");
lcd.print(humi);
lcd.print("%");
// Print temperature and humidity to serial terminal - Sequence 1
Serial.print("Temperature (C): ");
Serial.print(tempC);
Serial.println(" C");
Serial.print("Humidity: ");
Serial.print(humi);
Serial.println(" %");
// Publish temperature and humidity data to ThingsBoard
publishTelemetry("Temperature", String(tempC));
publishTelemetry("Humidity", String(humi));
delay(1000); // Wait for 1 seconds
// Print temperature and humidity to LCD - Sequence 2
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Temp: ");
lcd.print(tempF);
lcd.print("F");
lcd.setCursor(0, 1);
lcd.print("Humidity: ");
lcd.print(humi);
lcd.print("%");
// Print temperature and humidity to serial terminal - Sequence 2
Serial.print("Temperature (F): ");
Serial.print(tempF);
Serial.println(" F");
Serial.print("Humidity: ");
Serial.print(humi);
Serial.println(" %");
// Rain Sensor Part
digitalWrite(POWER_PIN, HIGH); // Turn the rain sensor's power ON
delay(10); // Wait 10 milliseconds
int rain_state = digitalRead(DO_PIN); // Read the digital output state
digitalWrite(POWER_PIN, LOW); // Turn the rain sensor's power OFF
// Print rain state to LCD - Sequence 3
lcd.clear();
lcd.setCursor(0, 0);
if (rain_state == LOW) {
lcd.print("Weather: Clear");
digitalWrite(BUZZER_PIN, LOW); // Turn the buzzer OFF
} else {
lcd.print("Weather: Rainy");
digitalWrite(BUZZER_PIN, HIGH); // Turn the buzzer ON
}
delay(1000); // Pause for 1 seconds
lcd.clear(); // Clear the LCD
// Print rain state to serial terminal - Sequence 3
Serial.print("Weather: ");
Serial.println(rain_state == LOW ? "Clear" : "Rainy");
// Convert the analog value into lux value:
int analog_value = analogRead(LIGHT_SENSOR_PIN);
float voltage = analog_value / 4095.0 * 3.3;
float resistance = 5000 * voltage / (1 - voltage / 3.3);
float lux = pow(RL10 * 1000 * pow(10, GAMMA) / resistance, (1 / GAMMA));
// Determine light intensity category
String lightCategory;
if (lux > 0.1 && lux <= 1) {
lightCategory = "Dark";
} else if (lux > 1 && lux <= 10) {
lightCategory = "Dim";
} else if (lux > 10 && lux <= 100) {
lightCategory = "Dull";
} else if (lux > 100 && lux <= 1000) {
lightCategory = "Drab";
} else if (lux > 1000 && lux <= 5000) {
lightCategory = "Gloomy";
} else if (lux > 5000 && lux <= 10000) {
lightCategory = "Glowing";
} else if (lux > 10000 && lux <= 25000) {
lightCategory = "Shining";
} else if (lux > 25000 && lux <= 50000) {
lightCategory = "Bright";
} else if (lux > 50000) {
lightCategory = "Luminous";
} else {
lightCategory = "Out of range";
}
// Publish weather and daylight data to ThingsBoard
publishTelemetry("Weather", rain_state == LOW ? "Clear" : "Rainy");
publishTelemetry("Brightness", lightCategory);
publishTelemetry("Illumination", String(lux));
// Print lux and light category to LCD - Sequence 4
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Lux: ");
lcd.print(lux);
lcd.setCursor(0, 1);
lcd.print("Light: ");
lcd.print(lightCategory);
// Print lux and light category to serial terminal - Sequence 4
Serial.print("Lux: ");
Serial.println(lux);
Serial.print("Brightness: ");
Serial.println(lightCategory);
delay(1000); // Pause for 1 seconds
lcd.clear(); // Clear the LCD
}
void reconnect() {
// Loop until connected to MQTT server
while (!client.connected()) {
Serial.print("Connecting to ThingsBoard...");
if (client.connect("ESP32 Device", deviceAccessToken, NULL)) {
Serial.println("Connected");
} else {
Serial.print("Failed, rc=");
Serial.print(client.state());
Serial.println("Retrying in 3 seconds...");
delay(3000);
}
}
}
void publishTelemetry(const char* key, String value) {
String telemetryTopic = String("v1/devices/me/telemetry");
String payload = String("{\"") + key + String("\":\"") + value + String("\"}");
client.publish(telemetryTopic.c_str(), payload.c_str());
}