2017年9月12日 星期二

MQTT bridged LoRa networks with MicroPython on ESP32

Wei Lin
2017/09/12

緣由


  前一陣子做了 MQTT 的實驗,最近又開始接觸 LoRa,有天想到可以把這兩項技術結合在一起,採用 蜂巢網路的模式,透過 MQTT 串聯與整合 分散在各地區的 LoRa networks。

   為了以後可能的需要,就花了一個週末的時間先把這個模型做出來,如果以後我需要佈署自己的 LoRa 網路時就可以派上用場。

  目前只有做出這個模型,沒有經過壓力測試。我手上只有四個 LoRa transceivers,所以只能用這樣兩組 gateway + node 的組成來測試。

  不 follow LoRaWAN 的規範,純粹個人實驗。

GitHub repo.



LoRa 的優點

    LoRa 最近很熱門,因為它具有 範圍大,低耗能,成本低的特點:

  • 長距: 涵蓋面積大,只需要少數 gateways 即可涵蓋頗大的地理範圍。
  • 低耗能: 靈敏度可以到 -148dbm ,可以用較低的能量傳遞較遠的距離。
  • 末端節點成本低: 單一 channel 的 transceiver 並不算貴。
  • 平行作業: 使用無線電廣播,訊號可同時傳達 多個點。



出發點與目的

    其實我比較注重 如何建構 M2M (machine to machine) 的溝通機制,主要是想利用 LoRa 低成本、低耗能的優勢,用大範圍無線通訊 作為 M2M event system 中,事件推播的機制。



LoRa 的缺點

    但是如果要在城市中佈署 LoRa 網路,也是會遇到很多缺點與困難,例如:

  • 制高點得之不易: 制高點相對稀少 且可能有額外成本。
  • gateway 設備並不是很便宜:
    • 市面上的 LoRa gateway 通常具有同時多 channels 收發訊號的功能,價格由數千元至上萬元不等,實在不算便宜。
  • 整體資料throughput 不大,因為:
    • 障礙
      • 在都市叢林中會受到障礙與干擾的影響,傳輸速率受限。
    • 環境吵雜 訊號碰撞
      • 涵蓋範圍越大,表示其中的 nodes 越多,訊號碰撞的機率越高,整體有效的資料傳輸量較容易受到限制。
      • 訊號涵蓋範圍大,如果主要是為了 downlink 的用途的話 那就太棒了,因為發送的訊息可以同時送達範圍內所有的 nodes。但如果主要的用途是要從廣大地區收集資料回來,也就是以 uplink 為主的用途,那麼 涵蓋範圍越大,nodes 數量越多 越容易發生訊號碰撞的情況。
    • 傳輸速度不高
      • 為了要傳比較遠端距離,傳輸速度不能太快,這算是 傳輸距離遠 的代價。



想法

    主要的想法是:

  • 採用 GSM 蜂巢網路的模式

    • 城市中 建物障礙多,line of sight 難得,LoRa 訊號的傳輸功率開大的話,影響範圍更大,涵蓋的 node 數量會較多,容易會有更多的訊號碰撞。
    • 不如採用 GSM 蜂巢網路的模式,功率開小一點,gateway 多一點,每個 gateway 因為功率較小,涵蓋範圍也較小,範圍內的 node 數量少,訊號碰撞的機率就會跟著比較低,傳輸速率可以提高;而且 每個 gateway 的涵蓋範圍雖然不大,但因為數量多, 所以整體涵蓋範圍也不小,也比較容易消除訊號的死角,反而比較適合在城市之中佈署。
  • 以 MQTT 作為傳遞資料的 backbone
    • MQTT 因為採用 publish / subscribe 的模式,可以做到廣播的效果,也可以針對性地傳遞資料給指定的對象,相當彈性且高效能,可以做為 在各 gateways 之間傳遞資料的backbone。
    • 一個 gateway 其實就是一個 MQTT client,可以收發 MQTT 訊息。
  • gateway as woker
    • 以 Celery 的觀點來看,一個 gateway 也是一個 worker,我們可以透過 MQTT 傳達 message 給各個 gateways,指揮它們做特定的工作。各個 gateway 之間也可以藉此機制互相溝通與合作。




作法與特色

    主要的作法與特色是:

  • 定址
    • 每個 LoRa node 或者 gateway 都有一個 EUI-64 的地址
  • 無主機
    • gateways 們會互相分享與交換資料,並無中央主機來做管理。
  • Routing table 自動產生與更新
    • LoRa node 每次發射訊號的時候,會被依據訊號強度 自動 clustering 並歸屬到最接近的 gateway,由該 gateway 負責回應 ACK 或收發其他 LoRa packet。而且 gateways 之間會隨時互相交換 routing table 資料,LoRa node 可以無隙 roaming。
    • 可以用 RSSI 來做 地理位置定位 (Geolocation)。
  • 兩種傳遞資料的模式
    • 如果 payload 中有註明 目的地 的 EUI,則會藉由 MQTT 將之 route 到離目的地最近的 gateway 才轉而以 LoRa 的訊號發送出去。
      • 一個 LoRa node 可以 "撥號" 並傳遞資料給某一個特定的 LoRa node ,只要指定對方的 EUI 地址即可,payload 會由 gateways 自動做 routing,降低對其他地區不相關的 LoRa nodes 的干擾.
    • 如果 payload 中沒有註明 目的地 的 EUI,則會藉由 MQTT 將 payload 傳送給每一個 gateway,再轉為 LoRa 訊號發射出去給各 network 中的 LoRa nodes,效果等同是做全域的廣播。因此,台中,台北,高雄若各有一個 小型的 LoRa network,可以藉由此 MQTT 平台 串聯並視為單一個 LoRa network。
  • 降低佈署 gateway 的門檻
    • 成本低,每個 gateway 本身的硬體成本 相對低很多, 志願者負擔得起。
所使用的 Gateway (ESP32 + RFM96W)


市面上也有賣這種 整合 ESP32 + SX1278 的模組,
成本可以壓低到三百元以下


    • 不需要設定,只需要連上WiFi 網路,即可成為一個gateway,服務周圍幾百公尺內的 LoRa nodes。
  • 提升資料 throughput
    • 降低碰撞的機率
      • 因為可以依據 目的地的 EUI 位址決定 MQTT route 資料的路線,所以可以避免做全域性的廣播,可以傳遞資料並且避免干擾不相關的其他地區網路。
  • MQTT 與 LoRa 雙向的資料交換
    • 可以由 外部送一個 MQTT message 給 gateway,命令其發送 LoRa 訊號並傳遞資料給特定的 node 。
    • 可以藉由 MQTT 的機制收集 末端節點透過 LoRa 訊號 所傳送出來的資料。



實驗模型說明

  • 由左到右分別是 node2, gateway2, gateway1, node1
  • 使用 SF(Spreading Factor) 隔離:  node2, gateway2 的 SF = 9,node1, gateway1 的 SF = 8。這樣可以模擬兩個距離相當遠,原本無法相通訊息的 LoRa networks。
  • node1, node2 隨機 每隔 2~4 秒傳送一個 packet 給各自的 gateway。
  • node 或 gateway,收到 packet 之後 LED燈會閃一下。
  • gateway 收到 node 所傳來的訊號之後
    • 會透過 MQTT 互相交換網路拓樸資料。
    • 由最接近的 gateway 回應 ACK。
    • 會依據所收到的 payload 中所標註的 目的地 EUI,將 payload forward 給 最接近目的地 的 gateway 做 transmit。
  • 可以由 PC端發送 MQTT message 命令某一個 gateway 傳送 message中夾帶的 payload 給任一指定 EUI位址的 LoRa node。
  • node1 是用 ESP8266 做的,LED燈在上方,有點被擋住,透過電腦螢幕的鏡面反射反而看得比較清楚。


後記
  • 2017/09/15: 
    • 打破界線,將 SF 都設為 8,所以現在四個 device 彼此都會聽到對方的 LoRa 訊號,而兩個 gateways 就必須要能判斷一個訊號是由別的 gateway 還是  node 傳過來的,並且藉由 RSSI 來隨時判斷每個 node 要由哪一個 gateway 負責對應來收發 LoRa 訊號。
  • 最近入手這種 ESP32 + SX1278 LoRa + SSD1306 OLED 整合模組,整體設計相當簡潔,目前的價格大約台幣 300元,以後可能更便宜。

      為了兼容這個模組,特別加了一個 controller_esp_ttgo_lora_oled 的 subclass,並且將有使用到的 SSD1306 driver 含括進來。 雖然腳位定義不同,但已經都封裝在 controller 的子類別 (controller_esp_ttgo_lora_oled ) 中,所以應用的時候使用者可以如常使用 controller 所定義的 interface 即可,不需要去操煩底層實作的細節。





有個 display 還是比較方便一點,也許以後可以做個 LoRa 推文顯示器




參考資料




    15 則留言:

    Unknown 提到...

    請問文中提到的Lora這部分的應用
    是否主要還是屬於大範圍收集資料
    而遠端控制各節點GPIO較不太適合
    如監控某場域並能透過後端來啟動某些設備等

    Unknown 提到...

    請問文中提到的Lora這部分的應用
    是否主要還是屬於大範圍收集資料
    而遠端控制各節點GPIO較不太適合
    如監控某場域並能透過後端來啟動某些設備等

    DeepBlue 提到...

    Hi chou sam
    你提到的部份,目前我手邊的環境就是這樣在玩
    如果有興趣,可以聊聊
    gary@advintl.asia

    Wei Lin 提到...

    LoRa node to LoRa node, MQTT to LoRa, LoRa to MQTT 都是可以通訊的,當然也可以做控制,只是 LoRa 訊號會有碰撞的問題,所以如果要用來做控制,就必須有完善的確認機制。
    然而就目前網路上的一些資料看來,我個人的認知是大部分的案例都偏向用來收集資料,末端節點大部分時間都在睡覺,沒有注意到有什麼案例是偏重在控制末端節點的。

    DeepBlue 提到...


    時代在變 科技也在進步
    現今的Lora module雖然在物理層碰撞問題沒辦法完全避免
    但是透過韌體的方式或是搭配其他的既有技術(通訊協定)
    已經大幅降低甚至可以完全解決因為碰撞帶來的問題
    目前自己在使用的lora就是一個案例
    我們在「工業控制」上已經使用lora一段時間了
    已經不是單純的單向收集資料而已
    目前一切都很不錯
    遇到特殊情況時 再加上 AES 加密技術
    幾乎還沒遇到沒辦法解決的事件!

    Wei Lin 提到...

    那真是太棒了! 可以多提供一些技術面的參考資料嗎?

    DeepBlue 提到...

    你想要什麼資料??

    工控不外乎就是 rs232/rs485通訊 ( Modbus RTU 協定 )
    透過 Modbus協定,可以讀取 sensor 資料(coin/register),可以寫入資料(coin/register)
    主要 Lora 的應用層面,是把過往的實體線路換成 RF
    搭配 Modbus協定本身的特值(一問一答) & node端硬體的配置(是否在接到指令後,回覆結果)
    說穿了,Lora 只是一個 傳輸介面,一個工具,並不需要想的太複雜
    真正 RF 複雜的部份,就丟給 Lora Module firmware (FW) 去解決
    ( ex: 你會花時間去思考 無線網路卡硬體底層 實際的工作內容嗎?? ^_^ )

    除了上述的使用情況之外,其實還有很多其他的應用
    一時之間,也不知道你想要什麼...

    DeepBlue 提到...

    其實,一個好的 LoRa Module 真的可以省掉很多很多的麻煩!!
    以前一開始時,也是什麼東西都是自已用程式來解決 ( Arduino + Raspberry pi + ESP8266 )
    但是現在,只雯要專注在"資料的處理"這件事上
    RF傳輸/檢查這些底層的事,已經不需要花時間去思考
    code 也從原本的幾百行變成短短幾十行

    所以,選擇好的工具(產品 - Lora Module) 是一件很重要的事 !!

    另外補充一下
    其實市場上有些 Lora Module 已經開發出支援 mesh (類似zigbee多路徑的特性)功能的產品了!!
    ( 市場上已經有一些 wifi Mesh產品了!! )

    Wei Lin 提到...

    不好意思,沒有表達清楚我的問題,在工控這方面,我其實很外行。

    我比較想做的是 利用 LoRa 作為 一對多事件推播的機制 來建構 M2M 系統,可能會著重在 node 和 node 之間的溝通,主機對node倒沒有那麼重要,說不定沒有主機。

    所以我會很想知道 在利用 LoRa 優點的同時,如何讓碰撞的影響降到最小? 讓整體的資料 throughput 達到最佳化?
    可能像您講的 可以透過韌體和通訊協定去處理,但是在整個網路的架構上該如何設計? 有什麼相關的技術可以用? 或者像您提到的 使用支援 mesh 的 LoRa module,才能讓整體的資料 throughput 達到最佳化? 這是我比較著重的議題。

    不知道您所謂的 好的 LoRa module 是哪一種? 太貴我可能玩不起,哈哈!

    Wei Lin 提到...

    您給了我一個好主意! 我可以來做 LoRa mesh network。
    基本上只要收到 packet 就轉發出去,並避免形成 loop,應該就可以吧?
    不過還是先來找資料看看。

    Wei Lin 提到...

    歐,有找到 LoRa mesh 的資料,不過不多:
    http://mx.nthu.edu.tw/~huclee/paper/2017%20IPSN%20LORA%20MESH%2020170124.pdf

    DeepBlue 提到...

    >>在利用 LoRa 優點的同時,如何讓碰撞的影響降到最小? 讓整體的資料 throughput 達到最佳化?

    理論上,這類的問題真正能有效解決的話,是要在 FW 上才有可能。
    ( FW 的做法是設計一套完美的演算法,將所有 node 的動作時間分開! )

    若單純從軟體(code)的方面著手,大概就只能使用 ACK 這樣的機制
    (ex: 對方收到資料後回覆一個 ACK ,沒收到 ACK 看是要 重傳 還是 直接 丟掉)

    >>透過韌體和通訊協定去處理
    這是市面上能買到的 module http://www.manthink.cn/index.php?c=article&id=14
    不過,我一直試不出它號稱的功能
    「支持在线监听射频空中信道,实现物理层上支持无线防碰撞协议;使用无线防碰撞
    和硬件物理机制,有效的解决了周围其他无线系统同频干扰的问题」

    DeepBlue 提到...

    Lora mesh 產品連結
    提供參考
    https://goo.gl/d31kjX

    DeepBlue 提到...

    LoRa 是一個還在持續變化的通訊方法
    理論上,LoRa 的應用正規的是走 LoRaWAN 的模式
    但是,礙於 Gateway 硬體的價格並不是那麼親民的情況下
    目前一般市場的應用大部份都是採 peer to peer 的方式
    這方式沒有不好,但是,硬要用 p2p 去達到 LoRaWAN 的功能,有時候反而是自找麻煩!

    另外 LoRa 也是一個新的東西,在使用上,有的時候難免會陷入一些舊有的思維模式中
    理論上 peer to peer 的架構下,最好的運作模式就是 looping ( 輪詢 也就是 一問一答 )
    這方式可能是現階段避開碰撞最好的方法。
    因為有個負責協調所有 node 動作的 角色存在,在這角色上,你可以任意的去定義你要的演算法來實現目的

    換個角度來看 LoRa 這東西,或許就會有不一樣的看法!!
    說不定再過幾個月 這些問題都不再是問題了!!

    Wei Lin 提到...

    這些都是很寶貴的意見,謝謝您的回應。