#include <WiFi.h>
#include <PubSubClient.h>
#include <ESP32Servo.h>
#include <LiquidCrystal_I2C.h>
#include <DHTesp.h>
const char* ssid = "Wokwi-GUEST";
const char* password = "";
//***Set server***
const char* mqttServer = "broker.mqtt-dashboard.com";
int port = 1883;
const float GAMMA = 0.7;
const float RL10 = 50;
//pins
LiquidCrystal_I2C LCD = LiquidCrystal_I2C(0x27, 16, 2);
const int redLedPin = 2;
const int greenLedPin = 4;
const int servoPin = 18;
const int DHT_pin = 15;
const int photoresistor_pin = 32;
const char* client_id = "SmartGarden";
const char* led_channel = "SmartGarden/led";
const char* servo_channel = "SmartGarden/servo";
const char* temperature_channel = "SmartGarden/temperature";
const char* light_channel = "SmartGarden/light";
const char* humidity_channel = "SmartGarden/humidity";
//components
Servo myServo;
DHTesp dhtSensor;
WiFiClient espClient;
PubSubClient client(espClient);
void wifiConnect() {
WiFi.begin(ssid, password);
int i = 5;
while (WiFi.status() != WL_CONNECTED) {
delay(500);
LCD.setCursor(i, 0);
LCD.print(".");
i++;
}
//LCD.clear();
LCD.setCursor(5, 0);
LCD.println(" Connected!");
delay(2000);
//LCD.clear();
}
void mqttReconnect() {
int i = 5;
while(!client.connected()) {
LCD.setCursor(i, 1);
LCD.print(".");
i++;
//***Change "123456789" by your student id***
if(client.connect(client_id)) {
//LCD.clear();
LCD.setCursor(5, 1);
LCD.println(" Connected!");
LCD.clear();
//***Subscribe all topic you need***
client.subscribe(servo_channel);
client.subscribe(led_channel);
}
else {
LCD.clear();
Serial.println("try again in 5 seconds");
delay(5000);
}
delay(500);
}
}
//this will be ran first for setting up esp32 and connecting to server
void setup() {
Serial.begin(115200);
pinMode(redLedPin, OUTPUT);
pinMode(greenLedPin, OUTPUT);
pinMode(photoresistor_pin, INPUT);
myServo.attach(servoPin);
dhtSensor.setup(DHT_pin, DHTesp::DHT22);
LCD.init();
LCD.setCursor(2, 0);
LCD.print("SMART GARDEN");
delay(5000);
LCD.clear();
//LCD.print("Connecting to ");
LCD.setCursor(0, 0);
LCD.print("WIFI: ");
LCD.setCursor(0, 1);
LCD.print("MQTT: ");
wifiConnect();
client.setServer(mqttServer, port);
client.setCallback(callback);
}
//MQTT Receiver
void callback(char* topic, byte* message, unsigned int length) {
Serial.println(topic);
String strMsg;
for(int i=0; i<length; i++) {
strMsg += (char)message[i];
}
Serial.println(strMsg);
if (String(topic) == String(servo_channel)) {
if (strMsg == "SERVO_ON"){
Serial.println("servo");
for (int pos = 0; pos <= 180; pos += 1) {
myServo.write(pos);
delay(15);
}
}
}
if (String(topic) == String(led_channel)){
if (strMsg == "LIGHT_ON"){
digitalWrite(greenLedPin, HIGH);
digitalWrite(redLedPin, LOW);
}
else if (strMsg == "LIGHT_OFF"){
digitalWrite(redLedPin, HIGH);
digitalWrite(greenLedPin, LOW);
}
}
//***Insert code here to control other devices***
}
void stringToChar(char* &result, String str){
result = new char[str.length() + 1];
int i;
for (i = 0; i < str.length(); i++){
result[i] = str[i];
}
result[i] = '\0';
}
void loop() {
if(!client.connected()) {
mqttReconnect();
}
client.loop();
//***Change code to publish to MQTT Server***
TempAndHumidity data = dhtSensor.getTempAndHumidity();
String temperatureS = String(data.temperature, 2);
String humidityS = String(data.humidity, 1);
String photoresistor_valueS = String(analogRead(photoresistor_pin));
int analogValue = analogRead(photoresistor_pin) / 4;
float voltage = analogValue / 1024.0 * 5;
float resistance = 2000 * voltage / (1 - voltage / 5);
float lux = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA));
Serial.println(lux);
float temperatureF = temperatureS.toFloat();
float humidityF = humidityS.toFloat();
char* temperature = new char [temperatureS.length() + 1];
char* humidity = new char [temperatureS.length() + 1];
char* photoresistor_value = new char [photoresistor_valueS.length() + 1];
LCD.setCursor(0, 0);
LCD.println("Temp: " + temperatureS + "C");
LCD.setCursor(0, 1);
LCD.println("Humidity: " + humidityS + "%");
stringToChar(temperature, temperatureS);
stringToChar(humidity, humidityS);
stringToChar(photoresistor_value, photoresistor_valueS);
client.publish(temperature_channel, temperature);
client.publish(humidity_channel, humidity);
client.publish(light_channel, photoresistor_value);
delete [] temperature;
delete [] humidity;
delete [] photoresistor_value
;
delay(2000);
}