รูปแบบโค้ดสำหรับการเชื่อมต่อ Device แบบ WiFi

ไอโอทีเส้นทางสู่เมืองอัจฉริยะ

Created with Sketch.

รูปแบบโค้ดสำหรับการเชื่อมต่อ Device แบบ WiFi

ตัวอย่างรูปแบบโค้ดสำหรับการเชื่อมต่อที่เป็นรูปแบบมาตรฐานที่จะต้องใช้ในแพลตฟอร์ม มีส่วนสำคัญประกอบด้วย

  • ส่วนการเชื่อมต่อตัวกลางเช่น WiFi
  • ส่วนการเชื่อมต่อกับเวบไซต์ โดเมนหลัก
  • ส่วนการเข้าถึง Server และการอัพโหลดข้อมูล
  • ส่วนของการอ่านข้อมูล Downlink
  • ส่วนการจัดการหลังบ้านกำหนดการแสดงผล

ส่วนที่ 1. การกำหนดตัวกลางการส่งข้อมูลไปยัง internet

const char* ssid     = "Arsenal2019_2.4G";
const char* password = "xxxxxxxxx";
const char* host = "otrixiot.com";



void WiFiForwardSetup()
{
    Serial.begin(115200);
    delay(10);
    // We start by connecting to a WiFi network
    Serial.println();
    Serial.println();
    Serial.print("Connecting to ");
    Serial.println(ssid);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    Serial.println("");
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
}

ตามตัวอย่างนี้เป็นการกำหนดการเชื่อมต่อแบบ WiFi สำหรับ device จำพวก esp8266, esp32, heltec LoRa 32 โดย ssid คือ ชื่อ WiFi และ password คือ รหัสผ่านของ WiFi นั้น ๆ และ host คือ Domain คือ domain ที่ระบบตั้งอยู่ สำหรับระบบของเราจะใช้ Otrixiot.com

การเชื่อมต่อแบบ Ethernet

Example

ส่วนที่ 2. ส่วนเข้าเชื่อมต่อกับ Domain เป็นรูปแบบมาตรฐานของ Arduino IDE ในแบบ WiFi ด้วย Library WiFi ด้วยคำสั่ง WiFiClient Client;

    Serial.print("connecting to ");
    
    //==============================
    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;
    }
    //==============================
    
 

โดย host เป็นตัวแปรที่ถูกกำหนดมาจากขั้นตอนแรก และกำหนด port = 80 ตามด้วยการตรวจสอบว่าหากทำการเชื่อมต่อไม่ได้ ก็จบออกจาก void นี้

ส่วนที่ 3 ส่วนการอัพโหลดข้อมูล

// We now create a URI for the request
     String url = "/api/insertData?device_id=" + String(iddevice)+"&code="+String(ccode)+"&data1=" +String(data1) +"&data2="
   + String(data2)+"&data3=" +String(data3)+"&data4=" +String(data4)+"&data5=" +String(data5)
   +"&data6=" +String(data6)+"&data7=" +String(data7)+"&data8=" +String(data8)+"&data9=" +String(data9)
   +"&data10=" +String(data10)+"&data11=" +String(data11)+"&data12=" +String(data12)+"&data13=" +String(data13)
   +"&data14=" +String(data14)+"&data15=" +String(data15)+"&data16=" +String(data16)+"&data17=" +String(data17)
   +"&data18=" +String(data18)+"&data19=" +String(data19)+"&data20=" +String(data20);   
 // ตัวรับจะทำการส่ง idddevice และ code ที่ได้รับจาก node ส่งไปยัง server  ดังนั้น ตัว Gateway ตัวนี้จึงทำหน้าที่แยกยแยะ device ได้ดี
    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;
        }
    }

โดยประกอบด้วยส่วนการเตรียม url ก่อนการส่งคำสั่ง request

โดย /api/insertData คือ การเรียก API insertData ที่อยู่ภายใน folder /api/ และตามด้วย

device_id คือ เลขประจำตัวของ device ซึ่งจะไม่ซ้ำกัน ถูกกำหนดมาจากขั้นตอนการ add device ที่สามารถตรวจสอบได้ด้วยตนเอง

code คือ รหัสผ่าน หรือ Password หรือ Secret Key ที่จะถูกกำหนดให้มีความปลอดภัยโดยผู้ใช้เอง

data1 ถึง data20 คือ ข้อมูลลำดับที่ 1 ถึง 20 ที่จะถูกส่งมาจาก device ในคราวเดียวกัน

และตามด้วยส่วนของการ request ด้วยคำสั่ง GET

ส่วนที่ 4 การตรวจสอบ แสดงผลการโต้ตอบจาก Server

// 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(5000);

หากรวมทุกส่วนเข้าด้วยกันเป็น โคัดตัวอย่างสมบูรณ์สำหรับการเชื่อมต่อ WiFi ก็จะได้ผลดังตัวอย่างนี้

/*
  This is a simple example show the Heltec.LoRa recived data in OLED.
  The onboard OLED display is SSD1306 driver and I2C interface. In order to make the
  OLED correctly operation, you should output a high-low-high(1-0-1) signal by soft-
  ware to OLED's reset pin, the low-level signal at least 5ms.
  OLED pins to ESP32 GPIOs via this connecthin:
  OLED_SDA -- GPIO4
  OLED_SCL -- GPIO15
  OLED_RST -- GPIO16
  
  by Aaron.Lee from HelTec AutoMation, ChengDu, China
  成都惠利特自动化科技有限公司
  www.heltec.cn
  
  this project also realess in GitHub:
  https://github.com/Heltec-Aaron-Lee/WiFi_Kit_series
*/
//=========
#include <WiFi.h>
//======
#include "heltec.h" 
#include "images.h"
#define BAND    510E6  //you can set band here directly,e.g. 868E6,915E6
String rssi = "RSSI --";
String packSize = "--";
String packet ;
String ccode ;
String iddevice ;
//====
const char* ssid     = "Arsenal2019_2.4G";
const char* password = "kb75xxxxxx";
const char* host = "otrixiot.com";
const char* code = "xxxxxxxx";
float temp_0 = 0;
float humid_0 = 0;
float vHumidity = 0;
float vTemperature = 0;
String data1 ;
String data2 ;
String data3 ;
float data4=100;
float data5=33;
float data6=33;
float data7=33;
float data8=33;
float data9=33;
float data10=33;
float data11=33;
float data12=33;
float data13=33;
float data14=33;
float data15=33;
float data16=33;
float data17=33;
float data18=33;
float data19=33;
float data20=33;
/// ===
String sentpacket ;
String str;
//= "35.55,44.789,345.678,A0";  // สร้างตัวแปรชื่อ str ชนิด String สำหรับทดสอบการ Splint ด้วยเครื่องหมาย ','
char charBuf[100];
void logo(){
  Heltec.display->clear();
  Heltec.display->drawXbm(0,5,logo_width,logo_height,logo_bits);
  Heltec.display->display();
}
void LoRaData(){
  Heltec.display->clear();
  Heltec.display->setTextAlignment(TEXT_ALIGN_LEFT);
  Heltec.display->setFont(ArialMT_Plain_10);
  Heltec.display->drawString(0 , 15 , "Received "+ packSize + " bytes");
  Heltec.display->drawStringMaxWidth(0 , 26 , 128, packet);
  Heltec.display->drawString(0, 0, rssi);  
  Heltec.display->display();
}
void cbk(int packetSize) {
  packet ="";
  packSize = String(packetSize,DEC);
  for (int i = 0; i < packetSize; i++) { packet += (char) LoRa.read(); }
  rssi = "RSSI " + String(LoRa.packetRssi(), DEC) ;
  LoRaData();
  //sentpacket =packet;
}
void WiFiForwardSetup()
{
    Serial.begin(115200);
    delay(10);
    // We start by connecting to a WiFi network
    Serial.println();
    Serial.println();
    Serial.print("Connecting to ");
    Serial.println(ssid);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    Serial.println("");
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
}
void setup() { 
   //WIFI Kit series V1 not support Vext control
  WiFiForwardSetup();
  Heltec.begin(true /*DisplayEnable Enable*/, true /*Heltec.Heltec.Heltec.LoRa Disable*/, true /*Serial Enable*/, true /*PABOOST Enable*/, BAND /*long BAND*/);
 
  Heltec.display->init();
  Heltec.display->flipScreenVertically();  
  Heltec.display->setFont(ArialMT_Plain_10);
  logo();
  delay(1500);
  Heltec.display->clear();
  
  Heltec.display->drawString(0, 0, "Heltec.LoRa Initial success!");
  Heltec.display->drawString(0, 10, "Wait for incoming data...");
  Heltec.display->display();
  delay(1000);
  //LoRa.onReceive(cbk);
  LoRa.receive();
}
void loop() {
  int packetSize = LoRa.parsePacket();
  if (packetSize) { cbk(packetSize); 
   str = packet;
   dataread_loop(); 
   Forward_loop();  
  }
  delay(10);
 
}
int value = 0;
void Forward_loop()
{
    delay(5000);
  
//    scanSensor_Box_Temperature();
    //data1 = vTemperature;
    ++value;
      
    data1 = data1 ;
    data2 = data2 ;
    Serial.print("connecting to ");
    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(data1) +"&data2="
   + String(data2)+"&data3=" +String(data3)+"&data4=" +String(data4)+"&data5=" +String(data5)
   +"&data6=" +String(data6)+"&data7=" +String(data7)+"&data8=" +String(data8)+"&data9=" +String(data9)
   +"&data10=" +String(data10)+"&data11=" +String(data11)+"&data12=" +String(data12)+"&data13=" +String(data13)
   +"&data14=" +String(data14)+"&data15=" +String(data15)+"&data16=" +String(data16)+"&data17=" +String(data17)
   +"&data18=" +String(data18)+"&data19=" +String(data19)+"&data20=" +String(data20);   
 // ตัวรับจะทำการส่ง idddevice และ code ที่ได้รับจาก node ส่งไปยัง server  ดังนั้น ตัว Gateway ตัวนี้จึงทำหน้าที่แยกยแยะ device ได้ดี
    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(5000);
}
//====
void splint_string(char sz[]){  // สร้างฟังชันต์ชื่อ splint_string กำหนดตัวแปรนำเข้าชื่อ sz ชนิด char แบบอาเรย์
  char *p = sz;  // สร้างตัวแปรชื่อ p ชนิด Pointer มีค่าเท่ากับ sz
  char *str;  // สร้างตัวแปรชื่อ str ชนิด Pointer
  int counter = 0;  // สร้างตัวแปรชื่อ counter ชนิด int สำหรับทำการนับครั้งที่ตัด
  
  while ((str = strtok_r(p, ",", &p)) != NULL){  // วนทำลูป while ซ้ำ โดยเรียกฟังชันต์ strtok_r() โดยทำการตัดค่าใน p เมื่อเจอเครื่องหมาย','
   
   // Serial.print(counter + String(". "));  // แสดงผลจำนวนครั้งที่ตัด
   // Serial.println(str); // แสดงผลค่าที่ตัดได้
   counter++;
   if (counter ==1){ccode = str;}
   if (counter ==2){iddevice   = str;}
   if (counter ==3){data1 = str;}
   if (counter ==4) {data2 = str;}
  
  }
  counter = 0;  // เคลียร์ค่าใน counter เป็น 0
}
void dataread_loop() 
{
  //char charBuf[100];
  str = packet;
  str.toCharArray(charBuf, 100);  // คัดลอกอักขระของชุดอักขระไปยังตัวแปร charBuf
  splint_string(charBuf); // เรียกใช้งานฟังชั่น Splint String
  //delay(1000);
}

โดยในตัวอย่างนี้ มี โค้ดอื่นๆ รวมกันอยู่เป็นการใช้งาน heltec LoRa 32 ที่ท่านจะเห็นว่าเราสามารถเอา LoRa device มาใช้งานเป็น Gateway ได้