#define led_pin 5
#define ldr_pin 33
//#define dht22_pin 13
#include <DHTesp.h>
#include <LiquidCrystal_I2C.h>
#include <WiFi.h>
#include "PubSubClient.h"
//sensor pin
//lcd
const int lcdColumns = 16;
const int lcdRows = 2;
LiquidCrystal_I2C lcd(0x27, lcdColumns, lcdRows);
//light sensor
const float GAMMA = 0.5;
const float RL10 = 5;
//dht22
const int DHT_PIN = 15;
DHTesp dht;
//wifi & mqtt
const char* wifi_ssid = "Wokwi-GUEST";
const char* wifi_password = "";
const char* mqtt_server = "test.mosquitto.org";
WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
String led_status = "";
String control_mode = "";
void setup() {
Serial.begin(115200);
pinMode(led_pin, OUTPUT);
control_mode = "auto";
led_status = "off";
setupLCD();
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
dht.setup(DHT_PIN, DHTesp::DHT22);
}
void setupLCD() {
lcd.init();
lcd.backlight();
lcd.setCursor(2, 0);
lcd.print("WELCOME...To");
lcd.setCursor(3, 1);
lcd.print("2669600823");
delay(1000);
}
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(wifi_ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(wifi_ssid, wifi_password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
randomSeed(micros());
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
delay(2000); // Delay to stabilize after WiFi connection
}
void callback(char* topic, byte* message, unsigned int length) {
Serial.print("Message arrived on topic: ");
Serial.print(topic);
Serial.print(". Message: ");
String stMessage;
for (int i = 0; i < length; i++) {
Serial.print((char)message[i]);
stMessage += (char)message[i];
}
Serial.println();
if (String(topic) == "boonsong/control") {
if (control_mode == "manual") {
lcd.clear();
if (stMessage == "on" || stMessage == "true") {
Serial.println("led on.");
led_status = "on";
lcd.print("Light:On");
led_status = "on";
digitalWrite(led_pin, HIGH);
lcd.setCursor(0, 0);
lcd.print("Mode:Manual");
lcd.setCursor(0, 1);
lcd.print("Light:On");
}
else if (stMessage == "off" || stMessage == "false") {
Serial.println("led off.");
lcd.print("Light:Off");
led_status = "off";
digitalWrite(led_pin, LOW);
lcd.setCursor(0, 0);
lcd.print("Mode:Manual");
lcd.setCursor(0, 1);
lcd.print("Light:Off");
}
} else {
Serial.println("command led " + String(stMessage) + "not work in manual mode.");
}
} else if (String(topic) == "boonsong/control/mode") {
if (stMessage == "true") {
control_mode = "auto";
Serial.println("Switch to auto mode");
}
else if (stMessage == "false") {
control_mode = "manual";
Serial.println("Switch to manual mode");
}
}
}
void mqtt_reconnect() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
String clientId = "ESP32Client-";
clientId += String(random(0xffff), HEX);
if (client.connect(clientId.c_str())) {
Serial.println("Connected");
//client.publish("/indobot/p/mqtt", "Indobot");
//client.subscribe("/indobot/p/mqtt");
client.subscribe("boonsong/control");
client.subscribe("boonsong/control/mode");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
void loop() {
if (!client.connected()) {
mqtt_reconnect();
}
client.loop();
unsigned long now = millis();
if (now - lastMsg > 1000) { //perintah publish data
lastMsg = now;
int ldr_sensor_value = analogRead(ldr_pin);
//Serial.println(ldr_sensor_value);
//int brightness = map(ldr_sensor_value, 0, 4095, 0, 255);
float voltage = ldr_sensor_value / 4095. * 5;
float resistance = 10000 * voltage / (5 - voltage);
float lux = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA));
// Serial.print("Analog Value = ");
// Serial.println(ldr_sensor_value);
// Serial.print("Voltage = ");
// Serial.println(voltage);
// Serial.print("Resistance = ");
// Serial.println(resistance);
TempAndHumidity dht_data = dht.getTempAndHumidity();
String temp = String(dht_data.temperature, 2);
String hum = String(dht_data.humidity, 1);
if (control_mode == "auto") {
lcd.clear();
if (lux > 40) {
lcd.setCursor(0, 0);
lcd.print("LUX:");
lcd.setCursor(4, 0);
lcd.print(lux);
lcd.setCursor(0, 1);
lcd.print("Light:Off");
led_status = "off";
//Serial.println(" => Bright \n");
digitalWrite(led_pin, LOW);
} else { // lux < 40 = Dark
lcd.setCursor(0, 0);
lcd.print("LUX:");
lcd.setCursor(4, 0);
lcd.print(lux);
lcd.setCursor(0, 1);
lcd.print("Light:On");
led_status = "on";
//Serial.println(" => Dark \n");
digitalWrite(led_pin, HIGH);
}
}
// client.publish("boonsong/control/lux", lux);
// client.publish("boonsong/control/temp", temp.c_str());
// client.publish("boonsong/control/hum", hum.c_str());
// Construct JSON string
String payload = "{";
payload += "\"lux\":" + String(lux) + ",";
payload += "\"temp\":" + temp + ",";
payload += "\"hum\":" + hum + ",";
payload += "\"led\":\"" + led_status + "\",";
payload += "\"mode\":\"" + control_mode + "\"";
payload += "}";
client.publish("boonsong/control/data", payload.c_str());
Serial.print("lux = " + String(lux));
Serial.print(" temp = " + String(temp));
Serial.println(" hum = " + String(hum));
}
//lcd.clear();
delay(1000);
}