บอร์ด 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 ส่วน คือ

  1. การอ่านค่าจากเซนเซอร์ และส่งขึ้นไปยังแพลตฟอร์ม
  2. การ รับค่า Relay Status จาก Platform มายัง Device
  3. การสื่อสารระหว่างแอพในมือถือ แพลตฟอร์ม และ 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 ที่มันจะถูกติดตั้งในตู้ควบคุมขนาดใหญ่ขึ้น ที่มีอุปกรณ์เพิ่มเติมอื่นๆ ที่จะช่วยกันทำงานเป็นระบบ เช่น เบรกเกอร์ แมกนีติก รีเลย์ช่วย และเซนเซอร์ต่างๆ

Leave a Reply

Your email address will not be published.