ESP8266 / ESP32 & Mesh Network ตอนที่ 4: Painlessmesh Bridge with LoRa

บทความในตอนนี้ก็จะใช้เวลาเขียนนานหน่อย เนื่องด้วยงานที่ทำ แล้วก็อุปกรณ์เจ้ากรรม Heltec ESP32+OLED 915MHz ที่สั่งมาดันเสียไปทั้งคู่ ก็เลยเว้นช่วงไว้รออุปกรณ์มาให้ครบเพื่อทดสอบ ซึ่งจากประสบการณ์ที่สั่งของจากจีนมาทดลอง กรณีที่ไม่ได้สั่งแบบนำเข้ามาทดสอบแบบเป็นทางการ ก็ควรสั่งเข้ามาอย่างน้อย 2-3 ตัวด้วยกัน เผื่อตัวหนึ่งใช้งานไม่ได้จะได้ทดสอบอีกตัวหนึ่ง จะได้รู้ว่าเอ๊ะมันเป็นที่ code ของเราหรือว่าเป็นที่อุปกรณ์กันแน่ ซึ่งสุดท้ายตัวนึง OLED เสีย อีกตัวนึง LoRa Module เสีย จบกันกับย่าน 915MHz

Heltec ESP32 SX1278 ความถี่ 433.175MHz ทดลองระยะประมาณ 80 เมตร ตัวส่งอยู่ในบ้าน ตัวรับอยู่ท้ายสวนมะพร้าว

เนื้อหาหลักๆในตอนนี้ก็จะเกี่ยวกับเรื่องของ LPWAN (Low Power Wide Area Network) อย่าง LoRa ทั้งการใช้งาน ข้อดีข้อเสีย กฎหมายที่เกี่ยวข้องในการนำมาใช้งาน เพราะถ้าติดตามอ่านมาตั้งแต่ตอนที่ 1 (ESP8266/ESP32: Introduction & Painlessmesh) ใจความหลักในการใช้งาน Mesh Network ด้วย Painlessmesh นั้นจบไปตั้งแต่ตอนที่ 3 แล้วครับ ที่เหลือเป็นการประยุกต์มากกว่า ว่าเราจะใช้งาน Mesh Network ให้เหมาะสมยังไง หรือเพื่อจุดประสงค์ไหน เช่น

  • เพื่อลด Single Point of Failure
  • เพื่อขยายพื้นที่การครอบคลุมในการส่งข้อมูล
  • ลดต้นทุนในการขยายจุดกระจายสัญญาณ

จากนั้นการส่งข้อมูลจาก Mesh Network ซึ่งเปรียบเหมือน Local Network ของเรา เราจะ Bridge ยังไงเพื่อให้ข้อมูลเหล่านั้นไปยัง Server, Database, Cloud, MQTT Broker หรืออะไรก็แล้วแต่ที่อยู่ Network อีกวงหนึ่งหรือผ่าน Internet ซึ่งก็จะได้ทดลองทำกันไปในตอนที่ 3 (ESP8266/ESP32: Painlessmesh Bridge) ซึ่งถ้าใครจะไม่ใช้ Software Serial ในการ Bridge ก็ยังสามารถทำได้อีกหลายวิธี ซึ่งวันนี้เราก็จะมา Bridge ผ่าน LoRa กัน

 

LoRa vs LoRaWan

ผู้ให้บริการทางด้านโทรคมนาคมในบ้านเราช่วงนี้ ทั้ง AIS  (AIS NB-IoT) และ True (True IoT) ก็เปิดตัวบริการ NB-IoT ออกมา ส่วน CAT ก็มาทางสาย LoRa (LoRa IoT by CAT) ซึ่งทั้งคู่ก็ออกมาเพื่อรองรับการสื่อสารสำหรับบริการประเภท IoT  ในส่วนของ AIS และ ​True ที่เป็นผู้ให้บริการมือถืออยู่แล้ว มีความถี่ที่ใช้ในการจัดสรรสำหรับบริการ LTE การมาให้บริการ NB-IoT ก็จะประหยัดต้นทุนไปได้เยอะแถมเป็นการ Utilize ความถี่ที่ตัวเองได้รับอนุญาตมาด้วย เท่าที่เห็นก็เป็น 3 ผู้บริการหลักๆที่เปิดตัวออกมา ซึ่งหัวข้อของเราในวันนี้ก็จะคุยกันในเรื่องของ LoRa และการใช้งานร่วมกัน Mesh Network ฉะนั้นเรามาดูข้อแตกต่างกันระหว่าง LoRa และ LoRaWan กันก่อน

 

 

LoRa จะเป็นการสื่อสารในระดับ Physical Layer ซึ่งเหมาะที่จะใช้งานในลักษณะแบบ P2P ไม่มี Encryption ส่งข้อมูลกันแบบ Broadcast ออกไปเลย ฉะนั้นถ้ามีคนตั้ง LoRa Node ขึ้นมาแล้วใช้ค่า Setting เดียวกับเราก็สามารถที่จะเห็นข้อมูลได้ ซึ่ง LoRa ถูกพัฒนาเป็น Wireless Data Communication โดยบริษัท Cycleo (Grenoble, France) จากนั้นผู้ผลิตชิป Semtech ก็เข้าไปซื้อบริษัทนี้มาในปี 2012 ถ้าดูตามสเปคของชิปยอดฮิตอย่าง SX1276 ที่รองรับย่านความถี่ 920-925MHz ตามประกาศของ กสทช ก็จะเห็นว่าที่ LoRa นั้นส่งได้ไกลนั้นส่วนนึงก็เพราะ High sensitivity ที่รองรับถึง -148dBm เลย (ข้อมูล Semtech SX1276) แต่ใช้งานจริงจะได้ที่เท่าไหร่ต้องดูกัน

LoRa module รุ่นต่างๆ แถวบนเป็น RA-02 จาก Ai-Thinker ที่ใช้ชิป Semtech SX1278/SX1276 สำหรับความถี่ 433MHz และสองตัวล่างสำหรับย่าน 915MHz  ส่วนสองตัวล่างขวาเป็น RM95W จากค่าย Hope RF สำหรับความถี่ย่าน 915MHz

ส่วน LoRaWan นั้นจะอยู่ Ontop ของการสื่อสารแบบ LoRa Radio อีกทีซึ่งจะมีในส่วนของ Protocol การรับส่งข้อมูลเข้ามา รองรับ Encryption ซึ่งใช้ AES-128 ในการเข้ารหัส สามารถทำ QOS ได้ด้วย โดยรายละเอียดของ LoRaWan นั้นจะมีอยู่ค่อนข้างเยอะพอสมควร รวมถึงในส่วนของ Device End Node ก็ยังสามารถจำแนกได้ออกเป็น Class A B C อีก และการทำงานก็จะแบ่งออกเป็น Tier ตามรูปด้านล่างนี้เลยครับ

ฉะนั้นการจะเลือกใช้ LoRa หรือ LoRaWan ก็ควรเลือกให้เหมาะสมกับ Application ที่จะใช้งานด้วย และที่สำคัญควรอยู่ตามข้อกำหนดของ กสทช ด้วยครับเนื่องจากคลื่นความถี่เป็นทรัพยากรส่วนรวมที่มีการใช้งานร่วมกัน ถ้าใช้ LoRa ก็ต้องดูในเรื่องของ Duty Cycle เองด้วยไม่ใช่ส่งข้อมูลตลอดเวลา จองการใช้งานคลื่นความถี่ตลอด รวมถึงกำลังส่งที่ถ้ามากไป ก็จะไปรบกวนการใช้งานของอุปกรณ์หรือ Application ที่ใช้งานในความถี่เดียวกัน

ข้อมูลเพิ่มเติมจาก LoRa Alliance ที่น่าศึกษา ซึ่งทาง LoRa Alliance ก็เป็น Non Profit Organization ที่ผลักดันในเรื่องของการใช้ LoRa/LoRaWan เพื่อใช้ในงาน IoT

 

Limitations

เรามาดูข้อดีข้อเสียของการใช้ LoRaWan กันบ้าง ไม่ใช่ว่าเทคโนโลยีที่ดีอย่าง LoRa/LoRaWan จะเหมาะสมครอบจักรวาลสำหรับทุก Application ฉันใดก็ฉันนั้น Mesh Network ก็จะเหมาะกับ Application ในบางประเภท หรือบางงาน เพราะถ้าเราต้องการเอา LoRa/LoRaWan ไปส่งข้อมูลแบบ Realtime ก็คงไม่เหมาะแน่นอนจะกลายเป็นการจองช่องสัญญาตลอดเวลา หรือให้ส่งข้อมูลขนาดใหญ่ๆก็คงไม่เหมาะเช่นกัน เพราะถูกจำกัดด้วยข้อมูลที่ส่งขนาดไม่กี่ byte และความเร็วในการส่งที่ต่ำ

Suitable use-cases for LoRaWAN:

  • Long range – multiple kilometers
  • Low power – can last months (or even years) on a battery
  • Low cost – less than 20€ CAPEX per node, almost no OPEX
  • Low bandwidth – something like 400 bytes per hour
  • Coverage everywhere – you are the network! Just install your own gateways
  • Secure – 128bit end-to-end encrypted
  • Geolocation / Triangulation – you should probably use GPS for this, but we’re doing our best to make it work with just LoRa. Check out Collos.

Not Suitable for LoRaWAN:

  • Realtime data – you can only send small packets every couple of minutes
  • Phone calls – you can do that with GPRS/3G/LTE
  • Controlling lights in your house – check out ZigBee or BlueTooth
  • Sending photos, watching Netflix – check out WiFi

ที่มา: (Limitations of LoRaWan:The Things Network)

 

Regulation & NBTC

เนื่องจากคลื่นความถี่ถือเป็นทรัพยากรที่ต้องถูกจัดสรรเพราะมีอยู่อย่างจำกัด และต้องมีกำกับดูแลในเรื่องของการใช้งาน ในประเทศไทยก็จะมีองค์กรที่ทันสมัยมว้ากๆ องค์กรหนึ่งชื่อว่า กสทช (สำนักงานคณะกรรมการกิจการกระจายเสียง กิจการโทรทัศน์ และกิจการโทรคมนาคมแห่งชาติ) ที่เดี่ยวๆก็จะชอบมีคนออกมาให้ข่าวว่า เด่วยึดใบอนุญาตมั่ง ปรับนู่นนี่นั่นมั่ง แล้วสุดท้ายเรื่องก็เงียบไป มาดูเรื่องการใช้งานความถี่ของเรากันดีกว่าครับ

จากข้อมูลที่หามาจากเวปของหน่วยงาน กสทช เองบอกได้เลยว่าเล่นเอางงทีเดียว บางทีค้นหาด้วยเลขความถี่ต้องใช้เลขไทย ไม่งั้นไม่เจอ ซึ่งผมรวบรวมมาได้ดังนี้โดยอิงตามความถี่ย่านที่เรามักจะเห็นคุ้นเคยเห็นการใช้งานกันสำหรับ LoRa, RFID และ RC นั่นก็คือ EU433 ISM Band, AS923-925MHz

 

  • ตารางกำหนดคลื่นความถี่แห่งชาติ 2560 (Download Link)

 

  • กรกฎาคม 2560: เอกสารประกอบการรับฟังความคิดเห็นสาธารณะ  ร่างประกาศเกี่ยวกับการใช้คลื่นความถี่ 920-925MHz (Download Link)

 

  • สิงหาคม 2560: ร่างประกาศเกี่ยวกับการใช้คลื่นความถี่ 920-925MHz และแนวทางการอนุญาตเพื่อประกอบกิจการ iot  (Download Link)

 

  • พฤษจิกายน 2560: ราชกิจจานุเบกษา – หลักเกณฑ์การอนุญาตให้ใช้คลื่นความถี่ย่าน 920-925MHz (Download Link)

 

  • พฤษจิกายน 2560: ราชกิจจานุเบกษา – มาตรฐานทางเทคนิคของเครื่องโทรคมนาคมและอุปกรณ์สําหรับเครื่องวิทยุคมนาคมที่ไม่ใช่ประเภท RFIDซึ่งใช้คลื่นความถี่ย่าน 920-925MHz (Download Link)

 

  • มกราคม 2561: ราชกิจจานุเบกษา – หลักเกณฑ์และเงื่อนไขการอนุญาตให้ใช้คลื่นความถี่สําหรับอากาศยานซึ่งไม่มีนักบินสําหรับใช้งานเป็นการทั่วไป (Download Link)

 

  • กุมภาพันธ์ 2561 ราชกิจานุเบกษา – เครื่องวิทยุคมนาคมและสถานีวิทยุคมนาคมที่ได้รับการยกเว้นไม่ต้องได้รับใบอนุญาตตามพระราชบัญญัติวิทยุคมนาคม (Download Link)

 

  • ความถี่วิทยุและใบอนุญาตวิทยุโทรคมนาคมประเภท RFID (Download Link)

 

  • การปรับปรุงกฎระเบียบด้านการบริหารคลื่นความถี่และทรัพยากรโทรคมนาคมเพื่อรองรับการพัฒนาของ Internet of Thingsในประเทศไทย (Download Link)

 

ฉะนั้นสำหรับส่วนของคลื่นความถี่ 433MHz ซึ่งที่เราจะทดสอบกันสำหรับ LoRa นั้น ก็จะไม่ได้เกี่ยวกับการใช้งานทั้ง RFID หรือการใช้งานในด้าน RC กับอากาศยานไร้คนขับ แต่จะทดสอบโดยอาศัยความตามเครื่องวิทยุคมนาคมและสถานีวิทยุคมนาคมที่ได้รับการยกเว้นไม่ต้องได้รับใบอนุญาต ซึ่งย่าน 433MHz นั้นห้ามส่งเกิน 10 มิลลิวัตต์

 

สำหรับย่าน 920-925MHz นั้นซึ่งมีข้อกำหนดในส่วนของ มาตรฐานทางเทคนิคของเครื่องโทรคมนาคมและอุปกรณ์ กสทช.มท. 1033 – 2560 ว่าด้วยเรื่องเครื่องวิทยุคมนาคมที่ไม่ใช่ประเภทRadio Frequency Identification: RFIDซึ่งใช้คลื่นความถี่ย่าน920-925เมกะเฮิรตซ์ ก็กำหนดไว้ว่า ไม่เกิน 50 มิลลิวัตต์ได้รับยกเว้นไม่ต้องได้รับใบอนุญาตให้ทํามีใช้นําเข้าและนําออกซึ่งเครื่องวิทยุคมนาคมและใบอนุญาตให้ตั้งสถานีวิทยุคมนาคมแต่ไม่ได้รับยกเว้นใบอนุญาตให้ค้าซึ่งเครื่องวิทยุคมนาคม

 

ถ้ายึดกันตาม Frequency Plan และตามช่วงความถีที่ กสทช ปลดล้อคให้กับอุปกรณ์และบริการ IoT ก็สามารถใช้ได้สองช่วงเลยครับ ทั้ง AS920 กับ AS923 (The Things Network Frequency Plan)

 

จากข้อมูลด้านบนเนี่ย ก็ต้องอ่านกันดีๆ หลักๆก็ควรยึดตามคลื่นความถี่ที่ใช้งานและจุดประสงค์ที่ใช้งาน จากนั้นก็ดูตามหลักเกณฑ์และเงื่อนไขที่ประกาศในราชกิจจานุเบกษา และก็ยังต้องดูด้วยว่าในการประกาศนั้นมีการยกเลิกประกาศตัวเก่าไว้หรือไม่ หรือพวกประโยคที่ว่าเว้นแต่กำหนดเป็นอย่างอื่น พวกร่างกับการรับฟังความคิดเห็นสาธารณะก็อาจใช้ประกอบได้ กรณีดีที่สุดหากมีข้อสงสัยในเรื่องของการใช้งานความถี่ การผลิตหรือนำเข้าเรื่องอุปกรณ์คมนาคมที่ใช้ความถี่ ก็ควรขอคำตอบจาก กสทช เป็นหลักซึ่งก็ควรทำเป็นหนังสือแจ้งไปเพื่อให้ กสทช ตอบกลับว่าสามารถทำได้ หรือไม่สามารถทำได้ หรือให้ยึดตามข้อกำหนดไหน

 

Scenario

กรณีไหนบ้างที่เราควรจะ Bridge ผ่าน LoRa ซึ่งข้อดีของ LoRa เลยก็คือเรื่องของ Power Consumption ที่ต่ำ และระยะในการส่งที่สูง ฉะนั้นด้วยคุณสมบัตินี้ แทนที่จุดที่เราต้องการเก็บข้อมูล หรือควบคุมอุปกรณ์ จะต้องวาง Mesh Network ให้ครอบคลุมมาถึงจุดที่จะส่งข้อมูลออก Internet อาจจะไม่จำเป็น แต่อาศัยการส่งระยะไกลผ่าน LoRa มาแล้วค่อยมาออก Internet จากฝั่งของ LoRa Node ที่ทำตัวเป็น Gateway ก็ได้ สำหรับตอนที่ 4 นี้ก็จะเป็นการใช้งานผ่าน LoRa นะครับ แต่ถ้าใครอยาก Advance Setup LoRaWan Gateway แล้วใช้งานผ่าน LoRaWan ก็ได้ อย่างที่บอกไว้ครับ หลักการเดียวกันกับตอนที่ 3 ลองมาคิดกันเล่นๆครับ

 

Scenario 1: Smart Farm
ลองนึกภาพของ Green House เรือนปลูกผัก ฟาร์มข้าวโพด หรือทุ่งนา ที่ต้องการควบคุมระบบจ่ายน้ำ หรือเก็บข้อมูลอุณหภูมิ ความชื้น ค่า PH/EC ของดินหรือสารละลาย แล้วส่งข้อมูลมาที่ส่วนกลางที่อยู่ติดกับพื้นที่ในการวาง ​Sensor Node เหล่านี้
เคสนี้การใช้ Mesh Network เหมาะมาก เพราะได้ประโยชน์ในเรื่องของการคลอบคลุมพื้นที่ที่กว้าง จากการกระจายตัวของ Node แล้วสร้างเป็น Mesh Network โดยที่จุดเชื่อมต่อสุดท้ายอาจอยู่ที่ชายขอบ หรือศูนย์กลางของ Mesh Network ก็จะเหมาะมาก สามารถลดต้นทุนในเรื่องของการสร้าง Network สำหรับการสื่อสารของแต่ละ Node ได้

 

Scenario 2: Falling Rock Alarm
สำหรับเคสนี้เป็นเคสจริงที่ใต้หวัน ที่ใช้ในการตรวจสอบหินที่ถล่มจากภูเขา เนื่องจากไต้หวันนั้นมีสภาพภูมิประเทศเป็นเกาะ และอยู่ในเขตแผ่นดินไหว ซึ่งถนนบางเส้นนั้นก็ตัดผ่านภูเขาเหมือนแถบภาคเหนือของประเทศไทย ซึ่งบางครั้งก็จะมีหินร่วงหล่นลงมา กว่าจะทราบเหตุก็ต้องมีคนโทรแจ้งจากที่ไปเจอ
ภาพประกอบจาก: https://www.geostru.eu/rockfall-analysis/
ซึ่งที่ใต้หว้นได้มีการติดตั้งเซนเซอร์ตรวจจับการสั่นสะเทือนของแนวตะข่ายกันหินตกตามถนนไว้ เพื่อตรวจจับว่ามีหินร่วงหล่นลงมา หรือมีดินสไลด์ลงมาปิดถนนมั้ยโดยการใช้การสื่อสารแบบ LoRa  เพราะการตรวจจับไม่ได้ตรวจตลอดทั้งแนว เฉพาะบางช่วงที่ตัดผ่านภูเขา และต้องการส่งข้อมูลระยะไกล LoRa จึงตอบโจทย์ดี ฉะนั้นเคสลักษณะแบบนี้ เราก็สามารถเอา Mesh Network มาทำงานร่วมกับ LoRa ได้ โดยที่ Sensor Node สามารถติดเป็นบริเวณที่กว้างขึ้นได้โดยมีต้นทุนที่ต่ำ และส่งข้อมูลแจ้งเตือนไปที่ศูนย์แจ้งเตือนด้วยการ Bridge ผ่าน LoRa ที่อาจอยู่ไกลออกไปหลายกิโล ถ้าเมืองไทยใครมีโครงการทำก็ดีมากเลยครับ ปีที่แล้วขับรถไปดอยตุงที่เชียงรายช่วงหน้าฝน ก็เจอถนนปิดไปครึ่งเลนเป็นบางช่วงอยู่เหมือนกัน ถ้าเรารู้ล่วงหน้าก็จะสามารถวางแผนการเดินทางหรือหลีกเลี่ยงเส้นทางได้ถูก

 

Scenario 3: Smart Bin
เคสนี้ก็เป็นเคสที่เกิดขึ้นจริงอีกเช่นกัน ลองคิดดูถึงเรื่องการเก็บขยะ ซึ่งในบางหมู่บ้าน ชุมชน ที่ต้องมีรถเก็บขยะวนเข้าไปเก็บทุกวันๆ หรือบางทีวันนึงอาจจะหลายรอบก็ได้ หรือบางทีเข้าไปเก็บ ขยะในถังอาจจะไม่มีเลยก็ได้

ซึ่งเคสนี้ก็มีคนทำเป็น Product Smart Bin ที่มีทั้งตัวบดอัดขยะเพื่อเพื่มพื้นที่การเก็บขยะได้มากขึ้น มีตัว Monitor ระดับของขยะเพื่อส่งคำสั่งไปแจ้งเตือนที่ศูนย์ว่าให้มาเก็บขยะได้แล้ว รวมถึงจัดเส้นทางให้รถเก็บขยะได้ด้วย ซึ่งเทคโนโลยีการสื่อสารที่ใช้โดยมากก็จะเป็น LoRa หรือไม่ก็ Cellular (2G, 3G, NB-IoT) เพราะด้วยลักษณะการตั้งวางถังขยะของหมู่บ้าน หรือชุมชนใน ตปท อาจไม่เหมาะกับการนำ mesh มาใช้

 

Wiring & Diagram
ความจริงการใช้งานจะใช้งานผ่าน Module SX1278/1276 ของ Ai-Thinker ก็ได้แต่ก็ต้องต่อสายเข้ากับ Breadboard หรือในส่วนของ RFM95W ก็ต้องมาบัดกรีขากันอีก ฉะนั้นตอนนี้เอาง่ายสุดสำหรับผม ก็ใช้บอร์ดสำเร็จรูปที่มาพร้อม ESP32+OLED ของ Heltec/TTGO เลยดีกว่าเพราะว่าทำการ wiring ไว้บน pcb เรียบร้อยแล้ว ซึ่ง pinout ก็จะเป็นดังรูปด้านล่างนี้
ฉะนั้นขาที่ใช้ในการกำหนดการใช้งานจะเป็นดังนี้ ซึ่งขาที่ถูกใช้ไปในการต่อกับ module sx127x บนบอร์ดนั้นก็จะไม่สามารถนำไปใช้งานอย่างอื่นได้
#define SCK     5    // GPIO5  -- SX127x's SCK
#define MISO    19   // GPIO19 -- SX127x's MISO
#define MOSI    27   // GPIO27 -- SX127x's MOSI
#define SS      18   // GPIO18 -- SX127x's CS
#define RST     14   // GPIO14 -- SX127x's RESET
#define DI0     26   // GPIO26 -- SX127x's IRQ(Interrupt Request)

#define BAND 915.2E6 //you can set band here directly,e.g. 868E6,915E6

 

ติดตั้ง Arduino core for ESP32 WiFi chip

ขั้นตอนนี้อาจแตกต่างไปจากตอนที่เราติดตั้ง ESP8266, ATTiny85 หรือ STM32 F103C Series ไปจากตอนก่อนหน้านี้ ซึ่ง Source ที่ใช้ในการติดตั้งมีอยู่ 2 แหล่งด้วยกันคือ

จาก Espressif ผู้ผลิตชิป ESP32

https://github.com/espressif/arduino-esp32#installation-instructions

 

จาก Heltec ผู้ผลิตบอร์ด Heltec ESP32 LoRa

https://github.com/Heltec-Aaron-Lee/WiFi_Kit_series#installation-instructions

 

ข้อแตกต่างระหว่างสองบอร์ดนี้ก็คือ ถ้า Clone มาจาก Heltec จะมี Library LoRa มาด้วยซึ่งก็เป็นตัวที่โมมาจากของคุณ Sandeep Mistry แต่ถ้ากรณีมีการ Update ก็จะไม่ถูก Update ผ่านทาง Library manager ต้องคอยตามจากทาง Heltec เอง ผมเลยเลือก Clone มาจากทาง Espressif แล้วทำการติดตั้ง LoRa Library เอง ส่วนวิธีการติดตั้งก็ขึ้นกับ OS ของแต่ละท่านที่ใช้อยู่ หลังจากตัดสินใจเลือกทางได้แล้วก็อาศัยลิงค์ข้างบนนี่แหละครับทำตาม Instruction ในแต่ละ OS ได้เลย

 

LoRa Library by Sandeep Mistry
สำหรับใครที่เลือกติดตั้ง Board โดยเลือก Source จาก Heltec ก็ข้ามขั้นตอนติดตั้ง Library นี้ไปได้เลยครับ แต่ถ้าใครที่ติดตั้งผ่าน Source ของ Espressif ก็ให้ติดตั้ง LoRa Library ของคุณ Sandeep Mistry โดยเข้าไปที่ Sketch –> Include Library –> Library Manager แล้วค้นหาคำว่า LoRa ครับ จะเจอหลายตัวมากให้เลือกตามรูปด้านล่างแล้วกด Install ได้เลยครับ

มาดูในส่วนของ Code ที่จะใช้ทดสอบระยะกันบ้าง ตัวโปรแกรมก็จะแบ่งเป็นสองชุดคือฝั่งส่งและฝั่งรับ ฝั่งส่งก็ Count Number แล้วส่งออกไปเรื่อยๆ ส่วนฝั่งรับนั้นเนื่องด้วยไม่มี GPS Module ก็เลยอาศัย GPS Stream จาก Blynk มาใช้ในการเก็บค่าพิกัดแทน เพื่อที่จะได้มา plot ดูว่าได้ระยะเป็นอย่างไรบ้าง ซึ่งถ้าใช้บอร์ดที่ใช้ชิป SX1278 ในส่วนของ Band จะกำหนดเป็น 433.175MHz และถ้าเป็นบอร์ดที่ใช้ชิป SX1276 ในส่วนของ Band จะกำหนดเป็น 923.2MHz นอกนั้นไม่มีอะไรแตกต่าง ส่วนใครที่จะทดสอบโดยที่ไม่ได้สนใจเรื่องของ พิกัดก็ตัด code ในส่วนของ Blynk ออกได้ครับ

 

Code for Sender:

#include <SPI.h>
#include <LoRa.h>
#include "SSD1306.h"

int counter = 0;


// GPIO5  -- SX1278's SCK
// GPIO19 -- SX1278's MISO
// GPIO27 -- SX1278's MOSI
// GPIO18 -- SX1278's CS
// GPIO14 -- SX1278's RESET
// GPIO26 -- SX1278's IRQ(Interrupt Request)

//OLED pins to ESP32 0.96OLEDGPIOs via this connecthin:
//OLED_SDA -- GPIO4
//OLED_SCL -- GPIO15
//OLED_RST -- GPIO16

SSD1306  display(0x3c, 4, 15);

#define SS      18
#define RST     14
#define DI0     26
#define BAND    433.175E6  //915E6

void setup() {
  Serial.begin(115200);

  pinMode(25, OUTPUT); //Send success, LED will bright 1 second

  while (!Serial);

  pinMode(16, OUTPUT);
  digitalWrite(16, LOW);    // set GPIO16 low to reset OLED
  delay(50);
  digitalWrite(16, HIGH); // while OLED is running, must set GPIO16 in high

  Serial.println("LoRa Sender");

  SPI.begin(5, 19, 27, 18);
  LoRa.setPins(SS, RST, DI0);

  if (!LoRa.begin(BAND)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }

  Serial.println("LoRa Initial OK!");

  // Initialising the UI will init the display too.
  display.init();
  display.flipScreenVertically();
  display.setFont(ArialMT_Plain_10);
}

void loop() {
  Serial.print("Sending packet: ");
  Serial.println(counter);

  // send packet
  LoRa.beginPacket();
  LoRa.print("hello ");
  LoRa.print(counter);
  LoRa.endPacket();

  display.clear();
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.drawString(10, 5, "Sending:");
  display.drawString(10, 20, "hello " + String(counter));
  // write the buffer to the display
  display.display();

  counter++;
  digitalWrite(25, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(25, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second

  delay(5000);
}

 

 

Code for Receiver:

#include <SPI.h>
#include <LoRa.h>
#include "SSD1306.h"

/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial

#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>

char auth[] = "xxxxxxxxx"; //blynk auth code

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "xxx xxxx";
char pass[] = "xxxx";

float lat;
float lon;



// GPIO5  -- SX1278's SCK
// GPIO19 -- SX1278's MISO
// GPIO27 -- SX1278's MOSI
// GPIO18 -- SX1278's CS
// GPIO14 -- SX1278's RESET
// GPIO26 -- SX1278's IRQ(Interrupt Request)

//OLED pins to ESP32 0.96OLEDGPIOs 
//OLED_SDA -- GPIO4
//OLED_SCL -- GPIO15
//OLED_RST -- GPIO16

SSD1306  display(0x3c, 4, 15);

#define SS      18
#define RST     14
#define DI0     26
#define BAND    433.175E6  //915E6

WidgetMap myMap(V1);


BLYNK_WRITE(V0) {
  GpsParam gps(param);

  // Print 6 decimal places for Lat, Lon


  lat = String(gps.getLat(),6).toFloat();
  lon = String(gps.getLon(),6).toFloat();
  
  Serial.print("Lat: ");
  Serial.println(lat,7);
 

  Serial.print("Lon: ");
  Serial.println(lon,7);

  Serial.println();
}

void setup() {
  Serial.begin(115200);
  while (!Serial);

  pinMode(16, OUTPUT);
  digitalWrite(16, LOW);    // set GPIO16 low to reset OLED
  delay(50);
  digitalWrite(16, HIGH); // while OLED is running, must set GPIO16 in high

  Serial.println("LoRa Receiver");

  SPI.begin(5, 19, 27, 18);
  LoRa.setPins(SS, RST, DI0);

  if (!LoRa.begin(BAND)) {
    Serial.println("Starting LoRa failed!");
    while (1);

  }
  Serial.println("LoRa Initial OK!");

  // Initialising the UI will init the display too.
  display.init();
  display.flipScreenVertically();
  display.setFont(ArialMT_Plain_10);

  Blynk.begin(auth, ssid, pass);

  myMap.clear();
  
}


void loop() {
  String tmp_string, tmp_rssi;
  
  // try to parse packet
  int packetSize = LoRa.parsePacket();
  if (packetSize) {
    // received a packet
    Serial.print("Received packet '");

    // read packet
    while (LoRa.available()) {
      //Serial.print((char)LoRa.read());
      tmp_string += (char)LoRa.read();      
    }

    Serial.print(tmp_string);
    
    tmp_rssi = LoRa.packetRssi();
    
    // print RSSI of packet
    
    
    Serial.println("' with RSSI " + tmp_rssi);
    
    //Serial.println(LoRa.packetRssi());

    display.clear();
    display.setTextAlignment(TEXT_ALIGN_LEFT);
    display.drawString(10, 0, "Received:");
    display.drawString(10, 15, tmp_string+" RSSI: "+tmp_rssi);
    display.drawString(10, 30, String(lat,7));
    display.drawString(10, 45, String(lon,7));
    // write the buffer to the display
    display.display();

    //BLYNK_WRITE(V0);
    Blynk.syncVirtual(V0);
    myMap.location(1, lat, lon, "value");
    
  }
  tmp_string ="";
  tmp_rssi = "";

  Blynk.run();
  
}

 

LoRa Range Test Result: 433.175MHz vs 923.2MHz

เริ่มกันที่จุด Start วางคู่กัน โดยใช้ความถี่ในการรับ-ส่ง ที่ 433.175MHz ได้พิกัดมาเรียบร้อย

 

หลังจากนั้นก็เดินเล่นเลยครับ เล่นเอาเหงื่อตกเหมือนกัน RSSI: -107dBm

 

ค่าต่ำสุดที่ Heltec ESP32 LoRa Sx1278 รับได้จะอยู่ที่ -108 dBm

 

ในความโชคร้ายยังพอมีโชคดีอยู่บ้าง ถึงแม้ตัว Heltec ESP32 LoRa SX1276 ที่ใช้งานย่าน 915MHz จะเสียแต่ก็ได้บอร์ดใหม่มาทันพอให้ทดสอบ ซึ่งเป็นของ TTGO เป็น ESP32 LoRa SX1276 เหมือนกันเพียงแต่แค่ไม่มี OLED มาด้วยเท่านั้น ฉะนั้นการวัดระยะ และค่า RSSI ก็เลยอาศัยอ่านค่า GPS จาก App Blynk บนโทรศัพท์มือถือแทน

TTGO ESP32 LoRa SX1276

 

Semtech SX1276: LoRa ชิป ย่าน 915MHz

 

ซึ่งการทดสอบสำหรับการรับ-ส่งที่ความถี่ 923.2MHz ค่า RSSI ที่สามารถรับได้ต่ำสุดและรับได้ต่อเนื่องอยู่ที่ระหว่าง -110 ถึง -117 dBm

 

ผลการทดสอบระยะของแต่ละความถี่ที่ใช้ก็ตามรูปด้านบนเลยครับ ซึ่งถ้าเอาระยะหวังผลไกลสุดซึ่งอยู่ใน Line of Sight ก็จะอยู่ที่ประมาณ 700-750 เมตรสำหรับการรับ-ส่งที่ความถี่ 923.2MHz ส่วนคลื่น 433.175MHz ระยะหวังผลก็จะอยู่ที่ประมาณ 600 เมตร ทำให้การใช้งาน LoRa นั้นค่อนข้างสมชื่อ Long Range เลย เพราะนี่คือใช้สายอากาศที่แถมมา ถ้าใช้สายอากาศดีๆ และตั้งเสาสูงน่าจะไปได้ไกลกว่านี้ แต่ทั้งนี้ทั้งนั้นกำลังส่งก็ไม่ควรเกิน กสทช กำหนดนะครับ ซึ่งเคสที่เขียนนี้ “สำหรับการทดลองเท่านั้น” เพราะจาก Code ได้มีการกำหนด TX Power ไว้ที่ 17dBm บวกกับเสาที่แถมมาน่าจะไม่เกิน +3dBm ตีกลมๆก็ 20dBm หรือ 100 milliwatts แล้ว (แต่ส่วนตัวคิดว่าไม่น่าจะถึง น่าจะมี loss เยอะ ถ้าอยากรู้จริงๆคงต้องเอาอุปกรณ์มาวัด)

 

Painlessmesh Bridge with Lora

เกริ่นมาซะยาวสุดๆก่อนที่จะเข้าเรื่องของเรากันจริงๆในการใช้ Painlessmesh สร้าง Mesh Network และ Bridge ข้อมูลผ่าน LoRa กัน ซึ่ง Configuration ก็จะเป็นลักษณะดัง diagram ด้านล่างนี้ครับ โดยมี Heltec ESP32 Lora SX1278 เป็นตัว Bridge เพื่อส่งข้อมูลไปยัง MQTT Server

 

เพิ่งเห็นว่ามี Dependency Library เพิ่มเข้ามาสำหรับ Painlessmesh อีกตัวคือ AsyncTCP  สำหรับ ESP32 และ ESPAsyncTCP สำหรับ ESP8266 ถ้าใคร Update เป็น version ล่าสุดของ Painlessmesh ก็อย่าลืมติดตั้งเพิ่มเข้าไปนะครับ

สำหรับ ESP32
https://github.com/me-no-dev/AsyncTCP


สำหรับ ESP8266

https://github.com/me-no-dev/ESPAsyncTCP

 

Nodemcu + DHT22 (mcu-t1, mcu-t2, mcu-t3)

Code:

#include "painlessMesh.h"
#include "DHT.h"
#define DHTPIN D4
#define DHTTYPE DHT22
#define   MESH_PREFIX     "HelloMyMesh"
#define   MESH_PASSWORD   "hellomymeshnetwork"
#define   MESH_PORT       5555
DHT dht(DHTPIN, DHTTYPE);

void receivedCallback( uint32_t from, String &msg );

painlessMesh  mesh;
size_t logServerId = 0;
// Send message to the logServer every 10 seconds
Task myLoggingTask(10000, TASK_FOREVER, []() {

  float h = dht.readHumidity();
  float t = dht.readTemperature();

  DynamicJsonBuffer jsonBuffer;
  JsonObject& msg = jsonBuffer.createObject();
  msg["nodename"] = "mcu-t1";  //change for identify for the node that send data mcu-t1 to mcu-t3
  msg["NodeID"] = mesh.getNodeId();
  msg["Temp"] = String(t) + "C";
  msg["Humidity"] = String(h) + "%";
  String str;
  msg.printTo(str);
  if (logServerId == 0) // If we don't know the logServer yet
    mesh.sendBroadcast(str);
  else
    mesh.sendSingle(logServerId, str);
  // log to serial
  msg.printTo(Serial);
  Serial.printf("\n");
});

void setup() {
  Serial.begin(115200);
  Serial.println("Begin DHT22 Mesh Network test!");
  dht.begin();
  mesh.setDebugMsgTypes( ERROR | STARTUP | CONNECTION );  // set before init() so that you can see startup messages
  mesh.init( MESH_PREFIX, MESH_PASSWORD, MESH_PORT, STA_AP, AUTH_WPA2_PSK, 6 );
  mesh.onReceive(&receivedCallback);
  // Add the task to the mesh scheduler
  mesh.scheduler.addTask(myLoggingTask);
  myLoggingTask.enable();
}

void loop() {
  // put your main code here, to run repeatedly:
  mesh.update();
}

void receivedCallback( uint32_t from, String &msg ) {
  Serial.printf("logClient: Received from %u msg=%s\n", from, msg.c_str());
  // Saving logServer
  DynamicJsonBuffer jsonBuffer;
  JsonObject& root = jsonBuffer.parseObject(msg);
  if (root.containsKey("topic")) {
    if (String("logServer").equals(root["topic"].as<String>())) {
      // check for on: true or false
      logServerId = root["nodeId"];
      Serial.printf("logServer detected!!!\n");
    }
    Serial.printf("Handled from %u msg=%s\n", from, msg.c_str());
  }
}

 

 

Heltec ESP32 SX1276 (Server Node + LoRa)

Code:

#include "painlessMesh.h"
#include <SPI.h>
#include <LoRa.h>
#include "SSD1306.h"

// GPIO5  -- SX1278's SCK
// GPIO19 -- SX1278's MISO
// GPIO27 -- SX1278's MOSI
// GPIO18 -- SX1278's CS
// GPIO14 -- SX1278's RESET
// GPIO26 -- SX1278's IRQ(Interrupt Request)
//OLED pins to ESP32 0.96OLEDGPIOs :
//OLED_SDA -- GPIO4
//OLED_SCL -- GPIO15
//OLED_RST -- GPIO16


#define   MESH_PREFIX     "HelloMyMesh"
#define   MESH_PASSWORD   "hellomymeshnetwork"
#define   MESH_PORT       5555

SSD1306  display(0x3c, 4, 15);
#define SS      18
#define RST     14
#define DI0     26
#define BAND    433.175E6  //915E6

painlessMesh  mesh;
// Send my ID every 10 seconds to inform others

Task logServerTask(10000, TASK_FOREVER, []() {
  DynamicJsonBuffer jsonBuffer;
  JsonObject& msg = jsonBuffer.createObject();
  msg["topic"] = "logServer";
  msg["nodeId"] = mesh.getNodeId();
  String str;
  msg.printTo(str);
  mesh.sendBroadcast(str);
  // log to serial
  msg.printTo(Serial);
  Serial.printf("\n");
});


void setup() {


  Serial.begin(115200);

  pinMode(25, OUTPUT); //Send success, LED will bright 1 second

  while (!Serial);

  pinMode(16, OUTPUT);
  digitalWrite(16, LOW);    // set GPIO16 low to reset OLED
  delay(50);
  digitalWrite(16, HIGH); // while OLED is running, must set GPIO16 in high


  Serial.println("LoRa PainlessMesh Server");

  SPI.begin(5, 19, 27, 18);
  LoRa.setPins(SS, RST, DI0);
  if (!LoRa.begin(BAND)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }

  Serial.println("LoRa Initial OK!");
  // Initialising the UI will init the display too.
  display.init();
  display.flipScreenVertically();
  display.setFont(ArialMT_Plain_10);

  display.clear();
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.drawString(10, 5, "Mesh Server Node:");
  display.display();



  mesh.setDebugMsgTypes( ERROR | CONNECTION | S_TIME );
  mesh.init( MESH_PREFIX, MESH_PASSWORD, MESH_PORT, STA_AP, WIFI_AUTH_WPA2_PSK, 6 );
  mesh.onReceive(&receivedCallback);
  mesh.onNewConnection([](size_t nodeId) {
    Serial.printf("New Connection %u\n", nodeId);
  });
  mesh.onDroppedConnection([](size_t nodeId) {
    Serial.printf("Dropped Connection %u\n", nodeId);
  });
  // Add the task to the mesh scheduler
  mesh.scheduler.addTask(logServerTask);
  logServerTask.enable();
}


void loop() {
  mesh.update();
}


void receivedCallback( uint32_t from, String &msg ) {
  
  String tmp_string = msg.c_str();
  
  Serial.printf("logServer: Received from %u msg=%s\n", from, tmp_string);
  
  Serial.println("");
  Serial.println("Sending LoRa packet: "+tmp_string);
  
  
  //เมื่อได้รับข้อความจากใน mesh network ก็ส่งต่อผ่านไปยัง LoRa
  LoRa.beginPacket();
  LoRa.print(tmp_string);
  LoRa.endPacket();
  
  display.clear();
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.drawString(10, 5, "Sending: "+tmp_string.substring(13,19));
  display.drawString(10, 20, "Temp: "+tmp_string.substring(49,55));
  display.drawString(10, 35, "Humid: "+tmp_string.substring(69,75));
  // write the buffer to the display
  display.display();


}

 

Heltec ESP32 SX1276 (Gateway Node + LoRa)

Code:

#include <SPI.h>
#include <LoRa.h>
#include "SSD1306.h"

#include <WiFi.h>
#include <WiFiClient.h>
#include <PubSubClient.h>



const char* ssid = "xxxWiFi-SSID";
const char* password = "xxxWiFi Password";
const char* mqtt_server = "xxx.xxx.xxx.xxx"; //<-- IP หรือ Domain ของ Server MQTT

long lastMsg = 0;
char msg[100];
int value = 0;

WiFiClient espClient;

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

}



PubSubClient client(mqtt_server, 1883, callback, espClient);




// GPIO5  -- SX1278's SCK
// GPIO19 -- SX1278's MISO
// GPIO27 -- SX1278's MOSI
// GPIO18 -- SX1278's CS
// GPIO14 -- SX1278's RESET
// GPIO26 -- SX1278's IRQ(Interrupt Request)
//OLED pins to ESP32 0.96OLEDGPIOs
//OLED_SDA -- GPIO4
//OLED_SCL -- GPIO15
//OLED_RST -- GPIO16
SSD1306  display(0x3c, 4, 15);
#define SS      18
#define RST     14
#define DI0     26
#define BAND    433.175E6  //915E6

void setup() {
  Serial.begin(115200);

  while (!Serial);
  pinMode(16, OUTPUT);
  digitalWrite(16, LOW);    // set GPIO16 low to reset OLED
  delay(50);
  digitalWrite(16, HIGH); // while OLED is running, must set GPIO16 in high
  Serial.println("LoRa Receiver");

  SPI.begin(5, 19, 27, 18);
  LoRa.setPins(SS, RST, DI0);
  if (!LoRa.begin(BAND)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
  Serial.println("LoRa Initial OK!");
  // Initialising the UI will init the display too.

  display.init();
  display.flipScreenVertically();
  display.setFont(ArialMT_Plain_10);

  setup_wifi();
  client.connect("ESP32Gateway", "joe1", "joe1");
  client.setCallback(callback);
  client.subscribe("command");



}

void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  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 reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("ESP32Gateway")) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("outTopic", "hello world");
      // ... and resubscribe
      client.subscribe("command");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void loop() {
  String tmp_string, tmp_rssi;

  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  // try to parse packet
  int packetSize = LoRa.parsePacket();

  if (packetSize) {
    // received a packet
    Serial.print("Received packet '");
    // read packet
    while (LoRa.available()) {
      //Serial.print((char)LoRa.read());
      tmp_string += (char)LoRa.read();
    }
    Serial.print(tmp_string);

    tmp_rssi = LoRa.packetRssi();

    // print RSSI of packet


    Serial.println("' with RSSI " + tmp_rssi);


    display.clear();
    display.setTextAlignment(TEXT_ALIGN_LEFT);
    display.drawString(10, 0, "Received:");
    display.drawString(10, 15, "From: " + tmp_string.substring(13, 19) + " RSSI: " + tmp_rssi);
    display.drawString(10, 30, "Temp: " + tmp_string.substring(49, 55));
    display.drawString(10, 45, "Humid: " + tmp_string.substring(69, 75));
    // write the buffer to the display
    display.display();

    tmp_string.toCharArray(msg, 100);
    Serial.print("Publish message: ");
    Serial.println(msg);
    client.publish("env", msg);  //ส่งข้อความ Temp + Humidity ออกไปที่ Topic "env"


  }
  tmp_string = "";
  tmp_rssi = "";


}

 

ผลลัพท์ที่ได้

ถ้าทำตามขั้นตอนที่ว่ามาทั้งหมดได้ ถึงบรรทัดนี้แล้วผลที่ได้ก็จะเป็นอย่างในคลิปด้านล่างนี้แหละครับ mcu-t1, mcu-t2, mcu-t3 จะอ่านค่าจาก DHT22 แล้วส่งผ่าน Mesh Network ไปยัง Server Node: Heltec ESP32 LoRa SX1278 จากนั้นเมื่อ Server Node ได้รับข้อความผ่านทาง Mesh Network ก็เอาข้อความนั้นส่งต่อผ่านไปยัง LoRa

 

ในอีกฟากหนึ่ง Gateway Node: Heltec ESP32 LoRa SX1278 เมื่อได้รับข้อความจาก LoRa ก็จะเอาข้อความนั้น Publish ต่อไปยัง MQTT Server ที่เราได้สร้างกันไว้ตั้งแต่ตอนที่ 3.5 ถ้าดูจากคลิปวีดีโอจะเห็นว่าระยะเวลาที่ใช้นั้นค่อนข้างเร็วมาก ซึ่งหลังจากนี้การจะนำข้อมูลจากภายใน Mesh Network ไปใช้งานก็ง่ายแล้ว จะเขียนลง Time Series Database เพื่อเอาไปแสดงผล หรือวิเคราะห์ข้อมูลต่อก็ไม่ยากแล้ว

 

สรุป

เนื้อหาในตอนนี้จะเน้นในเรื่องของ Data Communication อีกรูปแบบหนึ่งนั่นก็คือ LoRa ในการนำมาใช้งานร่วมกับ Mesh Network ซึ่งอย่างที่เกริ่นไปตอนแรกอะครับ ถ้าผ่านตอนที่ 3 มาแล้วก็ขึ้นอยู่กับเราว่าจะไป bridge กับอะไรเพื่อส่งต่อข้อมูลภายใน Mesh Network ไปยังอีก Network หนึ่ง ถ้าตัว Server Node ของเราต่อเข้ากับ Ethernet Module ENC28J60 ก็สามารถเป็น Bridge ในตัวมันเองได้เลยโดยส่งข้อมูลผ่านสาย Lan ก็ได้ ดังนั้นที่เขียนมายาวหลายตอนมากก็เพื่ออยากให้เข้าใจหลักการณ์ก่อน ที่เหลือก็จะขึ้นอยู่กับการประยุกต์ใช้ให้เหมาะสมนั่นเองครับ ใช่ว่าจำเป็นจะต้องใช้งาน ​Mesh Network สำหรับงาน IoT ทุกเคส หรือว่าจำเป็นต้องใช้งาน LoRa เพื่อให้ได้ระยะไกลๆ บางครั้งต่อพ่วงอุปกรณ์ของเราเข้ากับ GPRS/LTE Module ก็อาจจะทำให้ไปได้ไกลกว่าถึงชายขอบของผู้ให้บริการมือถือได้เลยด้วยซ้ำ ไกลกว่า NB-IoT ตอนนี้ด้วย

ส่วนในตอนหน้าที่น่าจะเป็นตอนสุดท้ายของ Series เรื่อง ESP8266/ESP32 กับ Painlessmesh ก็จะเป็นตอนปลีกย่อยละ เพราะในตอนที่ 3.5  ได้สอนในเรื่องของการติดตั้ง MQTT Server บน Google Cloud ไปแล้ว ก็คงปิด ​Series ด้วยการใช้งาน Telegraf, InfluxDB และ Grafana ไปเลย เพื่อที่จะทำให้ข้อมูลที่ไหลมาจาก Sensor Node ต่างๆ ไปอยู่ในรูปของ Data Visualization ที่สวยงามและเข้าใจง่าย

 

เรื่องเล่าท้ายตอน

ตอนนี้เป็นตอนที่ใช้พลังงานและเวลาในการเขียนเยอะมากจริงๆ ทั้งเรื่องการรออุปกรณ์ งานที่ทำอยู่ คลาสเรียนที่เพิ่มเข้ามา ต้องเขียนสารนิพนธ์ด้วย ยังไม่รวมถึงวันศุกร์ที่จะถึงนี้จะมีการประชุมผู้ถือหุ้น อีก T_T แต่เอาจริงๆเขียนเล่าเรื่องพวกนี้ก็สนุกดีเหมือนกันได้ทบทวนสิ่งที่ตัวเองได้ทดลองทำมา มีคนถามว่าเขียนแล้วได้อะไร อย่างแรกเลยก็คงเอาไว้เป็น Reference เพื่อไว้ทบทวนนั่นแหละครับเพราะไม่งั้นผ่านไปนานๆจำไม่ได้แน่ๆว่าตอนนั้นเราทำยังไง ขั้นตอนไหนก่อนหลัง แล้วก็เมื่อมีคนรู้เรื่องพวกนี้มากๆเราก็จะสนุกมากขึ้น มีคนถาม มีคนศึกษา มีคนทดลองต่อ บางคนเอาไปต่อยอดแล้วก็มาพูดคุยกัน เพราะจริงๆแล้วเราไม่ได้รู้ทุกๆเรื่อง บางเรื่องที่เขียนผมอาจจะเขียนไม่ถูกก็ได้ หรือบางท่านหลังไมค์หัวข้อมาให้เขียนก็ถ้ามีโอกาสก็จะไปหาข้อมูลมาแชร์กัน วันนี้ก็ขอจบตอนนี้ก่อนละกันครับ

Author: Joe D.S.
Just a man on earth

7 thoughts on “ESP8266 / ESP32 & Mesh Network ตอนที่ 4: Painlessmesh Bridge with LoRa

  1. Congratulations and thank you for sharing !!!
    I will try to replicate and then use an ultrasonic sensor

  2. ขอบคุณสำหรับบทความที่ดี

    ได้อ่านบทนี้ถือว่ามีค่ามาก ผมกำลังออกแบบ ระบบวัดความชื้นในสวนกล้วยไม้ มีพื้นที่เกือบ 20 ไร่ ปัญหาของเราเริ่มจากระยะ wifi ที่ไปไม่ถึง mcu ปลายสวนคิดมานานว่าจะแก้อย่างไร มาบรรเจิดมากที่ได้อ่านเกี่ยวกับ การใช้งาน LoRa ซึ่งวิเคราะห์แล้วว่าถือเป็นทางออกที่สวยงามอย่างยิ่งครับ รวมทั้งประหยัดต้นทุนด้วย

  3. ไม่ทราบว่า..จะนำ Lora มาทำในส่วน Mesh network แทนที่ wifi จะเป็นไปได้หรือเปล่าครับ???..

    1. ได้ครับ แต่จะไม่ค่อยเหมาะ เพราะมันจะจองข่องสัญญาณการส่งตลอดเวลา ลองค้น lora mesh ดูครับ

  4. ขอบคุณสำหรับบทความดีๆครับ ตอนนี้ทดลองทำตาม Node ทั้ง 3 ตัว สามารถส่งค่ามายัง Gateway ได้แล้ว ทีนี้อยากนำค่าอุณหภูมิที่ node ทั้งสามตัวส่งมาขึ้นเว็บแสดงผล UI เป็นตัว Gauge โดยเป็นคนละตัวกัน พอมีคำแนะนำในการเขียนโค้ดส่วนนี้บ้างมั้ยครับ ทดลองแล้วคือค่าอุณหภูมิจะถูกส่งเข้ามาที่ Gauge ตัวเดียวกันตลอด ไม่รู้จะดึงค่าทั้ง 3 ตัวแยกออกจากกันยังไง เพราะเหมือนว่าจะส่งมาตำแหน่งเดิมสลับๆกันครับ

    1. ก็ต้อง Identify ให้ได้ว่า Node3ตัวที่ว่า อาจมี ID ที่ต่างกัน ฉะนั้นข้อมูลที่ส่งมาก็ควรมี ID ของ Node ติดมาด้วย พอเอาไปแยกสแกน ก็แค่เขียน Code Filter ในการเลือกแสดงของแต่ละ Node ID ก็น่าจะได้ครับ

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.