920MHzに比べると国技館のBluetoothはカスや
<< 前:学生向けFixstars高速化コンテスト2024参加記 by kogetsu0728
>> 後:KotlinでBukkitプラグインを書く by toma09to
木更津高専 Advent Calendar 2024 14日目担当のこかすた〜です。今年2回目の登場です。
はじめに
木更津高専ロボット研究同好会は、高専ロボコン2024 全国大会でデザイン賞を受賞しました!!
そして、今年は無線通信にIM920sLを使用した無線通信を導入しました。今回は、そのチュートリアル的な記事を書きます。
この記事を読む前に
偉そうに記事を書いていますが、僕も今年が初めて使用したため、全ての機能を使えるようになっているわけではありません。そのため、「とりあえずこれで国技館で動いたよ~」という話になっています。
もしより良いモードをご存じの方がいたら、是非コメントで教えていただけると幸いです。
「Bluetoothはカスや」の真意
人込みの中でイヤホンを使っていたら接続が悪くなった経験はないでしょうか? これは、混線が発生しているためです。
Bluetoothが使用する2.4GHz帯というのはスマートフォンをはじめとする様々な機器で使用されています。しかし、その割にチャンネル数が少ないため、混線しやすいのです。これは国技館でも例外ではなく、これが原因でロボットが正常に動作せずに敗退してしまうチームもいます。これが、「Bluetoothはカスや」の真意です。
この記事は、そんな2.4GHz帯の混線の代表格ともいえるBluetoothから脱却したい人たちの参考にしてもらうために書きました。
920MHz帯の概要
920MHz帯は、特定小電力無線として免許不要で使用できる周波数帯(315MHz, 400MHz, 920MHz, 1200MHz)の1つです。特徴として、400MHzや2.4GHzよりも広い帯域であることや、伝送距離が長いことがあります。
920MHz帯全てが免許不要であるわけではなく、いくつかの区分に分かれていますが、今回紹介するIM920sLは免許不要で使用できます。
IM920sLとは?
IM920sLとは、interplan社から販売されてる無線モジュールで、920MHz帯を使用して通信します。扱うのが簡単なので、高専ロボコンでも様々なチームが採用しています。
UARTを使ってコマンドを送ることで使用できます。
今回作るもの
今回は、Arduino UNO R4間で一方向に数字を送信するプログラムを作成していきます(R4以外のUNOでも可能です)。
これを応用することで、
- コントローラーの入力をマイコンで受け取り(USB Host Shield等)、数字に変換
- IM920sL(コントローラー側)で送信
- IM920sL(ロボット側)で受信
- 数字から入力データに変換する。
という流れで920MHz対応ができます。
準備するもの
全部マルツで買えます。
IM920sL
今回使う無線モジュールです。モジュールにはユニークなIDが書いてあり、これを使って相手を識別してペアリングを行います。
変換アダプタ
IM920sLの変換アダプタです。IM無線シールドとの接続に使うほか、ブレッドボードに刺して使うときなどにも使える気がします。
IM無線シールド
変換アダプタをArduino UNOに刺せるようになります。
ノイズの関係もあるので避けるべきですが、IM920sL/変換アダプタに高さがあるので、普通のHost Shieldはこの上に重ねることができません。
USBインターフェースボード
Im920sLとPCの間でUSBを使ったシリアル通信ができるようになります。これは2個あると良いです。
これがなくても、変換アダプタのピンとUSBのRX/TXを適切につなぐことで書き込めますし、Arduinoからコマンドを送る方法でも代用できます。ただ、USBで繋げたほうがペアリング等で楽です。
A to MiniBケーブル
USBインターフェースボードとPCを接続するために使用するケーブルです。Nucleoとの通信で使うぐらいの中々使わない規格です。僕は、秋葉原の最終処分場で100円だったかで買いました。
Tera Term
シリアル通信のターミナルと言ったら定番のソフトです。シリアル通信をします。ここからダウンロードできます。
Linuxの方もたくさんいると思いますので、そのような方は各自で準備していただければと思います。
IM920sLをペアリングする
この章では、PCと接続してペアリングする作業を行います。
少しめんどくさいですが、マイコンから接続して同じ処理を行うことでも可能です。
PCと接続する
まずは、IM920sLをUSBインターフェースボードに取り付けます。変換アダプタをつけてもつけなくても取り付けられるような仕様になっています。
取り付けたら、USBをPCと接続します。その後、Tera Termで「設定」→「シリアルポート」と進み、以下の設定で「新規オープン」します。
項目 | 値 |
---|---|
ポート | 接続したポート |
スピード | 19200 |
データ | 8bit |
パリティ | none |
ストップビット | 1bit |
フロー制限 | none |
また、「設定」→「端末」から、以下の項目の設定を変更します。
項目 | 値 |
---|---|
改行コード 受信 | AUTO |
ローカルエコー | チェックを入れる |
これで設定は完了です。ターミナルに「SRST」と入れてEnterを押してください。
SRST
IM920sL Ver.01.07
このような表示が出たら成功です。このコマンドは、IM920sLにリセットをかけるコマンドです。
送信側のセットアップ
送信する側のIM920sLに対して、送信側であるとする設定を行います。
まずは、書き込みを許可します。
ENWR
OKが返ってくれば正常です。次に、ノード番号を0001にセットします。親機であることを識別させます。
STNN 0001
これもOKが返ってくれば完了です。
受信側のセットアップ
受信する側のIM920sLに対して、受信側であるとする設定を行います。
まずは、同様に書き込みを許可します。
ENWR
次に、ノード番号を0002にセットします。
STNN 0002
OKが返ってくれば、OKです。
ペアリングをする
両方のIM920sLに同時に接続します。Tera Termを2個開くことで可能です。
また、極めて短距離でないとペアリングできない仕様なので、親機と子機を隣り合わせで置いてください。
親機に対して、以下のコマンドを入力します。
STGN
次に、子機に対して以下のコマンドを入力します。
STGN
双方OKが返ってくれば、ペアリングが始まります。子機側で
GRNOREGD
と表示されれば、成功です。成功したらUSBケーブルを一度PCから抜いて、もう一度刺しなおしてください。
設定を確認する
親機の方の設定を確認してみます。
RPRM
を打つと、ずらっと設定が出てきます。今回注目するのは上の方です。
RPRM
ID:********
STNN:0001
STGN:********
STRT:1
STCH:01
IDは、固有のIDです。IM920sLの表面、S/Nの右にある数字を16進数表記したものです。
STGNは、先ほど設定したノード番号です。1番であり親機になっているのがわかります。
STGNは、親機のIDです。今回は自身が親機ですので、IDと同じものになってると思います。
1つ飛ばして、STCHは使用チャンネルです。これは、最後の方で解説します。
次に、子機の方でも同じことをします。
RPRM
ID:********
STNN:0002
STGN:********
STRT:1
STCH:01
STNNが2になっていれば正常です。また、STGNは先ほど確認した親機のIDになっているはずです。
これを確認出来たら、IM920sLのペアリングは完了です。逆にこれが正しく設定できていなければ、もう一度ペアリングしてみてください。
テストで送信してみる
親機側で以下のコマンドを入力してください。
TXDA 20241214
OKが返ってきたら送信完了です。また、子機を見ると
00,0001,E8:20,24,12,14
のようにデータが飛んできていると思います。これで、920MHzによる送信ができました。
今度は、これをマイコンで実装します。
ArduinoにIM920sLを取り付ける
IMホストシールドに取り付けます。写真の通りです。
IMホストシールドは、使用するピンを変えることができます。3種類用意されており、以下の表のとおりです。
はんだづけ箇所 | TxD | RxD | BUSY | CTS |
---|---|---|---|---|
1,2,3,4 | D8 | D9 | D10 | D11 |
5,6,7,8 | D0 | D1 | D2 | D3 |
9,10,11,12 | A4 | A5 | A3 | A2 |
5,6,7,8のピンをはんだ付けした場合は、ハードウェアシリアルを使用できます。また、それ以外の場合はソフトウェアシリアルを使うことになります。
ほかのピンとの兼ね合いを考えて、必要な個所をはんだづけしてください。初期状態では1,2,3,4がはんだづけされていると思います。
なお、Arduino UNO R4からはUSBのシリアルとD0,D1のシリアルが分離されました。その場合5,6,7,8がかなりおすすめです。
Arduinoで通信を実装する
今回は、Arduino R4 Minima/WiFiを使用し、ハードウェアシリアルを使って通信を行うプログラムになっています。そのため、Serial1
を使用していますが、R3以前はUSBのシリアルと同一であるため、Serial
に読み替えてください。
また、その他のピンを使う場合、ソフトウェアシリアルを使用します。Serial1
をIM920sLSerial
に読み替えてください。
送信側
1秒に1回数字を送信するプログラムです。
//1,2,3,4を使用している場合----------
#include <SoftwareSerial.h>
SoftwareSerial IM920Serial(8, 9);
//---------------------------------
//9,10,11,12を使用している場合--------
#include <SoftwareSerial.h>
SoftwareSerial IM920Serial(18, 19);
//----------------------------------
void setup(){
Serial1.begin(19200);
delay(1000);
while(Serial1.available()){
char c = Serial1.read();
Serial.print(c);
}
delay(500);
}
int cnt = 0;
void loop(){
Serial1.print("TXDA "); // IM920sL 送信コマンド
String hexString = String(cnt, HEX); //送信データを16進数に変換
while (hexString.length() < 8) { //前を0埋めして桁を揃える
hexString = "0" + hexString;
}
Serial1.print(hexString); // アナログ値を HEX フォーマットで送信
Serial1.print("\r"); // CR 1 文字を送信
cnt++;
delay(1000);
}
受信側
1メッセージ分の長さが来たら、適宜数字を表示します。
void setup() {
//結果表示用
Serial.begin(19200);
Serial1.begin(19200);
delay(1000);
while(Serial1.available()){
char c = Serial1.read();
Serial.print(c);
}
}
void loop() {
if(Serial1.available() >= 12){ //1つ以上データが届いていたら
String buf = Serial1.readStringUntil('\r'); //改行コードまで読み込み
if(buf.substring(4,8)=="0001"){ //親機からの受信であれば
//2番目の':'以降をいい感じに分割
String received = buf.substring(buf.indexOf(':')+1,buf.length());
char c[10] = {'\0'};
int idx = 0;
for(int i=0;i<received.length();i++){
if(received[i]!=','){
c[idx] = received[i];
idx++;
}
}
int result = strtol(c,NULL,16); //結果がここに格納される
Serial.println(result);
}
}
}
その他
周波数を変える
以下のコマンドの**にチャンネル番号を入れることで変更ができます。これを送信側と受信側の両方で行えば、通信ができるはずです。
チャンネル番号はIM920sL独自の番号が付与されているので、データシートで確認が必要です。データシートは、メーカーのページから入手可能です。
STCH **
動作がおかしい
IMシールド上にあるリセットボタンやArduinoのリセットボタンを押してもリセットされない場合が多いです。そのため、マイコンの電源を落としたりUSBケーブルを抜いたりして電源を落とすことが、最善策になる場合が個人的には多かったです。
その他コマンド
- 設定リセット
PCLR
- 書き込み禁止
DSWR
- IDの確認
RDID
最後に
この記事が920MHzの導入をしたい人への助け舟になれたら、幸いです。
ここで紹介したプログラムは割り込みを使っていませんので、安定して使うには工夫が必要かもしれません。ただ、今年は一応これを発展させる形のプログラムで通信ができたので、これだけでも使えるのではないかなと思っています。
Discussion