#define BLYNK_TEMPLATE_ID "TMPL3yxAu7IqA"
#define BLYNK_TEMPLATE_NAME "Automation"
#define BLYNK_AUTH_TOKEN "x_AGP7hJBhYzqhrOA08AKJJaBD5d7VDM"
#define WIFI_SSID "Wokwi-GUEST"
#define WIFI_PASSWORD ""
#define WIFI_CHANNEL 6
#define LDR_PIN 2
#define BLYNK_PRINT Serial
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include <ESP32Servo.h>
#include "DHTesp.h"
#include <LiquidCrystal_I2C.h>
#include "RTClib.h"
const float GAMMA = 0.7;
const float RL10 = 50;
const int DHT_PIN = 15;
DHTesp dhtSensor;
Servo servo_9;
BlynkTimer timer;
RTC_DS1307 rtc;
LiquidCrystal_I2C lcd(0x27, 20, 4);
int lullabyMode = 0;
int sleepTime = 20;
// Virtual Pin 0 state change
BLYNK_WRITE(V0)
{
lullabyMode = param.asInt();
if (lullabyMode == 1) {
Blynk.virtualWrite(V1, "ON");
} else {
Blynk.virtualWrite(V1, "OFF");
}
}
BLYNK_WRITE(V4)
{
sleepTime = param.asInt();
lcd.setCursor(13, 3);
lcd.print(" ");
lcd.setCursor(13, 3);
lcd.print(sleepTime);
}
// Blynk connection handler
BLYNK_CONNECTED()
{
Blynk.setProperty(V3, "offImageUrl", "https://static-image.nyc3.cdn.digitaloceanspaces.com/general/fte/congratulations.png");
Blynk.setProperty(V3, "onImageUrl", "https://static-image.nyc3.cdn.digitaloceanspaces.com/general/fte/congratulations_pressed.png");
Blynk.setProperty(V3, "url", "https://docs.blynk.io/en/getting-started/what-do-i-need-to-blynk/how-quickstart-device-was-made");
}
// Timer Event 1
void myTimerEvent()
{
int pos = 0;
DateTime now = rtc.now();
TempAndHumidity data = dhtSensor.getTempAndHumidity();
lcd.setCursor(14, 0);
if (data.temperature > 35) {
lcd.print(" ");
lcd.setCursor(14, 0);
lcd.print("CRYING");
servo_9.write(90); // Stop the servo motion
Blynk.virtualWrite(V1, "OFF");
Blynk.logEvent("crying_condition", "Baby is crying due to high temperature!");
return;
}
if ((lullabyMode == 1) || (digitalRead(LDR_PIN) == !HIGH) || (now.hour() == sleepTime)) {
lcd.print(" ");
lcd.setCursor(14, 0);
lcd.print("ON");
Blynk.virtualWrite(V1, "ON");
for (pos = 90; pos <= 120; pos += 1) {
servo_9.write(pos);
delay(20);
}
for (pos = 120; pos >= 60; pos -= 1) {
servo_9.write(pos);
delay(20);
}
for (pos = 60; pos <= 90; pos += 1) {
servo_9.write(pos);
delay(20);
}
} else {
lcd.print("OFF");
servo_9.write(90);
Blynk.virtualWrite(V1, "OFF");
}
}
// Timer Event 2
// Define notification counters
int babyCryingCounter = 0;
int roomConditionCounter = 0;
const int MAX_NOTIFICATIONS = 3;
void resetNotificationCounters() {
// Reset counters periodically (e.g., every hour)
babyCryingCounter = 0;
roomConditionCounter = 0;
}
// Timer Event 2
void myTimerEvent2()
{
static unsigned long cryingStartTime = 0;
static bool isCrying = false;
if (digitalRead(LDR_PIN) == !HIGH) {
if (!isCrying) {
cryingStartTime = millis();
isCrying = true;
} else if (millis() - cryingStartTime > 5000 && babyCryingCounter < MAX_NOTIFICATIONS) {
Serial.println("Baby has been crying for more than 5 seconds!");
Blynk.logEvent("long_crying", "Baby has been crying for more than 5 seconds");
babyCryingCounter++;
}
if (babyCryingCounter < MAX_NOTIFICATIONS) {
Serial.println("Baby crying");
Blynk.logEvent("baby_crying", "Baby's Crying");
babyCryingCounter++;
}
} else {
if (isCrying) {
isCrying = false;
cryingStartTime = 0;
}
Serial.println("Baby sleeping");
}
TempAndHumidity data = dhtSensor.getTempAndHumidity();
Blynk.virtualWrite(V2, data.temperature);
Blynk.virtualWrite(V3, data.humidity);
lcd.setCursor(2, 1);
lcd.print("Temp: " + String(data.temperature, 2) + "°C");
Serial.println("Temp: " + String(data.temperature, 2) + "°C");
lcd.setCursor(2, 2);
lcd.print("Humidity: " + String(data.humidity, 1) + "%");
Serial.println("Humidity: " + String(data.humidity, 1) + "%");
// Room condition notifications
if (data.temperature > 40 && roomConditionCounter < MAX_NOTIFICATIONS) {
Blynk.logEvent("room_too_hot", "Room is too hot");
roomConditionCounter++;
} else if (data.temperature < 20 && roomConditionCounter < MAX_NOTIFICATIONS) {
Blynk.logEvent("room_too_cold", "Room is too cold");
roomConditionCounter++;
} else if (data.humidity > 70 && roomConditionCounter < MAX_NOTIFICATIONS) {
Blynk.logEvent("room_too_humid", "Room's humidity is too high");
roomConditionCounter++;
} else if (data.humidity < 30 && roomConditionCounter < MAX_NOTIFICATIONS) {
Blynk.logEvent("room_too_dry", "Room's humidity is too low");
roomConditionCounter++;
}
// Brightness condition
if (digitalRead(LDR_PIN) == HIGH && roomConditionCounter < MAX_NOTIFICATIONS) {
Blynk.logEvent("room_too_bright", "Room is too bright for sleeping");
roomConditionCounter++;
}
}
void setup()
{
Serial.begin(115200);
Serial.print("Connecting to WiFi");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD, WIFI_CHANNEL);
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
}
Serial.println(" Connected!");
Blynk.begin(BLYNK_AUTH_TOKEN, WIFI_SSID, WIFI_PASSWORD);
servo_9.attach(4, 500, 2500);
pinMode(LDR_PIN, INPUT);
dhtSensor.setup(DHT_PIN, DHTesp::DHT22);
lcd.init();
lcd.backlight();
timer.setInterval(1000L, myTimerEvent);
timer.setInterval(500L, myTimerEvent2);
timer.setInterval(3600000L, resetNotificationCounters); // Reset counters every hour
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
abort();
}
lcd.setCursor(1, 0);
lcd.print("Lullaby mode:");
lcd.setCursor(1, 3);
lcd.print("Sleep time: ");
lcd.setCursor(13, 3);
lcd.print(sleepTime);
lcd.setCursor(15, 3);
lcd.print("h");
}
void loop()
{
Blynk.run();
timer.run();
}