LoRaNode & WiFi GateWay
ด้วยข้อจำกัดในการติดตั้ง Gateway จึงทำการประยุกต์การสื่อสารแบบผสมคือ ใช้การวัดและส่งข้อมูลด้วย LoRa Node ถึง Lora Node Receiver และทำการส่งต่อไปยัง Server ด้วย WiFI Gateway ด้วย Heltec 32
Code สำหรับ LoRaNode ตัวส่งที่ 1
/* This is a simple example show the Heltec.LoRa sended 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 <Adafruit_Sensor.h> #include <DHT.h> // กรณีนี้ต้องใช้คู่กันกับ DHT_U.h #include <DHT_U.h> #define DHTPIN 2 // Pin which is connected to the DHT sensor. // Uncomment the type of sensor in use: //#define DHTTYPE DHT11 // DHT 11 //#define DHTTYPE DHT22 // DHT 22 (AM2302) #define DHTTYPE DHT21 // DHT 21 (AM2301) // See guide for details on sensor wiring and usage: // https://learn.adafruit.com/dht/overview DHT_Unified dht(DHTPIN, DHTTYPE); uint32_t delayMS; #include "heltec.h" #include "images.h" #define BAND 510E6 //you can set band here directly,e.g. 868E6,915E6 unsigned int counter = 0; String rssi = "RSSI --"; String packSize = "--"; String packet ; String datasend ; float temp_0 = 0; float humid_0 = 0; float vHumidity = 0; float vTemperature = 0; String data1="166"; String cccode = "NPY-G-2910117"; void logo() { Heltec.display->clear(); Heltec.display->drawXbm(0,5,logo_width,logo_height,logo_bits); Heltec.display->display(); } void AM2301_setup() { Serial.begin(115200); // Initialize device. dht.begin(); Serial.println("DHTxx Unified Sensor Example"); // Print temperature sensor details. sensor_t sensor; dht.temperature().getSensor(&sensor); Serial.println("------------------------------------"); Serial.println("Temperature"); Serial.print ("Sensor: "); Serial.println(sensor.name); Serial.print ("Driver Ver: "); Serial.println(sensor.version); Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id); Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println(" *C"); Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println(" *C"); Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println(" *C"); Serial.println("------------------------------------"); // Print humidity sensor details. dht.humidity().getSensor(&sensor); Serial.println("------------------------------------"); Serial.println("Humidity"); Serial.print ("Sensor: "); Serial.println(sensor.name); Serial.print ("Driver Ver: "); Serial.println(sensor.version); Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id); Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println("%"); Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println("%"); Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println("%"); Serial.println("------------------------------------"); // Set delay between sensor readings based on sensor details. delayMS = sensor.min_delay / 1000; } void setup() { //WIFI Kit series V1 not support Vext control 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->display(); delay(1000); } void loop() { Heltec.display->clear(); Heltec.display->setTextAlignment(TEXT_ALIGN_LEFT); Heltec.display->setFont(ArialMT_Plain_10); Heltec.display->drawString(0, 0, "GeoShrimp Data packet: "); //Heltec.display->drawString(0, 10, String(counter)); Heltec.display->drawString(0,10, String(datasend)); Heltec.display->display(); // send packet LoRa.beginPacket(); /* * LoRa.setTxPower(txPower,RFOUT_pin); * txPower -- 0 ~ 20 * RFOUT_pin could be RF_PACONFIG_PASELECT_PABOOST or RF_PACONFIG_PASELECT_RFO * - RF_PACONFIG_PASELECT_PABOOST -- LoRa single output via PABOOST, maximum output 20dBm * - RF_PACONFIG_PASELECT_RFO -- LoRa single output via RFO_HF / RFO_LF, maximum output 14dBm */ LoRa.setTxPower(14,RF_PACONFIG_PASELECT_PABOOST); LoRa.print(datasend); //LoRa.print(counter); LoRa.endPacket(); AM2301_loop(); counter=temp_0; datasend = String(cccode)+","+String(166)+","+String(temp_0)+","+String(humid_0); //datasend = "30.00,95.35,99.00"; //counter++; digitalWrite(LED, HIGH); // turn the LED on (HIGH is the voltage level) delay(4000); // wait for a second digitalWrite(LED, LOW); // turn the LED off by making the voltage LOW delay(4000); // wait for a second } void AM2301_loop() { // Delay between measurements. delay(delayMS); // Get temperature event and print its value. sensors_event_t event; dht.temperature().getEvent(&event); if (isnan(event.temperature)) { Serial.println("Error reading temperature!"); //temp_0=35; } else { Serial.print("Temperature: "); Serial.print(event.temperature); Serial.println(" *C"); temp_0 = event.temperature; } // Get humidity event and print its value. dht.humidity().getEvent(&event); if (isnan(event.relative_humidity)) { Serial.println("Error reading humidity!"); //humid_0=90; } else { Serial.print("Humidity: "); Serial.print(event.relative_humidity); Serial.println("%"); humid_0 = event.relative_humidity; } }
โค้ดสำหรับตัวส่งตัวที่ 2
/* This is a simple example show the Heltec.LoRa sended 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 <Adafruit_Sensor.h> #include <DHT.h> // กรณีนี้ต้องใช้คู่กันกับ DHT_U.h #include <DHT_U.h> #define DHTPIN 2 // Pin which is connected to the DHT sensor. // Uncomment the type of sensor in use: //#define DHTTYPE DHT11 // DHT 11 //#define DHTTYPE DHT22 // DHT 22 (AM2302) #define DHTTYPE DHT21 // DHT 21 (AM2301) // See guide for details on sensor wiring and usage: // https://learn.adafruit.com/dht/overview DHT_Unified dht(DHTPIN, DHTTYPE); uint32_t delayMS; #include "heltec.h" #include "images.h" #define BAND 510E6 //you can set band here directly,e.g. 868E6,915E6 unsigned int counter = 0; String rssi = "RSSI --"; String packSize = "--"; String packet ; String datasend ; float temp_0 = 0; float humid_0 = 0; float vHumidity = 0; float vTemperature = 0; String data1="167"; String cccode = "Intake-2910117"; void logo() { Heltec.display->clear(); Heltec.display->drawXbm(0,5,logo_width,logo_height,logo_bits); Heltec.display->display(); } void AM2301_setup() { Serial.begin(115200); // Initialize device. dht.begin(); Serial.println("DHTxx Unified Sensor Example"); // Print temperature sensor details. sensor_t sensor; dht.temperature().getSensor(&sensor); Serial.println("------------------------------------"); Serial.println("Temperature"); Serial.print ("Sensor: "); Serial.println(sensor.name); Serial.print ("Driver Ver: "); Serial.println(sensor.version); Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id); Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println(" *C"); Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println(" *C"); Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println(" *C"); Serial.println("------------------------------------"); // Print humidity sensor details. dht.humidity().getSensor(&sensor); Serial.println("------------------------------------"); Serial.println("Humidity"); Serial.print ("Sensor: "); Serial.println(sensor.name); Serial.print ("Driver Ver: "); Serial.println(sensor.version); Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id); Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println("%"); Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println("%"); Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println("%"); Serial.println("------------------------------------"); // Set delay between sensor readings based on sensor details. delayMS = sensor.min_delay / 1000; } void setup() { //WIFI Kit series V1 not support Vext control 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->display(); delay(1000); } void loop() { Heltec.display->clear(); Heltec.display->setTextAlignment(TEXT_ALIGN_LEFT); Heltec.display->setFont(ArialMT_Plain_10); Heltec.display->drawString(0, 0, "GeoShrimp Data packet: "); //Heltec.display->drawString(0, 10, String(counter)); Heltec.display->drawString(0,10, String(datasend)); Heltec.display->display(); // send packet LoRa.beginPacket(); /* * LoRa.setTxPower(txPower,RFOUT_pin); * txPower -- 0 ~ 20 * RFOUT_pin could be RF_PACONFIG_PASELECT_PABOOST or RF_PACONFIG_PASELECT_RFO * - RF_PACONFIG_PASELECT_PABOOST -- LoRa single output via PABOOST, maximum output 20dBm * - RF_PACONFIG_PASELECT_RFO -- LoRa single output via RFO_HF / RFO_LF, maximum output 14dBm */ LoRa.setTxPower(14,RF_PACONFIG_PASELECT_PABOOST); LoRa.print(datasend); //LoRa.print(counter); LoRa.endPacket(); AM2301_loop(); datasend = String(cccode)+","+String(167)+","+String(temp_0)+","+String(humid_0)+","+String(220.5)+","+String(0.55)+","+String(45.00)+","+String(25.75)+"," +String(100.05); // ใช้ค่าวัดจริงมา 2 ค่า และ ใส่ข้อมูลจำลองไปอีก 4 ทดสอบขนาดการส่ง // โดย ccode และ 167 คือ รหัสและเลข ID ของ node ตัวนี้ digitalWrite(LED, HIGH); // turn the LED on (HIGH is the voltage level) delay(4000); // wait for a second digitalWrite(LED, LOW); // turn the LED off by making the voltage LOW delay(4000); // wait for a second } void AM2301_loop() { // Delay between measurements. delay(delayMS); // Get temperature event and print its value. sensors_event_t event; dht.temperature().getEvent(&event); if (isnan(event.temperature)) { Serial.println("Error reading temperature!"); //temp_0=35; } else { Serial.print("Temperature: "); Serial.print(event.temperature); Serial.println(" *C"); temp_0 = event.temperature; } // Get humidity event and print its value. dht.humidity().getEvent(&event); if (isnan(event.relative_humidity)) { Serial.println("Error reading humidity!"); //humid_0=90; } else { Serial.print("Humidity: "); Serial.print(event.relative_humidity); Serial.println("%"); humid_0 = event.relative_humidity; } }
/* 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 = "kb75699212"; const char* host = "otrixiot.com"; const char* code = "ESP32-002"; 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); }
ขอบคุณ โค้ดที่มาบางส่วน https://www.arduino-makerzone.com/article/42/arduino-tips-tricks-ep3-arduino-splint-string