IM920/IM920sL で PC と PC 間で送受信してみる

# 趣旨

920MHz 帯通信モジュール IM920/IM920sL を二台の PC に USB 接続して、片方のPCからもう一方のPCにデータを送ります。

分かったら何も難しくはないんですけど、最初の設定が少しわかりにくいので、しばらく使わなくて忘れたときに、使い方を思い出すためのメモです。

なお**IM920sとかIM920sL**は、通信方法が異なっています。相互に通信はできません。これについては、後ろのほうに書いてます。

# IM920 基礎知識

- [IM920 本体] (https://www.interplan.co.jp/support/solution/IM315/manual/IM920_HW_manual.pdf)メーカーのページ
- [IM920 秋月の通販ページ](https://akizukidenshi.com/catalog/g/gM-09064/)
- [USBゲタ](https://akizukidenshi.com/catalog/g/gM-15824/) ← 最低、これも併せて買うべき。
- [Arduinoシールド](https://akizukidenshi.com/catalog/g/gM-10144/) Arduino UNO などにつなぐ用。
- [USBケーブル USB2.0 MINI（B)](https://akizukidenshi.com/catalog/g/gC-07606/) USB ゲタを買うなら USB MINI(B) (Micro(B) ではない) のケーブルを用意そておく。

IM920 モジュール本体は2列ハーフピッチコネクタという、初心者殺しコネクタになっていて、UART の線を引っ張り出すだけでも多分苦労します。とりあえず試したい場合は、ゲタも買ったほうがいいです。ゲタをつかえば、簡単に PC とつながります。Arduino などとつなげたい場合は、シールドを使います。

# PCと接続

ゲタにはめて、ネジ止めして、USB ケーブルでPCに接続します。USBコネクタはミニです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/8db0239c-8d97-1c84-7e8f-c57b64cfaf89.png)


# ターミナルを起動

TeraTerm のシリアル接続とかでいけます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/9556f9e8-7a31-93b9-d3be-1b0041a5ef3f.png)

上のような設定でいけるはず。

# モジュールとしてみる

TeraTerm のウィンドウ内で RDID (Enter) と入力すると、16進数で4桁の固有 ID がかえってきたら、正常に動作してます。

```
RDID
A0B1
```

こんなかんじです。A0B1 というのが固有IDです。固有IDは通信機ごとに異なるので、通信機ごとに違うIDが表示されるはずです。TeraTerm の場合はローカルエコーの設定をしないと、RDID のところは表示されません。

コマンドの文字列のターミネータは `\r` (CR/0x0D) です。`\n` (LF/0x0A) では反応しません。

# モジュール間で通信してみる

## 受信機ID の設定

IM920 は、固有 ID を使って通信機の識別をしてるぽいです。通信機には「受信機ID」というものを設定する必要があって、登録した受信機IDを（固定IDとして）もつ通信機から送られてきたパケットだけを受け取るようになっているようです。

そのため、最初に「自分がパケットを受け取りたい受信機ID」を登録しておく必要があります。

登録は SRID というコマンドで行えます。ただし、デフォルトではパラメータ書き込み不可状態になっているので、先にパラメータ書き込み可状態にしてから、受信機IDを書き換え、最後にまたパラメータ書き込み不可にします。

A0B0 を受信機IDとして設定する場合は、以下のような感じです。

```
ENWR
OK
SRID A0B0
OK
DSWR
OK
```

こんな感じになれば成功です。コマンドが失敗すると NG と出ます。



モジュールをそれぞれ別の PC （同じPC でもいい）に USB で接続して、それぞれ TeraTerm を開いて通信可能状態にしておきます。

## 通信する

- 通信機A (固有ID: A0B0): COM3 (TeraTerm接続) 
- 通信機B (固有ID: A0B1): COM4 (TeraTerm接続) 

このようになっているとして、A0B1 側に受信ID A0B0 を上記の手順で登録してあるものとします。

このとき、A0B0 側 (COM3) で TXDT コマンド + 送信したい16進数の文字列、を入力すると、A0B1 側に送信できます。

A0B0 側:

```
TXDT FF00A0B0
OK
```

A0B1 側:

```
00,A0B0,CC:FF,00,A0,B0,00,00,00,00
```

こうなります。受信側では、上のようにカンマ区切りした状態で受け取ることになります。戦闘の 00 は ノード番号、次の A0B0 は受信ID、次の CC は RSSI 値、その後ろに続く値が送信されたデータです。TXDT コマンドで送れるのは、最大 8byte だそうです。8byte 未満のデータを送ると、不足部分は自動的に 00 でパディングされます。

## NG がかえってくる

キャリアセンスとか待機時間というのがあって、その結果によって NG になることがあります。

電波法の関係上、一度データをおくると 52ms は連続では送れず、そのあとキャリアセンス(拘束モードで 500us / 長距離モードで 5.2ms)するため、それ以下のタイミングでは送れません。また、キャリアセンスに失敗するとえんえん送れないこともあります。あまり NG がでるようなら、周波数をかえてみると良いかもしれません。

ちなみに、すでに設定済みの受信機IDを再度設定しようとしても、NG になります。つまり、

```
SRID A0B0
OK
SRID A0B0
NG
```

こうなります。別のIDを指定するとOKになります。同じのでも OK でいいやん！

## 参考

細かい設定とかは、下記のドキュメントに書かれてます。基本、4文字の文字列＋空白＋パラメータ、というコマンドを使って操作する感じです。

- [IM920 ソフトウェア編] (https://www.interplan.co.jp/support/solution/IM315/manual/IM920_SW_manual.pdf)

まったく受信できないときは、受信IDの設定が間違っていないか、周波数の設定がそろっているか、TeraTerm などの通信ソフトの設定(ポート、通信速度)が間違ってないか、コマンド文字列の末端を \r (CR) にしているか、あたりを確認します。

# IM920sL で通信する

仕様がかなり変わっていて、IM920 との間では通信できなくなっています。

なお、下記のモジュールを使用する前提で書いてます。

- [マルチホップ対応９２０ＭＨｚ無線モジュール　長距離　屋内用小型外部アンテナ](https://akizukidenshi.com/catalog/g/gM-16428/)
- [ＩＭ３１５ＲＸ／ＴＲＸ・ＩＭ９２０／ｃ／ｓシリーズ用　ＵＳＢインターフェースボード](https://akizukidenshi.com/catalog/g/gM-15824/)：PCと接続するために必要です。

このほかに、USB-MINI のケーブルが必要です。

# PCと接続

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/84cf573a-7045-8e60-3408-eac133f28a62.png)

ゲタをネジで固定して、USB-MINI のケーブルで PC につなぎます。

ネジはM2です。8mm が推奨です。スペーサーは 3mm が必要です。ゲタに同梱されているネジは IM920 用なので、IM920sL を止めるには微妙に長すぎます。また、同梱されているスペーサーもサイズがあってません。

シリアル通信のデフォルトの設定は以下の通りです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/b13bf2e1-6a67-7081-9884-e92e7c689269.png)

- 19200bps
- 8bit
- parity: none
- stop bit: 1bit
- flow control: none

## 初期設定

通信機 A 側の受信機IDを 0001 にして、B 側の受信機 ID を 0002 にします。

### A 側（親機）

```
ENWR
OK
STNN 0001
OK
```

### B側（子機）

```
ENWR
OK
STNN 0001
OK
```

## グループ番号の設定

基本、IM920sL はグループ番号が同じノード間でしか通信できないようです。グループ番号の設定は、下記の手順で行います。

- 親機をひとつ決める。ID を 0001 にすると、自動的に親機になります。ID を 0002 以上にすると、自動的に子機になるようです。
- 子機で ENWR, DSNF コマンドを実行してある状態で STGN コマンドを実行する。OK と出た場合は、子機は親機からのグループ番号受信待ち状態になる。
- 親機で STGN コマンドを実行する。親機のグループ番号が自動的に設定され、なおかつ周期的に子機に対してグループ番号を送信する。
- 子機はグループ番号が受信できると、GRNOREGD というメッセージを出して、HALT 状態になる。そうなったら、電源を入れなおす。

これで設定できるようです。

電源を入れなおした後に、RDGN コマンドを使って、グループ番号が親機と同じになっていることを確認します。設定できていない場合は、子機で STGN コマンドを使うところからやりなおします。

子機側の設定ができた場合は、DSWR, ESNF として、書き換えを禁止しておきます。親機も DWWR としておきます。

ここまでできると、同じグループ番号が振られたノード同士であれば通信できるようになります。

なお、子機側は、親機とかなり近づけなければグループ番号が受信できません（セキュリティ的な配慮で、送信電力が低く設定されているようです）。数センチの距離でも、アンテナがついていないと受信できないことがあります。子機で STGN が NG になる場合は、ENWR か DSNF コマンドを忘れている可能性が大です。

## 通信

親機 (0001) から子機 (0002) に一対一通信をする。

```
TXDU 0001 12345678
OK
```

子機側は、受信できた場合下記のようになります。

```
00,0001,EA:12,34,56,78
```

TXDU コマンドは ACK を受け取った場合だけ OK を返します。

なお、デフォルト (DCIO 状態) では、送信文字列は「１６進数の数字を表す文字列」と解釈されます。上の場合は、0x12, 0x34,0x56,0x78 の 4byte のデータとして送信／受信されています。

DCIO/ECIO コマンドで、数値と解釈するのか、文字列をアスキーコードとして送信するか／受信するかを変更できます。この解釈は、送信側、受信側で個別に設定します。

TXDT コマンドを使えば、ブロードキャスト通信ができます。


```
TXDT 12345678
OK
```

受信側では下記のようになります。

```
00,0001,EA:12,34,56,78,00,00,00,00
```
TXDT コマンドは 8 byte 固定で、データ長が不足している場合は 0 でパディングされます。

なお、TXDT/TXDA コマンドは受信されたか否かに関係なく、OK を返してきます。NG になることもありますが、それはコマンド自体が実行できなかった場合のようです。

# 主要なコマンド一覧

|コマンド|引数|意味|
|---|---|---|
|ENWR| - |パラメータ書き込みを**可**にする|
|DSWR| - |パラメータ書き込みを**不可**にする|
|RDNN| - |ノード番号読み出し|
|STNN| 16進数4桁 |ノード番号設定（要ENWR）|
|RDGN| - |グループ番号読み出し|
|STGN| - |グループ番号設定（上記記事を参照のこと）|
|ESNF| - |スニファモード（モニタモードを有効にする|
|DSNF| - |スニファモードを無効にする|
|RDCH| - |通信チャンネル読み出し|
|STCH| 01-29/31-45 |通信チャンネル設定（要ENWR）|
|TXDU| 子機ID 送信データ | データを子機に送信する | 
|TXDT| 送信データ（8byte） | 固定長文字列を子機にブロードキャストする | 
|TXDA| 送信データ（1-32byte） | 文字列を子機にブロードキャストする | 
|ECIO| - |送信データをアスキー文字列と解釈する|
|DCIO| - |送信データを16進数の数値と解釈する|
|SBRT| 0-9 |シリアル通信速度設定 (4:19200bps)|
|RDRS| - |RSSI 値読み出し|
|RDID| - |固有ID読み出し|
|RDRM| - |パラメータ一括読み出し|
|RDVR| - |製品バージョン読み出し|
|SRST| - |ソフトウェアリセット|
|PCLR| - |工場出荷設定に全パラメータをリセット|


# おわり

グループ番号の細かな設定については、ちょっとややこしいので、下記の 12P や 45P 付近を読んでください。

- [920MHz 帯無線モジュール IM920sL シリーズ 取扱説明書 ](https://www.interplan.co.jp/support/solution/IM315/manual/IM920sL_manual.pdf)

グループ番号はデフォルトで FFFFFFFF になっているようですが、このままでは通信はできないようです。

大前提として、**グループ番号に任意の番号を指定できません**。親機としたノードに自動的に固定のグループIDが割り振られ、その番号を子機に STGN コマンドで送信して、設定することになります。

つまり、親機をなくしてしまうと、そのなくした親機を使って設定した、過去のグループIDは二度と設定できなくなる、ということです。そのような場合は、別のノードを親機に設定して、その親機のグループ番号を使って。すべてのグループ番号を更新しなおすなどの対処が必要になります。

セキュリティ的な観点からこうなっているのだと思いますが、大量のノードを移動、追加、削除させながら運用する場合にはかなり不便なので、もうちょっと何とかならなかったのかな、という気はしてます。（認識が間違っていたらご指摘ください）

ちなみに、ブロードキャスト通信は、親機以外でも（親機がネットワーク中に存在していなくても）送信できます。仮に、グループ番号を設定した親機をなくしても、同じグループ番号がすでに割り振られている子機同士であれば、いずれかの子機が送信機となって、ブロードキャスト通信をすることはできます。