//#define PIR_PIN 12 //D12
//#define RELAY_Green_PIN 14 //D14
//const long Period_Green_Light = 10000; //Wait 10 Seconds
//unsigned long Step_Time_GreenLED = 0; //Stop Time Loop
//ESP32 Board
//void setup() {
//Serial.begin(9600);
//Serial.println("Get Started!!!");
//pinMode(PIR_PIN, INPUT);
//pinMode(RELAY_Green_PIN, OUTPUT);
}
// loop() Function
//void loop() {
//int PIR_Value = digitalRead(PIR_PIN);
//Serial.print("PIR Motion Sensor Status : ");
//Serial.println(PIR_Value);
//int LED_Value = digitalRead(RELAY_Green_PIN);
//Serial.print("Green LED Status : ");
//Serial.println(LED_Value);
//if(PIR_Value == 1) {
//if(millis() - Step_Time_GreenLED <= Period_Green_Light) {
//Step_Time_GreenLED = millis();
//String text_001 = "Motion is Detected!";
//Serial.println(text_001);
//digitalWrite(RELAY_Green_PIN, HIGH);
//}
//}
//if(PIR_Value == 0) {
//digitalWrite(RELAY_Green_PIN, LOW);
//}
//}
#include <PubSubClient.h> //*Library สำหรับการติดต่อ MQTT
#include <WiFi.h> //*Library สำหรับการตืดต่อ WiFi
#define PIR_PIN 12 // GPIO-12 to PIR Sensor
#define RELAY_LEDs_PIN 14 // GPIO-14 to LED
//***การกำหนดค่าหัวข้อสำหรับการส่งต่อข้อมูลไปให้ MQTT
//โนดสามารถส่งข้อมูลออกกับบัพข้อมูลเข้าผ่าน Topic ที่เราตั้งใช้งาน
//Topic subscribe รอรับข้อมูล รับค่าจาก nodered มาส่งผ่านใน board
//Topic publish ส่งออกข้อมูล ส่งค่า sensor ไปที่ nodered
//ควรเขียนส่วนบนช่วงต้น ๆ เพราะ มันมาค่าแก้ข้อมูลได้ง่ายกว่า
//ควรเลือก Topic ให้สอดคล้องกับการส่งข้อมูลของซอฟแวร์สัมพันธ์กับเซริฟเวอร์ จะรับ-ส่งข้อมูลกี่ค่า
#define TOPIC_SUBSCRIBE_LED "topic_on_off_led"
#define TOPIC_PUBLISH_MOTION "topic_sensor_motion"
#define PUBLISH_DELAY 2000 // Delay time for publish data to MQTT Broker
//ไม่ควรใช้คำสั่ง delay เพราะมันจะทำให้โค้ดใหญ่ ๆ เสียหาย
//แต่ควรใช้คำสั่ง millis()
//ทุก ๆ 2000 ms มันก็จะส่งค่าของ sensor ไปที่ตัว Broker //แล้วแต่เราว่าจะเอาทุก ๆ เท่าไรก็ได้
//ส่งค่า publish ของ sensor ไปที่ Broker
#define ID_MQTT "esp32_mqtt" // Device ID for connect to MQTT Broker //ใช้ define ไม่ได้ แต่เราจะเทสเป็น define ไปก่อน
//***เวลาเราติดต่อ เนื่องจากเรามี node หลาย ๆ ตัว แล้วก็ส่งเข้าไปที่ server ที่สำคัญก็คือ มันจะรู้ได้ไงว่ามันเป็นของตัวไหน เพราะฉะนั้นสิ่งที่จะบ่งบอกได้ก็คือ ID ของมัน
//ต้องดึง mac-address ของตัว node มาเป็น ID ของ node เรา เพราะถ้ามันซ้ำกัน server มันจะไม่รู้ใครส่งมากันแน่
PIResp pir; //ประกาศตัวแปรเป็น object ของ sensor
//
const char *SSID = ""; //"Wokwi_GUEST" เอาไว้สำหรับจำลองใน wokwi ให้มันเชื่อมต่อ wifi ได้ เพราะมันเป็น private ID ของเขาในการจำลองให้เชื่อม WiFi // SSID / nome da rede WI-FI que deseja se conectar
//ชื่อ wifi ปกติมันจะประกาศเป็นพอยเตอร์
//ใส่ชื่อ WiFi ที่จะเชื่อมต่อ
const char *PASSWORD = ""; // Senha da rede WI-FI que deseja se conectar
//ใส่รหัสผ่าน WiFi ของตัวที่เชื่อมต่อไป
// URL for MQTT broker
const char *BROKER_MQTT = "broker.hivemq.com";
int BROKER_PORT = 1883; // Port of Broker MQTT //พอร์ตมาตรฐานของมันคือ 1883
//เป็นการกำหนด broker หรือ mqtt beoker หรือ server broker ของเรา เป็น IP อะไร
//ตรงนี้ควรเทสกับ hivemq เพื่อทดสอบก่อนได้
unsigned long publishUpdate;
static char strMotion[10] = {0}; //ค่าข้องในเป็น 10 ตัวอักษร เป็น char และ array แต่ตอนนี้ไม่มีอะไร แค่ประกาศไว้ก่อน
//การประกาศตัวแปรสตริง
//มีข้อสำคัญอยู่ที่ เราได้ค่าข้อมูลที่เราเก็บมาเป็นข้อมูลสตริง แต่เราเอาสตริงส่งไปที่ mqtt ไม่ได้ มันต้องเป็นตัวแปรตัวอักษร หรือเป็นอาเรย์ของตัวอักษร ไม่ใช่สตริง
//ข้อมูลอะไรที่เราจะส่งไป Broker ต้องประกาศเอาไว้เสมอ
//เป็นมาตรฐานที่ต้องใช้
// Variable for Wifi Client Object
WiFiClient espClient;
PubSubClient MQTT(espClient); //เริ่มจะต่อกับ mqtt
//ประกาศชื่่อฟังก์ชัน
/* Prototypes */
//float getTemperature(void);
float getMotions(void);
void initWiFi(void);
void initMQTT(void);
void callbackMQTT(char *topic, byte *payload, unsigned int length);
void reconnectMQTT(void);
void reconnectWiFi(void);
void checkWiFIAndMQTT(void);
/* Function for get Temperature */
float getTemperature(void)
{
TempAndHumidity data = dht.getTempAndHumidity();
if (!(isnan(data.temperature)))
return data.temperature;
else
return -99.99;
}
/* Function for get Humidity */
float getHumidity(void)
{
TempAndHumidity data = dht.getTempAndHumidity();
if (!(isnan(data.humidity)))
return data.humidity;
else
return -99.99;
}
/* Initial WI-FI */
void initWiFi(void)
{
delay(10);
Serial.println("------Connect to WI-FI------");
Serial.print("Connecting to : ");
Serial.println(SSID);
reconnectWiFi();
}
/* Initial MQTT */
void initMQTT(void)
{
MQTT.setServer(BROKER_MQTT, BROKER_PORT);
MQTT.setCallback(callbackMQTT);
}
/* Function Callback: Receive Message from another MQTT Client publish message pass through the MQTT Broker */
void callbackMQTT(char *topic, byte *payload, unsigned int length)
{
String msg;
// Obtem a string do payload recebido
for (int i = 0; i < length; i++) {
char c = (char)payload[i];
msg += c;
}
Serial.printf("Receive string via MQTT: %s on topico: %s\n", msg, topic);
/* Toma ação dependendo da string recebida */
if (msg.equals("1")) {
digitalWrite(PIN_LED, HIGH);
Serial.println("LED status ON");
}
if (msg.equals("0")) {
digitalWrite(PIN_LED, LOW);
Serial.println("LED status OFF");
}
}
/* FUnction reconnect MQTT Broker */
void reconnectMQTT(void)
{
while (!MQTT.connected()) {
Serial.print("* Connecting MQTT Broker: ");
Serial.println(BROKER_MQTT);
if (MQTT.connect(ID_MQTT)) {
Serial.println("Connecting the MQTT Broker success!");
MQTT.subscribe(TOPIC_SUBSCRIBE_LED);
} else {
Serial.println("Fail to connect then reconnect MQTT Broker again in 2 seconds.");
delay(2000);
}
}
}
/* Function checking connected to WiFI and MQTT Broker */
void checkWiFIAndMQTT(void)
{
if (!MQTT.connected())
reconnectMQTT();
reconnectWiFi();
}
void reconnectWiFi(void)
{
if (WiFi.status() == WL_CONNECTED)
return;
WiFi.begin(SSID, PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
}
Serial.println();
Serial.print("Connected WiFi success. ");
Serial.print(SSID);
Serial.println("IP Address: ");
Serial.println(WiFi.localIP());
}
void setup()
{
Serial.begin(115200);
pinMode(PIN_LED, OUTPUT);
digitalWrite(PIN_LED, LOW);
// Setup DHT sensor
dht.setup(PIN_DHT, DHTesp::DHT22);
initWiFi();
initMQTT();
}
void loop()
{
/* Repeat every 2 seconds (PUBLISH_DALAY)*/
if ((millis() - publishUpdate) >= PUBLISH_DELAY) {
publishUpdate = millis();
// Verifica o funcionamento das conexões WiFi e ao broker MQTT
checkWiFIAndMQTT();
// Change format of the Data as String for send it via MQTT protocol
sprintf(strTemperature, "%.2fC", getTemperature());
sprintf(strHumidity, "%.2f", getHumidity());
// Send data string to MQTT Broker
MQTT.publish(TOPIC_PUBLISH_TEMPERATURE, strTemperature);
MQTT.publish(TOPIC_PUBLISH_HUMIDITY, strHumidity);
// Keep-alive for connected MQTT broker
MQTT.loop();
}
}