บอร์ด ESP32LoRa-Part-2- Platform
ในตอนนี้จะอธิบายการนำไปใช้ร่วมกับ Platform ครับ
ส่วนแรกคือ การเชื่อมต่อ WiFi กุญแจ id และ device code
//======สำหรับ WiFi ที่จะเชื่อมต่อ หากมาหลายตัวในบริเวณใกล้กัน const char* ssid = "Asenal2021_2G"; const char* password = "kb75699212"; const char* ssid1 = "Asenal2021_2G"; const char* password1 = "kb75699212"; const char* ssid2 = "Asenal2021_2G"; const char* password2 = "kb75699212"; //===== Server config , ID, Code //const char* host = "http://192.168.1.34"; const char* host = "myiotcity.com"; char* code = "123rr"; char* dID = "204";
โดยมีความสามารถสำคัญ 2 ส่วน คือ
- การอ่านค่าจากเซนเซอร์ และส่งขึ้นไปยังแพลตฟอร์ม
- การ รับค่า Relay Status จาก Platform มายัง Device
- การสื่อสารระหว่างแอพในมือถือ แพลตฟอร์ม และ Device
การอ่านค่าจากเซนเซอร์
จะมี Loop การทำงานกระจายออกไปตามแต่ละเซนเซอร์ เช่น AM2315 , MYMD02 , Soil Sensor, Energy (PZEM) ซึ่งจะได้ข้อมูล data1, data2, data3, data4 … data18, data19, data20 ซึ่งเราจะสามารถเปลี่ยน ให้เป็นข้อมูลใดๆ ได้ตามความเหมาะสม ตามความต้องการ
void Energy() { // Print the custom address of the PZEM Serial.print("PZEM Custom Address:"); Serial.println(pzem.readAddress(), HEX); //Read the data from the sensor float voltage = pzem.voltage(); float current = pzem.current(); float power = pzem.power(); float energy = pzem.energy(); float frequency = pzem.frequency(); float pf = pzem.pf(); // Check if the data is valid if (isnan(voltage)) { Serial.println("Error reading voltage"); } else if (isnan(current)) { Serial.println("Error reading current"); } else if (isnan(power)) { Serial.println("Error reading power"); } else if (isnan(energy)) { Serial.println("Error reading energy"); } else if (isnan(frequency)) { Serial.println("Error reading frequency"); } else if (isnan(pf)) { Serial.println("Error reading power factor"); } else { // Print the values to the Serial console Serial.print("Voltage: "); Serial.print(voltage); Serial.println("V"); Serial.print("Current: "); Serial.print(current); Serial.println("A"); Serial.print("Power: "); Serial.print(power); Serial.println("W"); Serial.print("Energy: "); Serial.print(energy, 3); Serial.println("kWh"); Serial.print("Frequency: "); Serial.print(frequency, 1); Serial.println("Hz"); Serial.print("PF: "); Serial.println(pf); } data7 = String(voltage); data8 = String(current); data9 = String(power); data10 = energy; data11 = frequency; data12 = pf; Serial.println(); }
ในการส่งค่าไปยัง Platform Server โดยการเรียกใช้ Forward_loop();
void Forward_loop() { ++value; Serial.print("connecting to server .... "); //Serial.println(host); // Use WiFiClient class to create TCP connections WiFiClient client; const int httpPort = 80; if (!client.connect(host, httpPort)) { Serial.println("connection failed"); return; } // We now create a URI for the request String url = "/api/insertData?device_id=" + String(iddevice) + "&code=" + String(ccode) + "&data1=" + String(data7) + "&data2=" + String(data8) + "&data3=" + String(data3) + "&data4=" + String(data4) + "&data5=" + String(v0) + "&data6=" + String(pHValue) + "&data7=" + String(data7) + "&data8=" + String(data8) + "&data9=" + String(data9) + "&data10=" + String(data10) + "&data11=" + String(data11) + "&data12=" + String(22) + "&data13=" + String(13) + "&data14=" + String(14) + "&data15=" + String(15) + "&data16=" + String(16) + "&data17=" + String(17) + "&data18=" + String(18) + "&data19=" + String(19) + "&data20=" + String(20); // Serial.print("Requesting URL: "); // Serial.println(url); // This will send the request to the server client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n"); unsigned long timeout = millis(); while (client.available() == 0) { if (millis() - timeout > 5000) { Serial.println(">>> Client Timeout !"); client.stop(); return; } } // Read all the lines of the reply from server and print them to Serial while (client.available()) { String line = client.readStringUntil('\r'); //Serial.print(line); } Serial.println(); Serial.println("closing connection"); delay(1000); }
การ รับค่า Relay Status จาก Platform มายัง Device
ทำได้โดยการเรียกจาก ลูป read_master_status_FromServer()
โดยการเรียกใช้ API โดยจะต้องให้ dID และรหัส (code) เพื่อให้ API ค้นหาสิ่งที่ต้องการออกมาได้ โดยจะได้ output ออกมาเป็น Json Object แล้วทำการอ่านค่าจาก member ของ Json ตามที่ต้องการ
เช่น กรณีนี้ในบรรทัด 66 – 74 จะเป็นการอ่านค่าสถานะ Relay ภายในระบบ (RR1-RR5) ของการตั้งค่าควบคุม สูงต่ำ และ RR6-RR9 สำหรับการตั้งเวลา ที่กำหนดมาจากแอพมือถือ หรือ admin panel อีกทีหนึ่ง โดย RR10 ตั้งไว้สำหรับการทำ OTA
//// read control ==== void read_master_status_FromServer() { Serial.print("Reading control command from Server ... connecting to "); //Serial.println(host); WiFiClient client; delay(1500); if (client.connect(host, 80)) { Serial.println("reconnecting..."); url = "/api/getRealyStatus/" + String(dID) + "/" + String(code) + "/" + "abZYrshRYR243askdSKSKSK5646dkfmTURDsand"; Serial.print("Requesting URL: "); //Serial.println(url); // comment to prevent hacker client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n"); delay(2000); String section = "header"; while (client.available()) { //Serial.println("Connection available "); String line = client.readStringUntil('\r'); //Serial.print(line); // we’ll parse the HTML body here if (section == "header") { // headers.. if (line == "\n") { // skips the empty space at the beginning section = "json"; } } else if (section == "json") { // print the good stuff section = "ignore"; String result = line.substring(1); // Parse JSON int size = result.length() + 1; char json[size]; result.toCharArray(json, size); StaticJsonDocument <2000> doc; //StaticJsonBuffer<2000> jsonBuffer; DeserializationError error = deserializeJson(doc, json); //JsonObject& json_parsed = jsonBuffer.parseObject(json); //if (!json_parsed.success()) // { // Serial.println("parseObject() failed"); // return; // } if (error) return; Serial.println("parseObject() OK ..."); //Serial.println(result); // show all json found //String led = json_parsed["led"][0]["status"]; String master_state = doc["result"]["masterStatus"]; String led1 = doc["result"]["relayStatus"]["data6_H"]; String led2 = doc["result"]["relayStatus"]["data6_L"]; String led3 = doc["result"]["relayStatus"]["data3_status"]; String FlowBypass = doc["result"]["relayStatus"]["data5_status"]; String RR1 = doc["result"]["relayStatus"]["data1_status"]; String RR2 = doc["result"]["relayStatus"]["data2_status"]; String RR3 = doc["result"]["relayStatus"]["data3_status"]; String RR4 = doc["result"]["relayStatus"]["data4_status"]; String RR5 = doc["result"]["relayStatus"]["data5_status"]; String RR6 = doc["result"]["relayStatus"]["data6_status"]; // Timer relay 6 in platform String RR7 = doc["result"]["relayStatus"]["data7_status"]; // Timer relay 7 in platform String RR8 = doc["result"]["relayStatus"]["data8_status"]; // Timer relay 8 in platform String RR9 = doc["result"]["relayStatus"]["data9_status"]; // Timer relay 9 in platform String RR10 = doc["result"]["relayStatus"]["data10_status"]; // Timer relay 10 in platform String R_OTA = doc["result"]["relayStatus"]["data10_status"]; // Timer relay 8 in platform R1 = RR1; R2 = RR2; R3 = RR3; R4 = RR4; R5 = RR5; R6 = RR6; R7 = RR7; R8 = RR8; R9 = RR9; R10 = RR10; RR_OTA = String(R_OTA); Serial.println("Relay : " + String(R1) + " " + String(R2) + " " + String(R3) + " " + String(R4) + " " + String(R5) + " " + String(R6) + " " + String(R7) + " " + String(R8) + " " + String(R9) + " " + String(R10)); // string led = json_parsed["table name""][array number]["value of field"] Serial.print("Relay 1 := "); Serial.println(led1); Serial.print("Master state = "); Serial.println(master_state); Serial.print("R8 for Relay : "); Serial.println(R8); Serial.print("RR_OTA1 : "); Serial.println(RR_OTA); Time1 = led1 ; Time2 = led2 ; /* if (R3 == "1") { Relay_ON_OFF(RELAY3, ON); } else { Relay_ON_OFF(RELAY3, OFF); } */ if (master_state == "0") { MainPumpStop(); MainPump = "Stop"; } else { // this loop master_state == "1 if (R7 == "1") { MainPumpRun(); MainPump = "Run" ; //delay(5000); /// check flow sensor //RequestFlowLowStatus(); if (FlowBypass == "1") { MainPumpRun(); Serial.println("Water Pump in By-pass Mode .. please take care ..."); FlowBypass = "By-Pass"; delay(1000); flowsensor = "--"; } else { if (FlowLowStatus == "1") { MainPumpRun(); flowsensor = "OK"; } else { MainPumpStop(); Serial.println("Flow Low pump will stop "); flowsensor = "NOK"; } FlowBypass = "Protecะed"; } } else { //Serial.println("Flow low stop pump check and reset the system ... "); flowsensor = "NOK"; MainPumpStop(); } } /* if (led1 = "0") { digitalWrite(13,LOW); digitalWrite(15,LOW); } else { digitalWrite(13,HIGH); digitalWrite(15,HIGH); } */ Serial.print("Pump Start : "); Serial.println(led1); Serial.print("Pump Stop : "); Serial.println(led2); Serial.print("Led3 : "); Serial.println(led3); Serial.print("Master Status : "); Serial.println(master_state); Serial.print("Timer Relay R5 : "); Serial.println(R5); Serial.print("By-Pass Status : "); Serial.println(FlowBypass); Serial.println("Relay : " + String(R1) + " " + String(R2) + " " + String(R3) + " " + String(R4) + " " + String(R5) + " " + String(R6) + " " + String(R7) + " " + String(R8) + " " + String(R9) + " " + String(R10)); RR_OTA = String(R_OTA); Serial.print("RR_OTA2 : "); Serial.println(RR_OTA); // delay(1000); //LCD_Pump_Status(); } // if found json } // end while client available } // end if host connected else { // if you couldn't make a connection: ///Serial.println("connection failed read server 1"); } }
เมื่อเราได้ค่า RR1 – RR9 ออกมาแล้ว ก็จะสามารถนำไปเขียนเป็นเงื่อนไขสำหรับการควบคุมระบบได้
การสื่อสารระหว่างแอพในมือถือ แพลตฟอร์ม และ Device
การทำงานร่วมกันในระบบประกอบด้วยระบบ
Platform ที่ทำหน้าที่เป็น BackEnd โดยติดตั้งบน VPS Platform จะมี API , Database และ Script สำหรับควบคุมการทำงาน การแสดงผล การรับข้อมูลจาก Device
Mobile App จะเป็นเครื่องมืออำนวยความสะดวกให้กับผู้ใช้งาน โดยสามารถดำเนินการทุกอย่างได้ เช่น การสร้าง device, system app การกำหนด label การตั้งค่า ตั้งเวลา และการควบคุมปิดเปิดอุปกรณ์รายตัวผ่านการควบคุม Relay 4 ตัวหรือมากกว่า
Device หรือ MCU ที่ทำหน้าที่เป็น field device ที่มันจะถูกติดตั้งในตู้ควบคุมขนาดใหญ่ขึ้น ที่มีอุปกรณ์เพิ่มเติมอื่นๆ ที่จะช่วยกันทำงานเป็นระบบ เช่น เบรกเกอร์ แมกนีติก รีเลย์ช่วย และเซนเซอร์ต่างๆ