#include <WiFi.h>
#include <PubSubClient.h>
#include "DHTesp.h"
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <ESP32Servo.h>
#include <ArduinoJson.h>
#define DHT_PIN 15
#define BUZZER 5
#define LDR1 34
#define LDR2 35
#define MOTOR 16
DHTesp dhtSensor;
WiFiClient espClient;
PubSubClient mqttClient(espClient);
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
Servo motor;
JsonDocument packet;
char tempAr[6];
char motorAr[6];
char angleAr[6];
char ctrlAr[6];
const float analogMinValue = 0.0;
const float analogMaxValue = 1023.0;
const float intensityMin = 0.0;
const float intensityMax = 1.0;
float minAngle = 30.0;
float controllingFac = 0.75;
float customAngle = 30;
float customControlFac = 0;
bool isScheduledON= false;
unsigned long scheduledOnTime;
void setup() {
Serial.begin(115200);
setupMqtt();
setupWiFi();
dhtSensor.setup(DHT_PIN,DHTesp::DHT22);
timeClient.begin();
timeClient.setTimeOffset(5.5*3600);
pinMode(BUZZER, OUTPUT);
digitalWrite(BUZZER,LOW);
pinMode(LDR1, INPUT);
pinMode(LDR2, INPUT);
motor.attach(MOTOR, 600, 2400);
connectToBroker();
String(minAngle, 2).toCharArray(angleAr, 6);
String(controllingFac, 2).toCharArray(ctrlAr, 6);
mqttClient.publish("MEDIBOX-SET-ANG", angleAr);
mqttClient.publish("MEDIBOX-SET-FAC", ctrlAr);
}
void loop() {
if(!mqttClient.connected()){
connectToBroker();
}
mqttClient.loop();
updateTemperature();
//Serial.println(tempAr);
//mqttClient.publish("ENTC-TEMP",tempAr);
updateLightIntensity();
checkSchedule();
delay(1000);
}
void setupWiFi(){
Serial.println("");
Serial.println("Connecting to");
Serial.println("Wokwi-GUEST");
WiFi.begin("Wokwi-GUEST","");
while(WiFi.status()!=WL_CONNECTED){
delay(500);
Serial.print(".");
}
Serial.println("WiFi connected");
Serial.println("IP address");
Serial.println(WiFi.localIP());
}
void updateTemperature(){
TempAndHumidity data = dhtSensor.getTempAndHumidity();
String(data.temperature,2).toCharArray(tempAr,6);
mqttClient.publish("MEDIBOX-TEMP", tempAr);
delay((1000));
}
void updateLightIntensity()
{
float rightLDR = analogRead(LDR1);
float leftLDR = analogRead(LDR2);
float intensity = 0;
char dataJson[50];
if (rightLDR > leftLDR)
{
packet["LDR"] = "Right LED";
if (rightLDR <= 1023)
{
intensity = (rightLDR - analogMinValue) / (analogMaxValue - analogMinValue);
AdjustServoMotor(intensity, 0.5);
}
else
{
intensity = 1;
AdjustServoMotor(intensity, 0.5);
}
}
else
{
packet["LDR"] = "Left LED";
if (leftLDR <= 1023)
{
intensity = (leftLDR - analogMinValue) / (analogMaxValue - analogMinValue);
AdjustServoMotor(intensity, 1.5);
}
else
{
intensity = 1;
AdjustServoMotor(intensity, 1.5);
}
}
packet["Intensity"] = String(intensity);
serializeJson(packet, dataJson);
mqttClient.publish("MEDIBOX-LIGHT-INTENSITY", dataJson);
}
void setupMqtt(){
mqttClient.setServer("test.mosquitto.org",1883);
mqttClient.setCallback(receiveCallback);
}
void connectToBroker(){
while(!mqttClient.connected()){
Serial.print("Attempting MQTT connection...");
if(mqttClient.connect("ESP32-4654564645645")){
Serial.println("connected");
mqttClient.subscribe("MEDIBOX-ON-OFF");
mqttClient.subscribe("MEDIBOX-SCHEDULE-ON-OFF");
mqttClient.subscribe("MEDIBOX-DROP-DOWN");
mqttClient.subscribe("MEDIBOX-MIN-ANG");
mqttClient.subscribe("MEDIBOX-CTRL-FAC");
}else{
Serial.print("Failed");
Serial.println(mqttClient.state());
delay(5000);
}
}
}
void buzzerOn(bool on){
if(on){
tone(BUZZER,256);
}else{
noTone(BUZZER);
}
}
void receiveCallback(char* topic,byte* payload, unsigned int length){
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("]");
char payloadCharAr[length];
for(int i=0;i<length;i++){
Serial.print((char)payload[i]);
payloadCharAr[i]=(char)payload[i];
}
Serial.println();
if(strcmp(topic,"MEDIBOX-ON-OFF")==0){
buzzerOn(payloadCharAr[0]=='1');
}else if(strcmp(topic,"MEDIBOX-SCHEDULE-ON-OFF")==0){
if(payloadCharAr[0]=='N'){
isScheduledON = false;
}else{
isScheduledON = true;
scheduledOnTime=atol(payloadCharAr);
}
}
if (strcmp(topic, "MEDIBOX-MIN-ANG") == 0)
{
minAngle = atof(payloadCharAr);
Serial.println(minAngle);
}
if (strcmp(topic, "MEDIBOX-CTRL-FAC") == 0)
{
controllingFac = atof(payloadCharAr);
Serial.println(controllingFac);
}
if (strcmp(topic, "MEDIBOX-DROP-DOWN") == 0)
{
if (payloadCharAr[0] == 'D')
{
minAngle = 30;
controllingFac = 0.75;
Serial.println("Angle:" + String(minAngle) + " and Control Factor: " + String(controllingFac));
mqttClient.publish("MEDIBOX-SET-ANG", "30");
mqttClient.publish("MEDIBOX-SET-FAC", "0.75");
}
else if (payloadCharAr[0] == 'A')
{
minAngle = 30;
controllingFac = 0.5;
Serial.println("Angle:" + String(minAngle) + " and Control Factor: " + String(controllingFac));
mqttClient.publish("MEDIBOX-SET-ANG", "30");
mqttClient.publish("MEDIBOX-SET-FAC", "0.5");
}
else if (payloadCharAr[0] == 'B')
{
minAngle = 45;
controllingFac = 0.3;
Serial.println("Angle:" + String(minAngle) + " and Control Factor: " + String(controllingFac));
mqttClient.publish("MEDIBOX-SET-ANG", "45");
mqttClient.publish("MEDIBOX-SET-FAC", "0.3");
}
else if (payloadCharAr[0] == 'C')
{
minAngle = 60;
controllingFac = 0.8;
Serial.println("Angle:" + String(minAngle) + " and Control Factor: " + String(controllingFac));
mqttClient.publish("MEDIBOX-SET-ANG", "60");
mqttClient.publish("MEDIBOX-SET-FAC", "0.8");
}
else if (payloadCharAr[0] == 'X')
{
String(customAngle, 2).toCharArray(angleAr, 6);
String(customControlFac, 2).toCharArray(ctrlAr, 6);
mqttClient.publish("MEDIBOX-SET-ANG", angleAr);
mqttClient.publish("MEDIBOX-SET-FAC", ctrlAr);
if (strcmp(topic, "MEDIBOX-MIN-ANG") == 0)
{
minAngle = atof(payloadCharAr);
Serial.println(minAngle);
mqttClient.publish("MEDIBOX-SET-ANG", "60");
}
if (strcmp(topic, "MEDIBOX-CTRL-FAC") == 0)
{
controllingFac = atof(payloadCharAr);
Serial.println(controllingFac);
}
}
}
}
unsigned long getTime(){
timeClient.update();
return timeClient.getEpochTime();
}
void checkSchedule(){
if(isScheduledON){
unsigned long currentTime =getTime();
if (currentTime>scheduledOnTime){
buzzerOn(true);
isScheduledON=false;
//mqttClient.publish("ENTC-ON-OFF","1");
mqttClient.publish("MEDIBOX-SCHEDULE-ON-OFF","0");
Serial.println("Scheduled ON");
}
}
}
void AdjustServoMotor(double lightintensity, double D)
{
double angle = minAngle * D + (180.0 - minAngle) * lightintensity * controllingFac;
angle = min(angle, 180.0);
motor.write(angle);
String(angle-90, 2).toCharArray(motorAr, 6);
mqttClient.publish("MEDIBOX-MOTOR-ANG", motorAr);
}