// https://console.hivemq.cloud/clusters/free/8fcfc29c35f04789a706f34250c4fc85
// https://console.hivemq.cloud/clusters/free/8fcfc29c35f04789a706f34250c4fc85/web-client
#define CRE_NAME F("Pham Duy Anh - 0908984010")
#define PRJ_NAME F("Wokwi.com ESP32 + MQTT")
#define UPDATED F("2023/11/01")
// define param for Serial Communicate
#define BAUDRATE 115200
#define TIMEOUT 20 //ms
// define PIN IO
#define PIN_LED 2
#define PIN_LEDG 12
#define PIN_LEDB 13
#define PIN_LEDR 15
// config Wifi info
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <TridentTD_LineNotify.h>
#define LINE_TOKEN "0O2ZfTMndxLjSKWmARDVGVn4jqA6h3vxrtXK8EkAXiv"
//WiFiClient espClient;
WiFiClientSecure espClient;
const char *ssid = "Wokwi-GUEST";
const char *pass = "";
// config MQTT info
#include <PubSubClient.h> // https://github.com/knolleary/pubsubclient/tree/master
PubSubClient client(espClient);
const int mqtt_port = 8883;
const char* mqtt_server = "4aa88cac749840338ce7cfdc85285e2d.s1.eu.hivemq.cloud"; // replace with your HiveMQ Cluster URL
const char* mqtt_username = "folkk"; // replace with your Username
const char* mqtt_password = "123456789folK"; // replace with your Password
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE (500)
char msg[MSG_BUFFER_SIZE];
int value = 0;
// HiveMQ Cloud Let's Encrypt CA certificate
static const char *root_ca PROGMEM = R"EOF(
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
-----END CERTIFICATE-----
)EOF";
// config TimeZone
//#include <TZ.h>
//#include "time.h"
#include <DHT.h>
#define PIN_DHT 5
#define DHTTYPE DHT22
DHT dht(PIN_DHT, DHTTYPE);
void setup() {
initSerial();
pinMode(PIN_LED, OUTPUT);
initMQTT();
initWifi();
//initTime("WET0WEST,M3.5.0/1,M10.5.0");
LINE.setToken(LINE_TOKEN);
// Send a test message
LINE.notify("Hello from ESP32 on Wokwi!");
LINE.notify("แจ้งเตือนอุปกรณ์เชื่อมต่อแล้ว");
}
unsigned long _t;
float t, h;
struct dhtSensor{
float temp;
float humi;
};
dhtSensor sensor;
void loop() {
LEDStatusFlashes(PIN_LED, 2, 2000, 1);
if (!client.connected()) { reconnect(); }
client.loop();
//publishMessage(sensor2_topic,String(XXXX),true);
unsigned long now = millis();
if (now - lastMsg > 2000) {
lastMsg = now;
++value;
snprintf (msg, MSG_BUFFER_SIZE, "Hello World! #%ld", value);
Serial.print("Publish message: ");
Serial.println(msg);
client.publish("testTopic", msg);
// char msg[50];
snprintf (msg, sizeof(msg), "%f", sensor.temp);//sensor.temp
client.publish("testTopic/temp", msg);
snprintf (msg, sizeof(msg), "%f", sensor.humi);//sensor.humi
client.publish("testTopic/humi", msg);
if ( sensor.temp > 40.0) {
LINE.notify ("Temperature exceeds 40 °C! Sending alert...");
}
}
if (millis() - _t > 2000){
_t = millis();
readDHT();
Serial.print("Temperature: ");
Serial.print(sensor.temp, 1);
//Serial.print((char)223);
Serial.print("°C \n");
Serial.print("Humidity: ");
Serial.print(sensor.humi, 1);
Serial.print("% \n");
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void readDHT(){
// t = dht.readTemperature();
// h = dht.readHumidity();
sensor.temp = dht.readTemperature();
sensor.humi = dht.readHumidity();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void initMQTT(){
espClient.setCACert(root_ca);
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
}
void reconnect() {
// Loop until we’re reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection…");
String clientId = "Wokwi.com ESP32";
// Attempt to connect
// Insert your password
if (client.connect(clientId.c_str(), mqtt_username, mqtt_password)) {
Serial.println("connected");
// Once connected, publish an announcement…
client.publish("testTopic", "hello world");
// … and resubscribe
client.subscribe("testTopic");
client.subscribe("iot/temp");
client.subscribe("iot/humi");
} else {
Serial.print("failed, rc = ");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void publishMessage(const char* topic, String payload , boolean retained){
//if (client.publish(topic, payload.c_str(), true))
//Serial.println(“Message publised [”+String(topic)+"]: "+payload);
}
// void initTime(String timezone){
// struct tm timeinfo;
// Serial.println("Setting up time");
// configTime(0, 0, "pool.ntp.org"); // First connect to NTP server, with 0 TZ offset
// if(!getLocalTime(&timeinfo)){
// Serial.println(" Failed to obtain time");
// return;
// }
// Serial.println(" Got the time from NTP");
// // Now we can set the real timezone
// Serial.printf(" Setting Timezone to %s\n",timezone.c_str());
// setenv("TZ",timezone.c_str(),1); // Now adjust the TZ. Clock settings are adjusted to show the new local time
// tzset();
// }
////////////////////////////////////////////////////////////////////////////////////////////////////
void initWifi() {
WiFi.mode(WIFI_STA); // WIFI_STA, WIFI_AP, WIFI_AP_STA
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.print("\n");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void initSerial() {
Serial.begin(BAUDRATE);
while (!Serial)
;
Serial.setTimeout(TIMEOUT);
Serial.println("\n\nCreated by " + String(CRE_NAME));
Serial.println(" Project " + String(PRJ_NAME) + ", edited on " + String(UPDATED));
char dateStr[10];
dateReFormat(__DATE__, dateStr);
Serial.println(" Compiled on: " + String(__TIME__) + " - " + String(dateStr) + "\n");
Serial.print(String(millis()) + "ms - ");
Serial.println("Initial Serial!");
}
void dateReFormat(char const *date, char *buff) {
int month, day, year;
static const char month_names[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
sscanf(date, "%s %d %d", buff, &day, &year);
month = (strstr(month_names, buff) - month_names) / 3 + 1;
//sprintf(buff, "%d%02d%02d", year, month, day);
sprintf(buff, "%d/%02d/%02d", year, month, day);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
#define timeLED 10
#define timeCycle 200
void LEDStatusFlashes(byte pin, byte timeBlink, unsigned int intervalLEDStatus, byte state) {
static unsigned long timeLEDStatus;
static byte timeBlinked;
static bool ledStatus;
pinMode(pin, OUTPUT);
if (millis() - timeLEDStatus > intervalLEDStatus) {
ledStatus = true;
timeBlinked = 1;
timeLEDStatus = millis();
}
//long checkTime = millis() - (timeLEDStatus + (unsigned long)timeBlinked * timeLED * 20);
long checkTime = millis() - (timeLEDStatus + (unsigned long)timeBlinked * timeCycle);
if (ledStatus && (checkTime > 0)) {
timeBlinked++;
if (timeBlinked > timeBlink) {
timeBlinked = 0;
ledStatus = false;
}
digitalWrite(pin, state);
delay(timeLED);
digitalWrite(pin, !state);
} else {
digitalWrite(pin, !state);
}
}