Arduino Nesso N1の使い方:LoRa無線通信編

Nesso N1 LoRa通信の使い方アイキャッチ

「Arduino Nesso N1」を使用して、LoRa無線通信で送受信する方法をサンプルプログラムを使用して詳しく紹介します。

今回はLoRa(P2P:独自LoRa)無線通信を使って、データ送受信を行う方法を確認します。
テスト方法としては、送信側がデータを送り、受信側が受け取ったデータをそのまま返す「エコーバック方式」で、通信が正しく行われたか、通信品質(RSSI:受信信号強度)はどうだったかまで確認できます。
通信相手には「Nesso N1」がもう1台、または同じトランシーバIC「SX1262」搭載のデバイスが必要です。今回は通信相手のデバイスとして「M5Stack」社製の「UNIT-C6L」を使用しています。
「Nesso N1」に搭載されているトランシーバICは「SX1262」です。
LoRaのP2P通信は無線ICごとに通信方式(プロトコル)や仕様が異なるため、確実に動作確認を行うには 同じトランシーバICを搭載したデバイス同士で動作確認するのが確実です。
また、日本国内で使用する場合は電波法を考慮した通信設定で 技適に対応したデバイスを使用する必要があります。
ここで紹介する内容は私の理解した内容での紹介となります。
実際の運用には以下リンク先の総務省のサイトを確認して運用してください。
→総務省 電波利用ポータル:920MHz帯の無線局の利用

「Nesso N1」の基本的な使い方や機能、端子配列等については、以下のリンクで詳しく紹介しています。

Arduino Nesso N1の使い方:基礎編
Arduino Nesso N1(M5StickC Plus互換)の開発環境やライブラリのインストール、端子配列や機能をサンプルプログラムを使って詳しく紹介

「M5StickC Plus2」でLoRa無線ユニット「LoRaE220-JP」を使用した、LoRa無線通信の使い方についても以下のリンク先で詳しく紹介しています。

LoRa E220 + M5StickC Plus2で無線相互通信する方法
無線通信ユニットLoRaE220-JPとM5StickC Plus2でP2P長距離通信を実践。無線ユニットの使い方や初期設定から遠隔Lチカまで詳しく紹介します。
スポンサーリンク

1.LoRa無線通信について

LoRa無線通信を理解するために、まずはその仕組みや使用するトランシーバIC「SX1262」、そして日本で利用する際に関係する電波法について詳しく紹介します。

・LoRaとは

LoRa」とは、「semtech社」が開発した変調方式(電波の飛ばし方)です。
長距離無線(Long Range Radio)を実現することから「Long Range」を略して「LoRa」と呼ばれています。

「LoRa」はWi-Fiのような高速通信はできませんが、遠くまで電波が届くのに省電力であることが特徴です。

通信距離は、壁の無い見通しの良い条件では「数km〜数十km」の通信が可能で、「数m〜数十m」のWi-FiやBluetoothより、はるかに遠くへの無線通信が可能で、ノイズにも強く障害物の影響も受けにくい変調方式です。

しかし、通信速度は「数百bps〜数kbps程度」と遅いため、動画や音声の通信には不向きです。
その代わり消費電力は少ないので、電池で駆動するデバイスで小さなデータを送信する用途には最適で以下のような用途で使用されます。

主な用途、農業(温度・湿度・土壌センサー)、河川の水位監視、工場の設備監視(IoT)、スマートメーター、位置情報トラッカー、防災センサー(地滑り・浸水など)
「LoRa」を使った通信の種類には「LoRaWAN」と「P2P:プライベート(独自)LoRa」があり、主な違いは以下になります。
・LoRaWAN:
  LoRaを使ったネットワークのルール(プロトコル)で、完成された通信規格。
・P2P:プライベート(独自)LoRa:
  LoRaを使って、独自の通信プロトコルを自作して行う通信。
今回ここで使用するのは「プライベート(独自)LoRa」です。

・無線通信モジュールSX1262について

SX1262」は、Semtech社の「LoRa トランシーバIC」で、LoRa・FSKなど複数の変調方式に対応しています。
低消費電力でありながら最大+22dBmの送信出力を持ち、LoRaWANやP2P(独自LoRa)通信など幅広い用途で利用されています。

Nesso N1」にもこの「SX1262」が搭載されており、LoRa無線通信を行うための中心的な役割を担っています。

SX1262の通信仕様一覧表

「SX1262」の通信仕様とLoRaWAN、P2P(独自LoRa)それぞれの用途で使用した場合の主な設定をまとめると以下表のようになります。

項目SX1262の仕様LoRaWANの設定P2Pの設定
対応周波数帯150〜960 MHzAS923(日本):923.2, 923.4 MHz920.6MHz~928MHz
(中心周波数、200kHz間隔で設定)
変調方式LoRa / (G)FSK / LR-FHSSLoRa(固定)LoRa または (G)FSK
帯域幅(BW)7.8〜500 kHz125 kHz(必須)125 kHz 推奨(200kHzチャネル内)
拡散係数(SF)SF5〜SF12SF7〜SF12(ネットワークが決定)SF7〜SF9
(SF10以上はデータ量から
送信時間を慎重に検討必要)
符号化率(CR)4/5〜4/84/5(LoRaWAN標準)4/5〜4/6(自由)
最大送信出力+22 dBm(IC性能)+13 dBm(日本の上限)+13 dBm(日本の上限)
プリアンブル長任意設定8(固定)8〜12 推奨(自由)
同期ワード任意設定0x34(固定任意(0x12がよく使われる)
受信感度約 -137 dBm(SF12, BW125kHz)共通(固定)共通(固定)
電源方式DC-DC:省電力、バッテリー駆動用
LDO:低ノイズ、安定受信
どちらでも可どちらでも可
モジュールによる
TCXO制御電圧1.6〜3.0Vモジュール依存モジュール依存
インターフェースSPIMCU経由で制御MCU経由で制御
通信方式半二重(送信と受信は同時不可)LoRaWANプロトコル自由設計
「SX1262」は高出力・高感度の優れた無線 IC ですが、日本国内では「電波法」に従い、送信出力を「+13dBm以下」に制限し、決められた送信時間/周期の範囲内で「技適対応デバイス」を使用する必要があります。
IC の性能をそのまま使えるわけではなく、電波法の範囲内で適切に設定して運用することが重要です。

スポンサーリンク

2.日本の電波法への適合確認

日本国内で LoRa などの無線通信を利用するには、「電波法」に適合していることが必須です。
無線機器は自由に使えるわけではなく、使用できる「周波数」や「送信出力」、「送信時間」など、守るべきルールが細かく定められています。

ここでは、「特定小電力無線」の基本的な考え方をはじめ、「技適マーク」の確認方法、利用可能な「周波数帯」、「送信時」の注意点など、LoRa を日本で安心・安全に使うために知っておきたいポイントについて詳しく紹介します。

Nesso N1」に搭載されている「SX1262」は、最大「+22dBm」の空中線電力(送信出力)に対応した高性能な 「LoRa トランシーバIC」です。
しかし、この性能をそのまま日本国内で使用することはできません。
日本では無線機器の利用が「電波法」によって厳しく管理されており、「LoRa 無線通信」もその規定の範囲内で運用する必要があります。

電波法に適合した無線通信を行うためには、送信時間や送信間隔、周波数の使い方など、多くの細かなルールを守る必要があります。

特に「920MHz帯の特定小電力無線」は、通信方式(キャリアセンスの有無、周波数ホッピング、LDCなど)によって制限条件が大きく異なり、関係する告示や技術基準も分散しているため、全体像を把握するのは簡単ではありません。

そこで本記事では、私なりの理解にはなりますが、主な通信方式ごとに送信時間や待ち時間の制約を整理し、以下のように一覧表としてまとめました。制度理解の参考資料としてご覧ください。

方式中心周波数範囲 (200kHz間隔)
※帯域幅200kHz以内
キャリアセンス 
(しきい値-80dBm)
空中線電力
(送信出力)
送信時間
1回の最大
休止時間1時間あたりの送信時間合計用途
通常
1〜20チャネル同時使用可
920.6~928.0MHz必要
128μs以上
5ms未満
20mW (13dBm) 以下0.4s以内2ms以上360秒(6分)頻繁な 短文向き
必要
5ms以上
4.0s以内50ms以上長文・高頻度 向き
周波数ホッピング(FH)方式
0.4秒以内に周波数を切り替える (送信時間0.4秒以内で同一周波数への送信間隔は4秒以上)
920.6~925.0MHz不要0.4s以内4秒以上 (同一波)合計720秒 (同一波36秒)複数chを 賢く使う
LDC(Low Duty Cycle)方式
1時間あたりの送信時間の割合が1%(36秒/時)以下
920.6~923.4MHz不要36秒(1%)たまに 送るだけ

詳細は以下リンク先の総務省のサイトや無線設備規則、電波法施行規則等でご確認の上、用途に応じて正しく運用してください。

以下からは、上の表を作成するにあたって確認した内容をまとめておきます。

特定小電力無線とは

特定小電力無線」とは、電波法で定められた「免許不要」で使える無線通信のことです。
しかし、「免許不要」=「自由に使っていい」ではないので注意が必要です。

Nesso N1」は、 「特定小電力無線局」として使えるように設計されており、「技適(技術基準適合証明)」も取得済です。
このため、「周波数」や「電波の出力」、「送信時間」などを正しく設定すれば、 個人でも免許なしで使用することができます。

技適(技術基準適合証明)の確認

「LoRa無線通信」を「免許不要」で使うには、まず大前提として技適に対応したデバイスを使用する必要があります。

日本国内で使う無線機器には、技適マーク(技術基準適合証明)が必要です。
これは、機器が日本の電波法に適合していることを示す証明で、 技適マークのない機器を違法に使うと「電波法違反」になります。

対応デバイスには必ず「技適証明番号」が書かれており(本体に限らず、梱包箱の場合もある)、以下のサイトで番号から適合内容を確認することができます。

「Nesso N1」は技適取得済(技術基準適合証明番号:219-259209)で取得内容は以下になります。
・第2条第8号に規定する特定無線設備:LoRa無線通信等、特定小電力無線局
・第2条第19号に規定する特定無線設備:Wi-Fi、Bluetooth等、2.4GHz帯高度化小電力データ通信システム

「特定無線設備」のうち、電波法に基づく技術基準に適合していることを示す表示(技適マーク)が付されていることにより、無線局の免許が不要となる設備の一覧は以下リンク先の表で確認できます。

「Nesso N1」は「特定小電力無線局」の「テレメーター、テレコントロール、データ伝送用」に該当します。

「テレメーター/テレコントロール」の「テレ」とは、ギリシャ語で「遠い」「遠く離れた」を意味します。
遠く離れた機器の状態を電波で受信して知ることができるシステムを「テレメータ」、遠く離れた機器へ指示を送信して、制御するシステムを「テレコントロール」といいます。

使用できる周波数範囲、空中線電力の確認

日本でLoRaなどの無線通信を「免許不要」で使う場合、「使用できる周波数空中線電力(送信出力)」が決まっています。

使用できる周波数空中線電力」については以下総務省のサイトで確認できます。

サイト内の「表 6 テレメータ用・テレコントロール用及びデータ伝送用無線局の技術基準等」で「特定小電力無線局」の「使用できる周波数空中線電力」が以下表のようにまとめられています

周波数空中線電力 技術基準特定無線設備の規格
中出力型(キャリアセンス要):920.5MHz~928.1MHz20mW以下 設備規則第49条の14第7号(同号ニただし書きに該当するものを除く。)証明規則第2条第1項第8号
中出力型(FH):
920.5MHz~925.1MHz
設備規則第49条の14第7号(同号ニただし書き(1)に該当するものに限る。)
中出力型(LDC):
920.5MHz~923.5MHz
設備規則第49条の14第7号(同号ニただし書き(2)に該当するものに限る。)

この表を見ると「空中線電力」は「20mW以下」であることがわかります。

無線で使用できる周波数や送信条件は、無線の用途や方式によって異なります。そのため、実際に機器を設計・運用する際には、該当する技術基準を必ず確認する必要があります。

ここで紹介している内容は、「無線設備規則 第49条の14 第7号」に基づいており、詳細な規定については以下のリンク先を参照してください。

使用できる周波数については電波法で細かく分類されているため、判断が難しいですが以下のリンク先の「施行規則第六条第四項第二号」の「3 九一五・九MHz以上九二八・一MHz以下の周波数の電波を使用する無線設備」の表で確認できます。

このページ内では特定小電力無線局の電波の型式、周波数及び空中線電力が用途の区分ごとに表にまとめられています。

該当する表を探すのはなかなか大変です・・・特に数字が読みにくいですが、以下が「Nesso N1」に該当すると思いますので抜粋して紹介します。


一 テレメーター用、テレコントロール用及びデータ伝送用
3 九一五・九MHz以上九二八・一MHz以下の周波数の電波を使用する無線設備

周波数空中線電力(送信出力)
中心周波数が九二〇・五MHzに一〇〇kHzのn倍を加えた周波数以上九二八・一MHzから一〇〇kHzのn倍を減じた周波数以下の周波数であって、九二〇・五MHzに一〇〇kHzのn倍を加えた周波数に二〇〇kHzの整数倍を加えたもの(キャリアセンスを行わないものにあっては、無線設備規則第四十九条の十四第七号ニただし書に掲げる条件に適合するものに限る。)(注2)〇・〇二ワット以下。ただし、無線設備が一の筐体に収められており、かつ、容易に開けられない構造であって、等価等方輻射電力が一六デシベル以下となるものにあっては、〇・二五ワット以下であること。

2 nは、一の無線チャネルとして同時に使用する単位チャネル(中心周波数が九二〇・六MHz以上九二八MHz以下の周波数のうち九二〇・六MHzに二〇〇kHzの整数倍を加えたものであって、帯域幅が二〇〇kHzのチャネルをいう。)の数であり、一以上二〇以下の整数とする。


空中線電力「1mW」の表と一緒に書かれてますがこれは「微弱無線局」の内容のため、上表の「0.02W = 20mW以下」が該当すると思います。

空中線電力「20mW」は「+13dBm」になり、「SX1262」では「最大+22dBm」が設定できても、「電波法」に従う必要があるため「+13dBm以下」で運用する必要があります。

次に周波数について読み解いてみます。まずは数字を読みやすくします。

中心周波数が920.5MHzに100kHzのn倍を加えた周波数以上
928.1MHzから100kHzのn倍を減じた周波数以下の周波数であって
920.5MHzに100kHzのn倍を加えた周波数に200kHzの整数倍を加えたもの

つまり、実際に使用する周波数の上限値下限値は以下のようになります。

下限値:920.5MHz + 0.1MHz = 920.6MHz
上限値:928.1MHz – 0.1MHz = 928.0MHz

使用できる周波数は920.6MHz〜928.0MHzの範囲で200kHz(0.2MHz)ごとに分割した以下38チャネルの値を中心周波数として選択して使用することになります。
※同時使用は連続した周波数を使用し、キャリアセンスが必須で20チャネルまで使用可

920.6、920.8
921.0、921.2、921.4、921.6、921.8、922.0、922.2、922.4、922.6、922.8
923.0、923.2、923.4、923.6、923.8、924.0、924.2、924.4、924.6、924.8
925.0、925.2、925.4、925.6、925.8、926.6、926.8、926.6、926.8、926.6
927.0、927.2、927.4、927.6、927.8、928.0(MHz)

さらに、注2のnについて読み解いてみます。これは複数チャネルで同時通信する場合に使用可能なチャネルについて書かれています。

例えば10個のチャネルを同時に使用する場合、n = 10となり、使用できる周波数範囲は以下になります。

 920.5 + 0.1× 10 〜 928.1 ー 0.1× 10
=921.5 〜 927.1(MHz)

これを、200kHz幅で分割すると以下29チャネルになり、この中から連続した10個のチャネルが使用できるということになります。

921.5、921.7、921.9、922.1、922.3、922.5、922.7、922.9
923.1、923.3、923.5、923.7、923.9、924.1、924.3、924.5、924.7、924.9
925.1、925.3、925.5、925.7、925.9、926.1、926.3、926.5、926.7、926.9
927.1(MHz)
このように複数のチャネルを同時に使用する場合は「干渉を避けるため」同時使用チャネルが増える(nが大きくなる)ほど、使用可能な周波数範囲は狭くなっていくようです。
複数のチャネルを同時に使用するには「キャリアセンス」を実施する必要があります。
「キャリアセンス」を実行しない場合には、同時使用可能なチャネルは1チャネルのみで、さらに周波数範囲や通信可能な時間にも条件に応じた制限があります。

キャリアセンスと送信時間

「キャリアセンス」とは、無線を送信する前に、周囲の電波状況を確認して、他の無線局が通信中でないか確認してから送信を開始する仕組みで、他の無線局との電波の衝突(混信)を防ぐために実施されます。

送信前に「RSSI(受信信号強度)が-80dBmより小さいかどうか」を測定することで、他の無線局が通信中でないことが確認できます。

キャリアセンスの実施は必須ではありませんが、キャリアセンスを実施しない場合は複数チャネルの同時使用はできません。

キャリアセンスを実施した場合と、しない場合の送信時間については以下のようになります。

・キャリアセンスあり:
 1時間あたりの送信時間の合計が360秒(6分)以下(10%以下)。
・キャリアセンスなし:
 周波数を0.4秒以内に切り替える(周波数ホッピング(FH)方式)か、
 1時間あたりの送信時間の合計を36秒以下(1%以下、LDC方式で)にする。

これについては、以下リンク先の「無線設備規則」の中に書かれており、「総務省の電波ポータル」の中でまとめられています。

送信時間などの具体的な数値は電波法の条文に直接記載されているわけではありませんが、「電波法」に基づいて「総務省」が定めた省令や告示(技術基準)で詳細に規定されており、これらに従う必要があります。

電波法を考慮したSX1262の推奨設定値一覧

「LoRa無線通信」を日本国内で使用する際に考慮すべき電波法に関する項目と、「SX1262」を使用する時の推奨設定値を一覧表にまとめて紹介します。運用時の参考にしてください。

項目詳細推奨設定値(日本の電波法準拠)
周波数 (Frequency)通信に使う中心周波数。
日本では920MHz帯(下限920.5MHz~上限923.5MHz)が利用可能。
帯域幅を考慮して設定する。
920.6MHz~928MHz
※周波数範囲を超えないよう帯域幅を考慮して設定(200kHz間隔[±100kHz])
※923.2MHz、923.4MHzで1チャネルのみの使用が安全
帯域幅 (Bandwidth)信号の広がり幅:125/250/500kHz
広いほど高速通信できるが、消費電力と別チャネルとの干渉リスクが増す。
125 kHz
(チャネル幅200kHzを超えてはいけない)
拡散係数 (Spreading Factor, SF)拡散変調の強さ。大きいほど遠くまで届くが、通信速度は遅くなる。SF7〜SF9(SF8以下が安全)
SF10以上(送信データによっては送信時間が電波法の制限を超える可能性あり)
符号化率分母 (Coding Rate, CR)誤り訂正の強さ。CR:4/5〜4/8。大きいほど信頼性は上がるが、速度は低下。CR:4/5 または 4/6(バランス重視)
※設定は分母の数値で指定
同期ワード (Sync Word)通信相手を識別するための識別子。LoRaWANとP2Pで異なる値を使う。LoRaWAN:0x34
P2P:0x12(LoRaWANと区別するための慣習的な値で自由に設定可。同じ値同士でのみ通信可能でグループ分けにも使える)
出力電力 (TX Power)送信時の電力。日本の特定小電力では20mW(+13dBm)が上限。+13 dBm
プリアンブル長 (Preamble Length)受信側が信号を検出して同期を取るための LoRa シンボル数。
長いと受信の安定性が向上するが、送信時間増、消費電力増。
LoRaWAN:8
P2P:8〜12程度
TCXO基準電圧TCXO(温度補償型水晶発振器)を使う場合の電源電圧設定。1.6〜3.0V
(使用するデバイスに合わせて設定)
useRegulatorLDOSX1262の内部電源レギュレータの選択。DC-DC/LDO(低ドロップアウト)バッテリー駆動:DC-DC推奨
安定性重視:LDO
実際に「LoRa無線通信」を行うときには送信時間と送信間隔に注意が必要です。
これらは「キャリアセンス」の有無で異なりますが、下で紹介する「サンプルプログラム」ではできるだけシンプルに通信確認を行いたいため、「キャリアセンスなし」としています。このため、送信動作の確認は1時間に50回程度にしてください。
※1時間あたり36秒(1%)以下にするため(送信データは0.2秒以下、エコーバック動作想定)
スポンサーリンク

3.開発環境の準備

「Nesso N1」で「LoRa無線通信」を使用するために必要な開発環境とライブラリ等のインストール、初期設定について詳しく紹介します。

・Arduino IDEのインストール

「Arduino IDE」のインストール方法は、以下のリンクで詳しく紹介しています。

Arduino IDE 2のインストール方法、初期設定、使い方
バージョンアップして使いやすくなったArduino IDE 2のインストールから使い方まで詳しく紹介、便利な機能やM5Stack、ラズパイPicoでの使用方法も紹介します。

・ボードマネージャ、ライブラリのインストールと初期設定

「Arduino IDE」のインストールが完了して起動したら、下画像のように左メニューアイコンから[ボードマネージャ]を選択し、検索窓に「ESP32」と入力すると「esp32 by Espressif」が表示されるため、これをインストールします。

Arduino Nesso N1開発環境の初期設定

次に以下表のライブラリをインストールします。

ライブラリ名用途バージョン検索名
M5UnifiedM5Stack共通ライブラリ0.2.13m5unif
M5GFX液晶画面制御用0.2.19m5g
RadioLibLoRa無線通信用7.5.0radiolib
M5Unified」は「M5Stackシリーズ」の共通ライブラリで「Nesso N1」にも対応しており、他の「M5Stackシリーズ」と同じように使用できるようになります。
M5GFX」ライブラリは液晶画面を制御するためのライブラリです。
RadioLib」はLoRa 無線通信を簡単に扱えるようにしたライブラリで、「SX1262」を含む多くの無線 IC をサポートしています。
RadioLib」は LoRa の物理層(PHY)通信を扱うライブラリで、周波数や帯域幅などの無線パラメータを直接制御できます。
一方で、「LoRaWAN」 のような上位プロトコル(MAC層・ネットワーク層)は実装されていないため、「LoRaWAN」 には対応していません
バージョンは基本的に最新のものをインストールしてください。
ここで紹介している「サンプルプログラム」が動作しない場合は上表のバージョンで動作確認してみてください。

ライブラリのインストールは、下画像のように左メニューアイコンから[ライブラリマネージャ]を選択して検索窓にインストールしたいライブラリ「m5unified(m5unifまででも良い)」のように入力すると「M5Unified by M5Stack」が表示されるため、必要なライブラリを[インストール]ボタンをクリックします。

M5Unifiedライブラリのインストール

[インストール]をクリックすると下画像のようなウインドウが表示されることがあります。

M5Unifiedライブラリのインストール

「M5Unified」の場合は動作に関連する「M5GFX」ライブラリがインストールできるため
[全てをインストール]ボタンをクリックします。

同様に「RadioLib」ライブラリも検索してインストールしましょう。


次に「NESSO N1」とパソコンをUSBケーブルでパソコンと接続します。

接続したら、下写真のようにメニューバーの[ツール]→[ボード:”ESP32 Familly Device”]→[esp32]→[Arduino Nesso N1(最下部)]をクリックしてください。

Arduino Nesso N1開発環境の初期設定

パソコン側で「NESSO N1」の接続が認識されると、下画像のように画面上部に「Arduino Nesso N1」と表示されます。

Arduino Nesso N1開発環境の初期設定
接続が認識されない場合は本体左側面の電源ボタンを長押し(内部の小さい青色LEDが点滅するまで)してから再度試してみてください。
それでもうまくいかない場合は[ツール]→[ポート:”COM番号は環境によります”]の選択で他のポートを選択して試してみてください。

・シリアルモニタ出力設定

最後に初期設定として、「Arduino IDE」のシリアルモニタ機能で「Nesso N1」からのシリアル出力を表示するための設定を行います。

下画像のように[ツール]→[USB CDC On Boot:”Disabled”]→[Enabled]を選択します。

Arduino Nesso N1開発環境の初期設定
「Nesso N1」は他のArduinoシリーズとは異なり「USBーSerial」変換チップを搭載していません。このためマイコン自身がシリアル通信機器として振る舞う必要があります。
「USB CDC On Boot」が「Disabled」の場合は電源ON時にこの機能が無効になっているため「Enable」にしておかないとシリアル通信機器として認識されずシリアル出力を行なっても何も表示されません。
スポンサーリンク

4.動作紹介

ここで紹介している「サンプルプログラム」を使用した動作について詳しく紹介します。
「サンプルプログラムは」送信側と受信側で同じ(デバイスに合わせて)ものを書き込みます。

「LoRa無線通信」で送受信の動作確認を行うには2台のデバイスが必要です。
「Nesso N1」が2台あるといいのですが、高価なデバイスなので私は1台しか持ってません^^;
このため受信側には「M5Stack社」製の「UNIT-C6L」を使用しました。

「Nesso N1」と同じトランシーバIC「SX1262」を搭載して、技適取得済みのデバイスとして「M5Stack社」製の「UNIT-C6L」があります。
比較的安価(スイッチサイエンスで¥4,191-)なのでおすすめです。
※サンプルプログラムも両方に対応できるように作成しています。
Nesso N1 LoRa通信 動作確認

実際に動作確認している様子は上写真のようになります。

Nesso N1 LoRa通信 動作確認

「Nesso N1」の電源を入れると、「LoRa無線通信」の初期設定が開始され、完了すると上写真のような表示になります。

Nesso N1 LoRa通信 動作確認

初期設定完了後に本体正面ボタンを押すと「Hello! #1(番号はボタンを押した回数)」が送信(>Send)されます。
受信側にデータが届くと、送信したデータがそのまま送り返されてくるので受信(<Receive)して表示されます。

RSSI:〜dBm」は「受信電波強度」で通信品質を表します。
写真では「-0dBm」になってますが、デバイス同士が近すぎるためこのような値になっています。
実際は-数dBmから-数十dBmで、-100dBm程度までが安定した通信品質です。
-120dBmを超えてくると、データが届かないことが多くなります。
Nesso N1 LoRa通信 動作確認

データを受信した時には上写真のようにデータが受信(<Receive)されると、データが受信されたことを伝えるために、受信したデータをそのまま送信(>Send)します。

Nesso N1 LoRa通信 動作確認

ボタンを押すたびに送信データの数値が「#1,2,3・・・」のように増えていきます。

サンプルプログラムでは受信したデータをそのまま送り返す「エコーバック」動作にしています。
単純に「エコーバック」させると、2台のデバイス間で送受信を延々と繰り返すため、受信データが自分で送ったデータと異なる場合のみ「エコーバック」を行うようにしています。
このため、たまたま受信したデータが前回送信したデータと同じだった場合には「エコーバック」動作は実行されません。
スポンサーリンク

5.サンプルプログラム

サンプルプログラムは「Nesso N1」用です。2台の「Nesso N1」に同じものを書き込んで動作確認してください。
5行目」をコメントアウトして、「6行目」のコメントアウトを解除することで「UNIT-C6L」用としても使用することができます。
※「UNIT-C6L」では「8行目」の文字サイズは「Font0」にしないと文字が大きすぎるのでこちらも変更してください。
サンプルプログラムは「キャリアセンスなし」のため、送信時間は1時間あたり36秒(1%)以下にする必要があります。今回の送信データは0.2秒以下を想定していますが送信回数はエコーバックも考慮して1時間あたり50回程度を目安に動作確認してください

サンプルプログラムは以下になります。
コピペで貼り付けて実行してください。コピーは下の黒塗り部右上のアイコンクリックでもできます。

#include <M5Unified.h>
#include <RadioLib.h>

// LoRa通信 SX1262ピン設定(CS, IRQ, NRST, BUSY)
SX1262 radio = new Module(23, 15, RADIOLIB_NC, 19); // Nesso N1のピン設定
// SX1262 radio = new Module(23, 7, RADIOLIB_NC, 19);  // Unit-C6Lのピン設定

#define MAIN_FONT &fonts::Font4 // フォント指定 ※C6LはFont0推奨

// グローバル変数
volatile bool receiveFlag = false; // 受信フラグ
bool isTransmitting = false;       // 送信中フラグ
int count = 0;                     // 送信パケットカウンタ
String sendMessage;                // 送信メッセージ格納用
String receiveMessage;             // 受信メッセージ格納用

// 受信割り込みコールバック ************************************
void setReceiveFlag() {
  if (!isTransmitting) {  // 送信中でなければ
    receiveFlag = true;   // 受信フラグをセット
  }
}

// ログ出力:画面とシリアルへ同時出力 ***************************
void logPrint(const String& msg) {
  Serial.println(msg);      // シリアル出力
  M5.Display.println(msg);  // 画面出力
}

// LoRa送信処理 **********************************************
void sendLoRaMessage(String& message) {
  isTransmitting = true;  // 送信中フラグをセット
  radio.clearPacketReceivedAction(); // 受信割り込無効化(送信中のゴースト受信割り込み対策)
  radio.standby(); // 受信を停止
  delay(10);       // 受信停止待ち

  logPrint("\n>Send:\n" + message);    // 送信メッセージ出力
  int state = radio.transmit(message); // 同期送信(完了まで待つ)

  if (state == RADIOLIB_ERR_NONE) { // 送信成功なら
    logPrint("Success!"); // 成功表示
  } else {
    logPrint("Failed, code: " + String(state)); // エラーコード表示
  }
  radio.finishTransmit(); // 送信完了処理
  delay(15);              // 送信完了待ち
  radio.setPacketReceivedAction(setReceiveFlag); // 受信割り込み再設定
  radio.startReceive();   // 受信再開
  isTransmitting = false; // 送信中フラグをクリア
}

// LoRa(SX1262) 初期化 ****************************************
void initSX1262() {
  auto& ioe = M5.getIOExpander(0);  // I/OエキスパンダーE0のオブジェクトを取得

  // リセット処理
  ioe.digitalWrite(7, false); // SX_NRSTをLOWにしてSX1262をリセット
  delay(100);                 // リセット待ち
  ioe.digitalWrite(7, true);  // SX_NRSTをHIGHに戻す
  delay(100);                 // 安定待ち

  // RF回路有効化
  ioe.digitalWrite(6, true);  // SX_ANT_SWをHIGHにしてアンテナスイッチを有効化
  ioe.digitalWrite(5, true);  // SX_LNA_ENをHIGHにしてLNA(低雑音増幅器)を有効化

  // SX1262 通信設定(周波数 MHz、帯域幅 kHz、拡散係数、符号化率分母、同期ワード、出力電力 dBm、プリアンブル長、TCXO基準電圧、useRegulatorLDO)
  int state = radio.begin(923.2, 125.0, 9, 5, 0x12, 13, 8, 3.0, true);

  if (state != RADIOLIB_ERR_NONE) { // 初期化失敗なら
    logPrint("LoRa Init \nFailed: " + String(state)); // エラーコード表示
    while (true) delay(100);                          // 無限ループ
  }
  logPrint("LoRa Init \nSuccess!"); // 初期化成功表示

  radio.setPacketReceivedAction(setReceiveFlag); // 受信完了時のコールバック関数を設定
  radio.startReceive(); // 受信開始
}

// 液晶画面初期化 **********************************************
void initDisplay() {
  M5.Display.setTextSize(1);          // 文字サイズ(整数倍率)
  M5.Display.setFont(MAIN_FONT);      // フォント指定
  M5.Display.setBaseColor(TFT_BLACK); // 画面クリア時の背景色指定
  M5.Display.setTextScroll(true);     // 文字スクロール有効化
  M5.Display.clear();             // 画面クリア
  M5.Display.setCursor(0, 0);     // 表示座標設定(x, y)
  M5.Display.println("[SX1262]"); // 画面出力
}

// 初期設定 --------------------------------
void setup() {
  M5.begin();  // M5Unified初期化
  Serial.begin(115200); // シリアル出力初期化
  delay(1000);          // 1秒待機

  initDisplay(); // 液晶画面初期化
  initSX1262();  // LoRa(SX1262) 初期化
}

// メインループ ----------------------------
void loop() {
  M5.update();  // M5ボタン状態更新

  // 送信処理(ボタンA ON)
  if (M5.BtnA.wasPressed() && !isTransmitting) { // 送信中フラグが立っていない状態でボタンAが押されたら
    count++;                                  // 送信パケットカウンタ+1
    sendMessage = "Hello! #" + String(count); // 送信データ作成
    sendLoRaMessage(sendMessage);             // LoRaデータ送信処理関数
  }

  // 受信処理
  if (receiveFlag) {
    radio.clearPacketReceivedAction(); // 受信割り込み無効化
    radio.standby(); // 受信を停止
    delay(10);       // 受信停止待ち

    int state = radio.readData(receiveMessage); // 受信データ読み込み

    if (state == RADIOLIB_ERR_NONE && receiveMessage.length() > 0) { // 受信成功かつデータが存在するなら結果表示
      logPrint("\n<Receive:\n" + receiveMessage); // 受信メッセージ出力

      Serial.printf("RSSI: %.0f dBm\n", radio.getRSSI());        // 受信信号強度指標(RSSI)取得・表示
      M5.Display.printf("RSSI: \n %.0f dBm\n", radio.getRSSI()); // 画面表示

      Serial.printf("SNR: %.2f dB\n", radio.getSNR());                // 信号雑音比(SNR)取得・表示
      Serial.printf("FreqErr: %.2f Hz\n", radio.getFrequencyError()); // 周波数誤差取得・表示

      // エコーバック(自分の送信内容と違う場合のみ ※ループ対策)
      if (receiveMessage != sendMessage) {  // 受信メッセージが送信メッセージと異なるなら
        sendLoRaMessage(receiveMessage); // LoRaデータ送信処理関数
      }
    } else if (state == RADIOLIB_ERR_CRC_MISMATCH) {  // CRCエラーなら
      logPrint("CRC Error");  // CRCエラー表示
    } else {
      logPrint("Receive Failed: " + String(state)); // エラーコード表示
    }
    radio.setPacketReceivedAction(setReceiveFlag); // 受信割り込み再設定
    radio.startReceive(); // 受信再開
    receiveFlag = false;  // 受信フラグクリア
  }
  delay(50);
}
スポンサーリンク

6.サンプルプログラムの詳細

サンプルプログラムは「Nesso N1」と「UNIT-C6L」で共通で使用できるようにしています。

「UNIT-C6L」を使用する場合はサンプルプログラムの「5〜8行目」を以下のようにして書き込んでください。

// LoRa通信 SX1262ピン設定(CS, IRQ, NRST, BUSY)
// SX1262 radio = new Module(23, 15, RADIOLIB_NC, 19); // Nesso N1のピン設定
SX1262 radio = new Module(23, 7, RADIOLIB_NC, 19);  // Unit-C6Lのピン設定

#define MAIN_FONT &fonts::Font0 // フォント指定 ※C6LはFont0推奨

「LoRa無線通信」の通信設定はサンプルプログラムの「67行目」で以下のように設定しています。

// SX1262 通信設定(周波数 MHz、帯域幅 kHz、拡散係数、符号化率分母、同期ワード、出力電力 dBm、プリアンブル長、TCXO基準電圧、useRegulatorLDO)
int state = radio.begin(923.2, 125.0, 9, 5, 0x12, 13, 8, 3.0, true);
設定内容は日本の電波法を考慮しつつ、通信速度は遅くてもできるだけ長距離で安定した通信を想定して以下のようにしました。
・周波数:923.2Hz(日本の電波法920MHz帯で使用できる値、チャネル1を使用)
・帯域幅:125kHz(日本の電波法の200kHz以下対応のため)
・拡散係数:SF9(送受信速度は遅くても良いため長距離通信を想定して大きく)
・符号化率:CR=4/5(分母の数値を設定、5は速度重視)
・同期ワード:0x12(P2P通信の定番設定)
・出力電力:+13dBm(日本の電波法で設定できる最大値)
・プリアンブル長:8(速度重視、省電力設定)
・TCXO基準電圧:3.0V(Nesso N1デバイスの設定)
・useRegulatorLDO:true(有効、内部電源レギュレータの選択)

受信動作については「SX1262」の「IRQ:DIO1」端子を使用した割り込み処理を使用しています。
サンプルプログラムの「75行目」で以下のように、受信完了時の割り込み処理としてコールバック関数「setReceiveFlag」を設定しています。

radio.setPacketReceivedAction(setReceiveFlag); // 受信完了時のコールバック関数を設定

サンプルプログラムの「17〜22行目」でコールバック関数「setReceiveFlag」を実行して受信フラグを立てます。メインループでこのフラグを確認することで受信処理を実行するようにしています。

// 受信割り込みコールバック ************************************
void setReceiveFlag() {
  if (!isTransmitting) {  // 送信中でなければ
    receiveFlag = true;   // 受信フラグをセット
  }
}
radio.setPacketReceivedAction(setReceiveFlag); // 受信完了時のコールバック関数を設定

注意点として、送受信処理の前には以下のように受信割り込み受信処理を無効にしておく必要があります。

radio.clearPacketReceivedAction(); // 受信割り込無効化(送信中のゴースト受信割り込み対策)
radio.standby(); // 受信を停止
delay(10);       // 受信停止待ち
.
.
送信または受信処理
.
.
radio.setPacketReceivedAction(setReceiveFlag); // 受信割り込み再設定
radio.startReceive();   // 受信再開
SX1262 を RadioLib で使用する場合、受信割り込み(DIO1)は受信完了や CRC エラーなどのイベントを通知するため、送受信の切り替え時に割り込みが残っていると誤動作が発生します。
特に、送信中に受信割り込みが有効になっていると、自分の送信信号を誤って受信したと判断する「ゴースト受信」が発生することを確認しました。
このため、送信処理や受信処理を開始する前に、必ず受信割り込みと受信処理を無効化してから処理を実行する必要があります。
割り込みを明示的に停止し、処理完了後に再度受信を開始することで安定した動作を行うことができます。
LoRa無線は高速・大容量通信向けではなく、少量のデータを長距離へ確実に届ける用途に適した方式です。
また、LoRaは送信と受信を同時に行う仕組みではなく、片方ずつ交互に動作することを前提とした通信方式であるため、アプリケーション側で明確に送受信を切り替える設計が必要になります。

キャリアセンスを実施するなら

今回はシンプルな送受信処理のみの確認のため、キャリアセンスは実装していませんが、実際に行う場合は送信前に周囲の電波状況を電波強度(RSSI値)から確認します。

「RadioLib」では「radio.getRSSI()」を使うことで、現在の電波強度(RSSI値)を取得できます。

このRSSI値が 「−80dBm より小さい場合」は、その周波数が空いていると判断し、送信を開始し、「−80dBm 以上」の場合は、他の無線機が使用している可能性があるため、送信を待つ、または再試行するといった処理を追加します。

// 現在の周囲の電波強度を取得
float rssi = radio.getRSSI();
キャリアセンス時にも「ゴースト受信」の対策が必要と思いますので、実装の際は注意してください。
スポンサーリンク

7.まとめ

Arduino Nesso N1」を使用して、LoRa無線通信で送受信する方法をサンプルプログラムを使用して詳しく紹介しました。

Nesso N1」に搭載されている「SX1262」 は高感度かつ省電力で扱いやすい「LoRa トランシーバIC」ですが、日本の「電波法」についてよく確認して正しく使用する必要があります。

周波数チャネル、帯域幅、送信出力などのパラメータを正しく設定し、+13dBm 制限や 200kHz チャネル間隔、技適適合デバイスの使用といった日本の電波法に沿って運用することが重要になります。

LoRa無線通信制御用ライブラリ「RadioLib」を使えば「SX1262」の設定や送受信処理を簡単に扱えますが、受信割り込み(DIO1)の扱いには注意が必要です。

特に送受信処理時に受信割り込みを無効化しないと、自局送信を誤って受信したと判定する「ゴースト受信」が発生するため、処理前に必ず受信割り込みと受信処理を無効にしておくことが安定動作のポイントです。

今回の動作確認は「LoRaWAN」とは異なり、「LoRa の物理層(P2P通信)」ですが、独自プロトコルの開発や実験用途には十分な機能と柔軟性があります。

電波法に沿った適切なパラメータ設定と、送信時間は短く、送信間隔は十分に開けて、送信と受信を片方ずつ交互に行うことを前提とした通信方式であることを理解することで、安全かつ安定した 「LoRa無線通信」を実現することができます。

LoRa E220 + M5StickC Plus2で無線相互通信する方法
無線通信ユニットLoRaE220-JPとM5StickC Plus2でP2P長距離通信を実践。無線ユニットの使い方や初期設定から遠隔Lチカまで詳しく紹介します。

コメント

タイトルとURLをコピーしました