ลองเล่น AIS NB-IoT Shield ครั้งแรก
หลังจากที่ได้รับ NB-IoT Shield มาจากคุณหมอจิมมี่ ก็รับมาลองเล่นว่าจะทำอะไรกับมันได้บ้าง ช่วงนั้นก็ราวๆต้นธันวาคมก่อนงาน Chiang Mai Maker Party 4.0
ในช่วงวันงานก็มี Pre-Order NB-IoT Shield ครั้งขึ้นมาเป็นครั้งแรกด้วย โอ้โห เท่ชะมัด… ไอ้ที่พิมพ์ยาวๆ งงๆ มานี่ก็คือตั้งสติอยู่ครับว่าจะเขียนยังไงดี 555
คำเตือน.. 1. บทความนี้ไม่มีสาระมากนัก ไม่ใช่ tutorial และอย่าคาดหวังอะไรเยอะครับ.. ไว้บทความอื่นๆจะตามมาครับ บทความนี้ก็เลยเป็น overview กันไปก่อนครับ 55555552. ผมไม่มี official ของที่ใดเลย... ข้อมูล Specification ทั้งหมด Search มาจาก Google ครับ
เอาล่ะครับ.. เริ่มกันเรื่องสถานที่สำหรับทดสอบ AIS NB-IoT Shield ก่อน
นั่นก็คือที่ Chiang Mai Maker Club นั่นแหละครับ เนื่องจากทาง AIS มาเปิดสัญญาณให้ที่แถวๆชมรมครับ มีอีกที่ก็.. Chiang Mai Maker Party ที่ศูนย์แสดงสินค้าครับ
สิ่งแรกที่ทำเมื่อได้รับ Shield
ก็คิดก่อนว่าทำอะไรกับมันดีใช่ไหมล่ะครับ?… ปกติผมมีแนวคิดในการออกแบบ Applicationให้ไม่อิงกับเครือข่ายการส่งข้อมูลอยู่เลย… จะเป็น WiFi / NB-IoT / LoRa ก็วิ่งได้หมด… ดังนั้นก็เลยมีโค๊ดส่วนนึงเอาไว้ให้ใช้ได้เลยครับ
ตอนได้ Shield มาใหม่ๆ ก็คิดไม่ออกว่าจะทำอะไรดี… มันเบื่อๆขี้เกียจทำซ้ำๆ…
คิดไม่ตก…..
งั้น..สิ่งแรกที่ผมทำก็คงเป็นไปสุดสะแนนครับ… พกสมุดไปเล่มนึง… ปากกาสักสองสีแบบ Pigment ink.. แล้วก็อาหารโปรด เพลงโปรด… แล้วเติมเบียร์อีกสักหน่อย…
แล้วเป็นไง… สุดท้าย… เมาก่อนครับ (อย่าเอาเป็นเยี่ยงอย่างครับ 555),
โถ.. พิมพ์มาตั้งยืดยาว หาสาระยังไม่ได้อีก!!!
ESPresso Lite + NB-IoT Shield
แล้ววันรุ่งขึ้นผมก็รู้ว่าลางๆเราจะทำอะไรกับมันดี.. โอ้โห… ได้ผลสุดๆ 555
เริ่มต้นเล่น NB-IoT Shield
ผมก็เลยเริ่มจากเช็คดูก่อนครับว่า Library ติดต่อกับบอร์ด NB-IoT ยังไง และตัว Arduino Library รองรับบอร์ดอะไรบ้างบน Arduino IDE ก็ได้คำตอบว่า… UNO ครับ และมีการใช้ AltSoftSerial.h
เพื่ออิสรภาพของการเขียนโปรแกรม และ explore โค๊ดใน Library ได้อย่างรวดเร็ว.. เราจะใช้ Arduino Mega ตั้งแต่โปรเจ็คแรก… และใช้ Hardware Serial คุยกับ NB-IoT Shield และ GPS … คิดภาพเอาไว้ว่า.. ต้องทำ IoT Gateway ด้วย NB-IoT มันก็เลยยังไม่พอเท่านี้ครับ!!!
NB-IoT Gateway แบบจัดหนัก.. จัดเต็ม!
เท่าที่ว่าไปข้างบนยังจัดหนักจัดเต็มไม่พอ… ผมก็เลยเพิ่ม ESP8266 ที่เป็น ESPNow Gateway เข้ามาอีกชั้นนึง… ซึ่งตัวนี้จะมีลูกๆอีก 4–6 ตัวยิงตัวยิงเข้ามาเรื่อยๆ
ESP8266 ตัวนั้นก็จะส่งข้อมูลมาให้ NB-IoT Gateway ของเราที่รันเป็น Arduino Mega อยู่นั่นเองครับ.. (คุยกันผ่าน HW Serial อีกช่อง) จัดเต็มกันที่ HW กันไปเลย เท่ากับว่าตอนนี้… เราใช้ Hardware Serial ทั้งหมด 3 ตัว จาก 3 ตัว… ครบเลย!
- Serial1 สำหน้าที่คุยกับ GPS
- Serial2 ทำหน้าที่คุย NB-IoT Shield
- Serial3 ทำหน้าที่คุยกับ ESP8266 Gateway (ESPNow)
ส่วน software จะใช้ระบบเดิมครับ.. แต่จะมี UDP Server ขึ้นมาสำหรับ Bridge ข้อมูลไปออก MQTT เพื่อสร้างความยืดหยุ่น… แล้วก็ยิงเข้าระบบที่เรามีอยู่…แล้วข้อมูลก็จะไหล BigQuery, InfluxDB และถึงมือ Grafana ในที่สุด
เริ่มลุยโค๊ด…
ก็เริ่มจากการโหลด Library AIS NB_IoT_BC95 มาก่อน แล้วก็ลบ Library AltSoftSerial ทิ้งเป็นอันดับแรก….
หลังจากนั้นก็ถึงคิว Arduino Mega ต้องทำตรง HW เพิ่มนิดนึงโดยจั๊ม Serial2 ไปให้ตรงกับใน AltSoftSerial ซึ่งแต่เดิม Arduino UNO ใช้ Pin 9 และ 8 นั่นเอง
แล้วก็แก้โค๊ดใน AIS_NB-IoT ให้ใช้ Serial2 ซะให้เรียบร้อย…
ออกแบบการส่งข้อมูล
หลังจากนั้นออกแบบ Data Packet แบบจัดเต็มกันไปเลยครับ ส่งข้อมูลจาก Sensor ได้ ไป 40 กว่าช่อง packet ก็หวดไปเลยประมาณ 200bytes (4byte * จำนวน fields) ซึ่งประกอบไปด้วย
- CMMC_SENSOR_T ตัวนี้เป็น Packet จาก Sensor Node ที่ส่งจาก ESP8266 มาที่ ESPNow Gateway ประกอบไปด้วยชื่อ… และ field ข้อมูลทั้งหมด 6 ช่อง มีข้อกำหนดอีกนิดหน่อยก็พวก uuid และ battery อันนี้ผม design ให้เป็นมาตรฐานของ CMMC ครับ
- CMMC_PACKET_T เป็น packet ที่ส่งออกจาก ESP8266 Controller Node รับจากลูกๆมาแล้วหุ้มเป็น packet มีการใส่หัว… และหาง และข้อมูลอีกนิดหน่อยจาก Controller หลังจากนั้นก็ส่งผ่าน SerialPort ไปหา Arduino Mega ของเรา
- CMMC_MASTER_PACKET นี่จะอยู่ที่ Arduino Mega ซึ่งเป็นทุกอย่าง.. ของเธอแล้ว… เก็บ Sensor แบบจัดเต็มมากตามรายละเอียดข้างล่างเลยครับ
IDE ที่เลือกใช้สำหรับโปรเจ็คนี้คือ ใช้ platform-io บน Visual Studio Code และ Atom ครับ เราจะได้แก้ไข Library ต้นทางได้รวดเร็ว… ฉับไว… หน้าตาโปรแกรมเป็นแบบนี้ (source code)
ส่วนแสดงผลข้อมูล
ข้อมูลที่เราเก็บ… เก็บลง time series database ใน Influxdb แสดงผลใน grafana แล้วอีกอันก็เก็บข้อมูลแบบ relational ด้วย Google Big Query
Google Big Query
InfluxDB + Grafana
มาดู Source Code ฝั่ง Server กันบ้าง
ฝั่ง UDP Server ผมเขียนด้วยภาษา NodeJS ครับ ซึ่งใช้ built-in API ของตัวภาษาเลย ไม่ต้องลง Library เพิ่ม
การดูดข้อมูลเข้า Influxdb
ดูจากโค๊ดแล้วเราจะเห็นว่า Data ไหลเข้า Google Big Query (Serverless) ผ่านทาง Google Cloud Function (Serverless) แล้ว Influxdb ล่ะ…
เอาข้อมูลเข้า Influxdb ด้วย Telegraf Configuration หน้าตาแบบนี้ครับ ก็คือใช้ mqtt_consumer ในการดูด topic ที่มี Prefix เป็น CMMC/NB-IoT ออกมาแล้วก็จับใส่ใน Influxdb เลยครับ
โค๊ด Arduino
กลับมาที่โค๊ด Arduino กันบ้างครับ เริ่มจากตัวอย่าง Basic นะครับ ….
ตั้งแต่ Section นี้เป็นต้นไปไม่น่าจะอ่านรู้เรื่องเท่าไหร่ครับ… สามารถ Scroll ผ่านไปเร็วๆได้เลย…. ดูผ่านๆเพื่อความบันเทิงเท่านั้น 555
ในโค๊ดจะมีให้ประกาศ serverIP และ ServerPort ในที่นี้ก็คือ UDP Server ธรรมดานั่นเองครับ ผมใช้ Digital Ocean เข้ามาทำครับ ก็สบายดี ทำได้เลยครับ
แต่ตอนนั้นผมพัฒนาระบบคุยกับ ESP8266 Gateway ด้วย..แก้หลายรอบเลย ก็เลยต้องมี #ifdef
เอาไว้เพื่อข้ามกระบวนการเชื่อมต่อ NB-IoT ออกไป เพื่อว่ามันเสียเวลา Connect กับเสา พอสมควรเลยครับ (มันคุยกันผ่านทาง AT-Command)
ทาง AIS จะมีคลาสที่มีลักษณะเป็นแบบ Helper เอาไว้ให้ครับ… ในไฟล์ AIS_NB_IoT.h จะเป็นแบบนี้…
กลับมาเริ่มต้นใหม่…. กลับมาดูโค๊ดตัวอย่าง
ในส่วนของ setup()
จะมีการส่ง serverPort
เข้าไปใน AISnb.setupDevice
เลยครับ… แล้วบรรทัดถัดมาเรียก AISnb.getDeviceIP()
เลย… อ้าวเห๊ย…. ทำไมได้ IP มาแล้ว… เราเข้าไปดูใน getDeviceIP
กันต่อดีกว่าครับ
ฟังก์ชั่น AIS_NB_IoT::setupDevice(String )
นั่นไง… ชัดเลย ฟังก์ชั่นนี้ทำทุกอย่าง… ไม่ว่าจะเป็น
reset()
NB-IoT ModulegetIMEI()
getFirmwareVersion
getIMSI()
attachNB(serverPort)
….. ฟังก์ชั่นนี้น่าสนใจ… ทำอะไรบ้างนะ..
ฟังก์ชั่น attachNB(String )
ในส่วนของ attachNB(String)
นั้น…. มีความพยายามมากมายเหลือเกิน… ต้องไปไล่กันเองแล้วครับ… ที่เห็น delay(3000)
นั้นคือค่า Default ของ library ครับ… ไม่ถูกใจเท่าไหร่ เพราะแถวๆนี้มี delay อยู่เยอะมาก… ซึ่งปกติแล้วคิดว่าลูปมันน่าจะค้างอยู่กับโค๊ดพวกนี้อยู่แล้วครับ wait_rx_bc(1000, F("OK"));
แต่… เอาแล้วล่ะครับ… ส่วนนี้ทั้งหมดจะเป็นการคุย AT-Command
กับบอร์ด BC-95 ทั่วๆไปครับ…
Specification
ข้อมูลจำเพาะของมอดูล ผมไม่มีครับ… ลองค้นๆ Google มาโพสให้ดูครับ… ตรงที่น่าสนใจก็คือหัวข้อ Data Transmission ครับ
NB-IoT Data Transmission
โห… สำหรับ Single Tone ได้ตั้ง UL: 15.625kbps ส่วน DL: 24Kbps
… ก็ถือว่าไม่เลว… แต่พอผมลองยิงดูได้เพียงแค่ 1 msg/s ซึ่งขนาด 1 msg = ~400bytes แปลงแล้วได้ ~1.2kbits/s ซึ่ง… ผมยังไม่มีเวลาไปไล่ต่อครับ… แต่ที่เข้าใจคือมันติดที่การคุยผ่าน AT-Command ด้วยครับ
แต่จะเล่นต่อวันหลังครับ… Optimization ไม่ใช่เป้าหมายของบทความวันนี้ครับ..
Spec จากใน Brochure
สำหรักนักพัฒนา (Library)
ใครยังไม่มี Module NB-IoT ไปโหลดหนังสือมาอ่านกันก่อนได้ครับ
โหลดที่:
- https://www.quectel.com/product/bc95.htm
- https://www.quectel.com/UploadImage/Downlad/Quectel_BC95_AT_Commands_Manual_V1.9.pdf
- https://www.quectel.com/UploadFile/Product/Quectel_BC95_NB-IoT_Specification_V1.3.pdf
ผมเพิ่งรู้ว่า…… ว่า ว่า… มันโหลดมาอ่านได้ด้วยนะ.. แต่ต้องสมัคร สมาชิกและ Login ครับ.. ไม่ต้องส่งหลักฐานอะไรพิเศษด้วยครับ.. 555555
สรุป
สรุปแล้ว…. ผมทำอะไรลงไปบ้างเนี่ยยยยยยยยยย งั้นขอสรุปเป็น Bullet นะครับ (คิดบ่าออกเตื้อ… แปลว่ายังคิดไม่ออกครับ)
- บทความนี้เป็น Overview ครับ.. ให้ปรับตัวกันหน่อย รอบหน้ามาเจอกันใหม่
- ใช้เวลาเขียนโค๊ดกับ NB-IoT ตอนช่วง Maker Party ไปทั้งสิ้น… ประมาณ 24 ชั่วโมงครับ (ไม่นับเวลานอน)
- ข้อจำกัดของ Packet เป็น 512byte แต่การออกแบบ Packet ของผมรองรับตรงนี้อยู่แล้วครับ… เลยไม่กระทบอะไร… แต่ขอเตือนไว้ก่อน ใครยังคิดเป็น JSON อยู่ กระทบแน่นอนครับ ต้องมาทำ Binary Protocol กัน.. อิอิ
- Library สามารถพัฒนาต่อยอด ให้ดีขึ้นกว่านี้ได้ครับ (ผมมีแผนจะทำ เพื่อการศึกษา แต่ตอนนี้งานอื่นยังไม่เสร็จ)
- เจอบั๊กในการส่ง raw byte ของตัว library … แต่ยังไม่มีเวลา reproduce เลยทำฟังก์ชั่นขึ้นมาแปลง เพื่อแก้ปัญหาไปก่อน
- ยืนยันว่า.. binary packet ยังเป็นคำตอบของ NB-IoT / LoRa / WiFi / ESPNow / BLE … อยู่ครับ (ไว้วันหน้ามาลงบทความอื่นกันต่อเนอะ)
- ทำสอบตากฝนมาให้แล้วครับ… ไม่พัง 5555
- ไว้เจอกันบทความถัดไปครับ.. กำลังอ่าน Documentation แล้วครับ