#include <PubSubClient.h>
#include <WiFi.h>
#include <DHTesp.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <ESP32Servo.h>
#define BUZZER 12
#define LDR_L 35
#define LDR_R 34
#define SERVOMOTOR 18
const int DHT_PIN = 15;
//Parameters related to light intensity
float GAMMA = 0.75;
const float RL10 = 50;
float MIN_ANGLE = 30;
//float lux = 0;
//servo moter initializing position
int pos = 0;
Servo servo;
WiFiClient espClient;
PubSubClient mqttClient(espClient);
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
DHTesp dhtSensor;
char lightAr_L[6];
char lightAr_R[6];
char tempAr[6];
bool isScheduledON = false;
unsigned long scheduledOnTime;
void setup() {
pinMode(LDR_L, INPUT);
pinMode(LDR_R, INPUT);
Serial.begin(115200);
setupWiFi();
setupMqtt();
dhtSensor.setup(DHT_PIN, DHTesp::DHT22);
servo.attach(SERVOMOTOR, 500, 2400);
timeClient.begin();
timeClient.setTimeOffset(5.5*3600);
pinMode(BUZZER, OUTPUT);
digitalWrite(BUZZER, LOW);
analogRead(LDR_L);
analogRead(LDR_R);
}
void loop() {
if (!mqttClient.connected()){
connectToBroker();
}
mqttClient.loop();
updateTemperature();
mqttClient.publish("ENTC-TEMP", tempAr);
mqttClient.publish("LEFT-LDR", lightAr_L);
mqttClient.publish("RIGHT-LDR", lightAr_R);
monitorIntensity();
checkSchedule();
delay(1000);
}
void setupWiFi(){
Serial.println();
Serial.print("Connecting to ");
Serial.println("Wokwi-GUEST");
WiFi.begin("Wokwi-GUEST", "");
while (WiFi.status() != WL_CONNECTED){
delay(500);
Serial.print(".");
}
Serial.println("");
}
void setupMqtt(){
mqttClient.setServer("test.mosquitto.org", 1883);
mqttClient.setCallback(receiveCallback);
}
void connectToBroker(){
while (!mqttClient.connected()){
Serial.print("Attemping MQTT connection...");
if(mqttClient.connect("ESP32-477585895")){
Serial.println("Connected...");
mqttClient.subscribe("ENTC-ON-OFF");
mqttClient.subscribe("ENTC-SCH-ON");
mqttClient.subscribe("MINIMUM-ANGLE");
mqttClient.subscribe("CONT-FACTOR");
}else {
Serial.println("Failed");
Serial.print(mqttClient.state());
delay(5000);
}
}
}
void updateTemperature(){
TempAndHumidity data = dhtSensor.getTempAndHumidity();
String(data.temperature, 2).toCharArray(tempAr,6);
}
void receiveCallback(char* topic, byte* payload, unsigned int length){
Serial.print("Message arrived [");
Serial.print(topic);
Serial.println("]");
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, "ENTC-ON-OFF") == 0){
buzzerOn(payloadCharAr[0]=='1');
}else if(strcmp(topic, "ENTC-SCH-ON") == 0){
if(payloadCharAr[0]=='N'){
isScheduledON = false;
}else{
isScheduledON = true;
scheduledOnTime = atol(payloadCharAr);
}
}
//receive minimum angle
if (strcmp(topic, "MINIMUM-ANGLE") == 0){
MIN_ANGLE = atoi(payloadCharAr);
}
//receive control factor
if (strcmp(topic, "CONT-FACTOR") == 0) {
GAMMA = atof(payloadCharAr);
if(GAMMA>1){
GAMMA = 1;
}
}
}
void buzzerOn(bool on){
if(on) {
tone(BUZZER, 256);
}else{
noTone(BUZZER);
}
}
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-ADMIN-MAIN-ON-OFF-ESP", "1");
mqttClient.publish("ENTC-ADMIN-SCH-ESP-ON", "0");
Serial.println("Scheduled ON");
}
}
}
float updateIntensity(int LDR, char* lightAr) {
int analogValue = analogRead(LDR);
float voltage = analogValue / 1024. * 5;
float resistance = 2000 * voltage / (1 - voltage / 5);
float maxlux = pow(RL10 * 1e3 * pow(10, GAMMA) / 322.58, (1 / GAMMA));
float lux = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA))/maxlux;
String(lux).toCharArray(lightAr,6);
return lux;
}
void monitorIntensity(){
float lux_1 = updateIntensity(LDR_L, lightAr_L);
float lux_2 = updateIntensity(LDR_R, lightAr_R);
Serial.print(tempAr);
Serial.print(" ");
Serial.print(lux_1);
Serial.print(" ");
Serial.println(lux_2);
if(lux_1>lux_2){
// mqttClient.publish("ENTC-LIGHT-MAX", lightAr_L);
// mqttClient.publish("ENTC-LIGHT-MIN", lightAr_R);
// mqttClient.publish("LDR-DIRECTION", "Left");
servoMotor(lux_1, 1.5);
}else{
// mqttClient.publish("ENTC-LIGHT-MAX", lightAr_R);
// mqttClient.publish("ENTC-LIGHT-MIN", lightAr_L);
// mqttClient.publish("LDR-DIRECTION", "Right");
servoMotor(lux_2, 0.5);
}
}
void servoMotor(float lux, float D){
Serial.print(MIN_ANGLE);
Serial.print(" ");
Serial.println(GAMMA);
pos = MIN_ANGLE*D + (180 - MIN_ANGLE) * lux * GAMMA;
servo.write(pos);
}