#include <LiquidCrystal_I2C.h>
#include "DHTesp.h"
#include <WiFi.h>
#include <HTTPClient.h>
#include <PubSubClient.h>
#include <thread>
#define LED_PIN 32
#define DHT_PIN 15
LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 16 chars and 2 line display
DHTesp dhtSensor;
String serverName = "http://8962-1-55-245-5.ngrok-free.app";
String contentJson = "application/json";
const char* mqttServer = "broker.hivemq.com";
int port = 1883;
const char* client_id = "SmartGarden-unique-192837465";
const char* led_channel = "hust-iot-lightbulbs-super-unique-2001-vietnam";
String accessTokenSoilSensor = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkZXZpY2VfaWQiOjE0fQ.zZh0WRGRuvIwUQYeygbVZRm9YHxevHGjkZdskCQcHzk";
String accessTokenTemperature = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkZXZpY2VfaWQiOjE1fQ.0T-u-Qg7b48iRNV6dTE1LCVX7Lz8sWATfg7f4u-EgYU";
String accessTokenHumidity = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkZXZpY2VfaWQiOjE2fQ.A9qMvhAcFGnX1-r7-Cny9mj7mq_aaEDcMq7l6RsAOGY";
WiFiClient espClient;
PubSubClient client(espClient);
HTTPClient http;
void mqttReconnect() {
int i = 5;
while(!client.connected()) {
lcd.setCursor(i, 1);
lcd.print(".");
i++;
if(client.connect(client_id)) {
lcd.clear();
Serial.println("MQTT Connected!");
client.subscribe(led_channel);
}
else {
lcd.clear();
Serial.println("try again in 5 seconds");
delay(5000);
}
delay(500);
}
}
void manualControl() {
while (true) {
client.loop();
delay(500);
}
}
void setup() {
//setup for serial communication
Serial.begin(115200);
delay(1000);
Serial.println("ESP32 collecting sensors data");
//config LED_PIN output
pinMode(LED_PIN, OUTPUT);
//setup for dht sensor
dhtSensor.setup(DHT_PIN, DHTesp::DHT22);
lcd.init(); // initialize the lcd
// Print a message to the LCD.
lcd.backlight();
lcd.setCursor(1,0);
lcd.println("ESP32 collecting data ...");
//setup for WiFi connection
Serial.println("Connecting to WiFi");
WiFi.begin("Wokwi-GUEST", "", 6);
const int MAX_ATTEMPT = 10;
int attempt = 0;
while (WiFi.status() != WL_CONNECTED && attempt < MAX_ATTEMPT) {
attempt++;
delay(500);
Serial.print(".");
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("WiFi Connected!");
} else {
Serial.println("WiFi Error!");
}
// connect mqtt
client.setServer(mqttServer, port);
client.setCallback(callback);
std::thread manualControlThread(manualControl);
manualControlThread.detach();
delay(1000);
}
//MQTT Receiver
void callback(char* topic, byte* message, unsigned int length) {
String strMsg;
for(int i=0; i<length; i++) {
strMsg += (char)message[i];
}
Serial.println("Queue message: " + String(strMsg));
if (String(topic) == String(led_channel)){
if (strMsg == "1"){
digitalWrite(LED_PIN, HIGH);
}
else if (strMsg == "0"){
digitalWrite(LED_PIN, LOW);
}
}
}
void loop() {
// reconnect mqtt
if(!client.connected()) {
mqttReconnect();
}
client.loop();
TempAndHumidity data = dhtSensor.getTempAndHumidity();
float temp = data.temperature;
float humid = data.humidity;
String stemp = String(temp);
String shumid = String(humid);
int16_t soil_moisture = analogRead(34);
String ssoil_moisture = String(soil_moisture);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Temp: " + stemp + "%");
lcd.setCursor(0,1);
lcd.print("Humidity: " + shumid + "C");
lcd.setCursor(0,2);
lcd.print("Soil moisture: " + ssoil_moisture + "%");
if (WiFi.status() == WL_CONNECTED) {
sendRequest(serverName, accessTokenSoilSensor, ssoil_moisture);
sendRequest(serverName, accessTokenTemperature, stemp);
sendRequest(serverName, accessTokenHumidity, shumid);
http.end();
}
delay(10000);
}
void sendRequest(String serverName, String accessToken, String data) {
String serverPath = serverName + "/devices/pings";
http.begin(serverPath.c_str());
http.addHeader("Content-Type", contentJson);
String pingRequest = "{\"access_token\": \"" + accessToken + "\"}";
int pingResponse = http.POST(pingRequest);
Serial.println("Ping response: " + String(pingResponse));
http.end();
if (pingResponse == 200) {
serverPath = serverName + "/measure-data/";
http.begin(serverPath.c_str());
String httpRequestData = "{\"access_token\": \"" + accessToken + "\",\"value\": \"" + data + "\"}";
int responseCode = http.POST(httpRequestData);
Serial.println("Send data response: " + String(responseCode));
http.end();
}
}