ESP32晶片實作CoAP Server

以NodeMCU 32+, CoAP-simple-library 模擬 CoAP Light

邱奕修
Feb 28, 2022

最近開始在跑碩論的實驗,需要模擬一些IoT end device,因此稍微摸了一下支援wifi與BLE通訊的ESP32。網路上查支援ESP 32的CoAP套件大概都是推薦CoAP-simple-library這個開源程式碼,於是我就用這個套件的範例進行開發,過程中有遇到一些小問題,因此本篇主旨就是分享開發過程與一些遇到小問題,跟分享解決問題後的程式碼,希望能幫助到一些人~

NodeMCU 32+ 模擬 CoAP Light

模擬場景:

模擬場景如下圖所示,client(右)以PUT method向server(左)發送開燈請求,server收到請求後執行開燈指令,並回傳目前燈泡狀態給client。

模擬場景流程圖

本篇僅討論server端的議題,client端我是用一般電腦並使用node-coap這個套件來實現。

範例程式:

server端程式採用esp32.ino這個範例程式進行修改,填入ssid, pwd並修改LED腳位與鮑率即可初步運行,有在序列埠看到類似下圖的log就是有正確運行。

server啟動log檔

server準備完成後就可以用client進行測試,client端要輸入的URI類似下:

coap-client -e “1” -m put coap://(arduino ip addr)/light
coap-client -e “0” -m put coap://(arduino ip addr)/light

測試範例與除錯:

執行client程式會發現沒有回應,但看了下server這邊的LED,確實有執行開關燈指令,代表client的request是有傳到server的,初步研判造成這樣的原因可能有兩種:

  1. server端根本沒有response(可能當成是non-confirmable message)
  2. server端有response但client收不到
範例程式執行結果

打開wireshark並重新執行程式可以看到server端是有回傳ACK封包的,從程式碼中也可以看到是有response的(coap.sendResponse(…)),所以可以把原因1去除。

wireshark監控範例程式執行結果

但從wireshark看起來好像都正常(ip, port, message id等等),於是我用平常在用的node-coap進行比對,從下圖可以看出,上面的ACK少帶了token,所以client才會收不到(直接看出我對CoAP規格還沒到完全熟,第一時間竟然沒發現要帶token QQ)。

這下就抓到bug了,只要讓server的ACK帶著token,事情應該就解決了。

比對正常可完整運行程式與範例程式ACK差異

修正程式:

去看了下範例程式所使用的coap函式庫,可以看到如果coap.sendResponse裡面不帶token,會自動填入NULL。

coap.sendResponse()若不填token,會自動帶入NULL

所以我們要在範例程式sendResponse部分把request的token帶入,問題就解決了!

修改範例程式coap.sendResponse()

重新編譯server程式並執行client,就可以看到client正常的收到response了。

修正後程式碼:

最後附上修正後的程式碼,有把一些用不到的function也刪掉,看起來應該乾淨好理解一點。

心得:

果然要畢業了壓力還是有的,我竟然228連假每天下午都關在lab裡面弄實驗,不知道有沒有時間搞BLE的end device(有點想直接用rasp pi模擬了,這樣就可以直接用node寫XD),但其實玩玩這些小晶片也是蠻有趣、有成就感的~如果之後有做再寫個心得分享好了!

最後分享個小趣事,我一兩年前做大專生計畫時也有用arduino模擬coap end device,當時老闆是給我一塊what’s next公司出的red board,這塊板子可以兼容arduino IDE並支援UDP,不需要外接wifi晶片很方便,但壞處是需要他們公司自己的wifi, udp函式庫。最近在弄實驗時老闆第一時間也是給我那塊板子,然後…那間公司倒了XDD所以函式庫跟編譯器那些東西,網路上都找不到了(公司官網的domain直接404),所以那塊板子就直接變磚頭了😂

非常感謝讀完本篇文章,希望本文能對你有些幫助,記得按拍手給我一些鼓勵,Medium 文章中一個人最多能按 50 下 !

--

--

邱奕修
邱奕修

No responses yet