#include <WiFi.h>
#include <WiFiClient.h>
#include <PubSubClient.h>
#include <ESP32Servo.h>
#include <uRTCLib.h>
const int servoPin = 18;
#define Ldrpin 35
int LED_R = 23;
Servo myServo; // Creates a servo object for controlling the servo motor
int angle = 0;
const char *WIFI_SSID = "Wokwi-GUEST";
const char *WIFI_PWD = "";
const char *MQTT_SERVER = "broker.hivemq.com"; // MQTT server name
const uint16_t MQTT_PORT = 1883; // MQTT port number to use
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
// ---------------------------
// ---------------------------
const char *topicPubSensor = "IOT/PA31/s10206236";
const char *topicPubDist = "IOT/PA31/dist";
const char *topicPubTemp = "IOT/PA31/temp";
const char *topicPubHumi = "IOT/PA31/humi";
const char *topicPubDate = "IOT/PA31/date";
const char *topicPubLux = "IOT/PA31/lux";
// defines variables
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
uRTCLib rtc(0x68);
long duration;
int distance;
//**************
void SetupRtc()
{
URTCLIB_WIRE.begin();
}
void ConnectToWiFi()
{
Serial.print("Connecting to WiFi ");
Serial.println(WIFI_SSID);
WiFi.begin(WIFI_SSID, WIFI_PWD, 6);
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
delay(500);
}
Serial.print("\nConnected to ");
Serial.println(WIFI_SSID);
}
//--------------------------------------------------------
void SetupMqtt()
{
mqttClient.setServer(MQTT_SERVER, MQTT_PORT);
// set the callback function
mqttClient.setCallback(callback);
}
void ConnectToMqtt()
{
Serial.println("Connecting to MQTT Broker...");
while (!mqttClient.connected())
{
char clientId[100] = "\0";
sprintf(clientId, "ESP32Client-%04X", random(0xffff));
Serial.println(clientId);
if (mqttClient.connect(clientId))
{
Serial.println("Connected to MQTT broker.");
// subscribe to topics
MQTTSubscribe();
}
}
}
void callback(String topic, byte* payload, unsigned int length)
{
String messageTemp;
Serial.print("\nMessage received in topic: ");
Serial.print(topic);
Serial.print(" length is: ");
Serial.println(length);
Serial.print("Data received from broker: ");
for (int i = 0; i < length; i++)
{
Serial.print( (char)payload[i] );
messageTemp += (char)payload[i];
}
//The whole code above is just to print all the message recieved (payload)
int value = messageTemp.toInt();
if ( topic == topicPubDate)
{
if (messageTemp == "00:00")
{
for(angle = 0; angle <= 180; angle+=180)
{
myServo.write(angle); // tells servo to go to position in variable 'angle'
delay(10000);
}
// rotates the servo motor from 180 to 0 degrees
for(angle = 180; angle >= 0; angle-=180)
{
myServo.write(angle); // tells servo to go to position in variable 'angle'
delay(10000);
}
}
else if (messageTemp == "08:00")
{
for(angle = 0; angle <= 180; angle+=180)
{
myServo.write(angle); // tells servo to go to position in variable 'angle'
delay(10000);
}
// rotates the servo motor from 180 to 0 degrees
for(angle = 180; angle >= 0; angle-=180)
{
myServo.write(angle); // tells servo to go to position in variable 'angle'
delay(10000);
}
}
else if (messageTemp == "16:00")
{
for(angle = 0; angle <= 180; angle+=180)
{
myServo.write(angle); // tells servo to go to position in variable 'angle'
delay(10000);
}
// rotates the servo motor from 180 to 0 degrees
for(angle = 180; angle >= 0; angle-=180)
{
myServo.write(angle); // tells servo to go to position in variable 'angle'
delay(10000);
}
}
}
else if (topic == topicPubTemp) {
if (value > 30) {
// rotates the servo motor from 0 to 180 degrees
for(angle = 0; angle <= 180; angle+=15)
{
myServo.write(angle); // tells servo to go to position in variable 'angle'
delay(100);
}
// rotates the servo motor from 180 to 0 degrees
for(angle = 180; angle >= 0; angle-=15)
{
myServo.write(angle); // tells servo to go to position in variable 'angle'
delay(100);
}
}
}
else if (topic == topicPubLux) {
if (value < 50) {
digitalWrite(LED_R, LOW);
}
else {
digitalWrite(LED_R, HIGH);
}
}
else {
Serial.printf("\nReceived topic \"%s\" + payload \"%s\" not processed",
topic.c_str(), messageTemp.c_str());
}
}
void MQTTSubscribe()
{
Serial.printf("\n--- Subscribe to topics:");
Serial.printf("\n%s", topicPubSensor);
mqttClient.subscribe(topicPubSensor);
Serial.printf("\n%s", topicPubDist);
mqttClient.subscribe(topicPubDist);
Serial.printf("\n%s", topicPubTemp);
mqttClient.subscribe(topicPubTemp);
Serial.printf("\n%s", topicPubHumi);
mqttClient.subscribe(topicPubHumi);
Serial.printf("\n%s", topicPubDate);
mqttClient.subscribe(topicPubDate);
Serial.printf("\n%s", topicPubLux);
mqttClient.subscribe(topicPubLux);
}
//--------------------------------------------------------
// Publish a topic with its payload
bool publishTopic(const char* topic, const char *str) {
Serial.printf("\nPublishing topic \"%s\" + payload \"%s\"", topic, str);
if (mqttClient.publish(topic, str)) {
Serial.print(" -- Done");
return true;
}
else {
Serial.print("\nPublishing encounter error");
return false;
}
}
//--------------------------------------------------------
// ---------------------------
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
pinMode(LED_R,OUTPUT);
myServo.attach(18); // Defines the attached pin of servo motor
SetupRtc();
ConnectToWiFi();
SetupMqtt();
ConnectToMqtt(); // This line establishes the MQTT connection
}
const size_t BUFFER_SIZE = 100;
const char *BUFFER_FORMAT = "%1.3f";
char buffer[BUFFER_SIZE + 1];
const float GAMMA = 0.7;
const float RL10 = 50;
void loop() {
// put your main code here, to run repeatedly:
delay(10); // this speeds up the simulation
if (!mqttClient.connected())
{
ConnectToMqtt();
}
mqttClient.loop();
{
rtc.refresh();
snprintf(buffer, BUFFER_SIZE, "%02d:%02d",rtc.hour(), rtc.minute());
mqttClient.publish("IOT/PA31/date", buffer);
Serial.print("\nCurrent Hour in 24 hour format: ");
Serial.println(buffer);
int ldrValue = analogRead(Ldrpin);
float voltage = ldrValue / 4095. * 5;
float resistance = 2000.0 * voltage / (1 - voltage / 5);
float lux = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1.0 / GAMMA));
char luxStr[20];
dtostrf(lux, 6, 3, luxStr); // Format: %6.3f (6 characters wide, 3 decimal places)
Serial.println(luxStr); // Print the lux value to Serial Monitor
mqttClient.publish("IOT/PA31/lux", luxStr); // Publish the lux value
} //make sure connection is not broken, auto restart the connection
delay(1000);
}