第二十四項 無線制御

電子工作創作表現(2019/01/17)

スライドPDF

Wi-FiやBTだけではない無線

  • Wi-FiやBluetoothなどは安く便利だが、混線のリスクが高い
     
  • 他の無線で通信する方法
以前ESP-WROOM-02でWi-Fi接続ができるという話をしました。
Wi-Fiは既製品のルーターが使えるなど環境構築自体が安価で簡単になっていますが、出力もそこまで強くなく、一般的に使われている電波なので混線のリスクが高いです。
展示会や舞台など大勢の人が携帯電話やポケットWi-Fiを持って入る空間では特に混線のリスクが高まるため、信頼性が求められる状況では避けることが多いです。
今回は無線通信の基本から、Wi-FiやBluetooth以外の通信方式の紹介をしていきます。

無線通信で気にするべき要素

  • 伝送距離
     
  • 通信速度
     
  • 通信品質(繋がりやすさ)
有線を使わず無線と使う時というのは、ケーブルの取り回しが難しいという状況だと考えられます。まずどのくらいの距離まで届くのか。一般的にデータシート等に書かれている通信距離というのは何もない空間での理想的な環境条件における距離なので、実際に使いたい環境で届くのか試す必要があります。
やりとりする内容によっては通信速度も鍵になってきます。周波数が高いほど通信速度を上げることが可能になりますが、障害物などに弱くなってしまう傾向があり、繋がりやすさ=通信品質に影響してきます。

無線の特性を左右する「周波数」

  • 電波を使う無線通信は、周波数で住み分けをしている。単位は「Hz」
     
  • 船舶航空などは110~150MHzの低周波、BluetoothやWi-Fiは2.4GHzの高周波
これらの特性は、電波を発する時の周波数によって左右されることが多いです。単位は音と同じHzです。
船舶や航空機のように、公共の場で広く使われる周波数は110~150MHzのような低周波、逆に我々が使う無線は800MHz以上の高周波帯がよく用いられます。BluetoothやWi-Fiは2.4GHzがよく使われています。

電波と法律

  • ある機器がその周波数で電波を送信と、他の機器は同じ周波数を使うことが出来ない
     
  • 周波数や出力に法律規制がある。日本はかなり厳しめ
     
  • 海外のデバイスは「技適」があるか要確認
先ほど混線の話をしましたが、電波というのは同じ周波数を複数の通信で使うことはできません。そのため、誰かが勝手に使いだすとその電波が届く範囲の人たちは同じ周波数を使えなくなってしまうので、乱用を防ぐため周波数の使い道や出して良い強さが法律で定められています。船舶や航空無線のような帯域を扱うためには免許も必要です。

免許が不要な装置の場合でも、日本国内で電波を発する装置を使用するには、そのデバイスに対して総務省の許可が必要となります。これが「技適」と呼ばれるもので、このマークが無い装置の使用は基本的にNGです。最近の例で言うと、Raspberry pi4が発売されたのは2019年の6月でしたが、技適が登録され無事使えるようになったのは同11月からとなっています。

ただ最近法改正があり、技適の無いマークでも届け出をすれば実験目的で180日間に限り電波を発射することができるようにもなっているそうです。

電子工作向けの無線デバイス

  • 電子工作向けの無線デバイスがいくつか存在
     
  • 免許不要の「特定小電力無線局」
     
  • 2.4GHz帯か900MHz帯が多い
ということをふまえて、電子工作で扱う事の出来る無線デバイスをいくつか紹介します。
特定小電力無線局に該当する2.4GHz帯と、サブギガ帯と呼ばれる920MHz帯の2種類です。

無線モジュールのメリット

  • チャンネル等を細かく設定して干渉をある程度防げる
     
  • 「マルチホップ」など特殊な通信構成
     
  • プロトコルがシンプル
電子工作用の無線モジュールを使うメリットとして上げられるのが、チャンネル等を細かく設定することで機器同士の干渉などをある程度防げる、選択肢が多いこと。他にはマルチホップのように特殊な通信構成を組むことで効率よく安定した通信環境を構築することが出来るという事などが挙げられます。

Xbee/Twe-Lite

  • 近距離通信規格の「Zigbee」をベースにしたモジュール
     
  • 規制も緩く気軽に使えるが、人の多い場所では△
有名なモジュールとして上げられるのが「Zigbee」と呼ばれる無線規格の機能を搭載したモジュールで、XbeeやTwe-Liteなどがあります。
2.4GHzと900Mhz/800MHzの三種類がありますが、日本国内で使用が許されているのは2.4GHz帯のみなので、Wi-FiやBluetooth等の影響は避けられません。
一方でX-CTUという高機能なソフトウェアがあったり、入手性も良いので導入として始めるには丁度良いデバイスだと思います。ネット上にも情報がたくさん載っています。

IM920

  • 最大1㎞とかなり長距離通信が可能
     
  • 900MHz帯国内仕様なので、通信時間に制限がある
2つ目がIM920というモジュールです。こちらは920MHz帯を日本国内で使用できるように設定されたもので、通信時間が1時間のうち6分間(それでも1時間あたり2万回のやりとりが可能)と制限されていますが、開けたところであれば最大で1㎞程度の長距離通信が可能なデバイスです。
920MHzという帯域を使っているので2.4GHz帯より障害物にも強いということ、大勢の人がいる場所でも携帯電話のようなデバイスに影響されにくいというメリットがあります。

LoRaWan

  • LPWA(LowPowerWideArea)の一種
     
  • 間欠動作で長期間バッテリー動作する
     
  • IoT向けと言われている通信技術
最後はLoRaWanというLPWAの一種です。こちらも900MHz帯が使われており、間欠動作(必要な時だけ動作する機能)により消費電力を最小限に抑えるという働きがあります。
作品やパフォーマンスというよりは畑で土壌の温度を数時間おきに計測して送信するといった実用向きな仕様ではありますが、考え方次第で面白い使い方ができると思います。

IM920の接続

  • 送信機と受信機の回路構成は同じ 
     
  • 送信側と同じ色に光る
今回はIM920のデモをやってみます。IM920に接続するのに最低限必要なのは電源とGND・そしてシリアルのTX/RXです。
NeoPixelを追加して赤→緑→青…と色の変化が同期するようにしました。

送信側

  • 通常のUSBとのシリアル通信のように送る
     
  • IM920のプロトコルに従ってデータを送信する
前回のDMXと同様に、Arduinoの0/1番ピンからシリアル通信でやりとりを行います。送ってほしいデータをIM920にリクエストをすると、そのデータを解釈して通信範囲のデバイス全体、もしくは特定のデバイスに向けて送信してくれるのでデータシートを読みながら必要なコマンドを実装する必要があります。
#include <Adafruit_NeoPixel.h>
Adafruit_NeoPixel pixels(1, 6, NEO_GRB + NEO_KHZ800);

String mes = "";

void setup() {
  Serial.begin(19200);
  pixels.begin();
}

void loop() {
  int dl = 500;
  //01,02,03...という順番で1バイトの数値を送っている。txdaは全体に送信するコマンド
  delay(dl);
  Serial.print("txda 01\r\n");
  pixels.setPixelColor(0, pixels.Color(50, 0, 0));
  pixels.show();

  delay(dl);
  Serial.print("txda 02\r\n");
  pixels.setPixelColor(0, pixels.Color(0, 50, 0));
  pixels.show();

  delay(dl);
  Serial.print("txda 03\r\n");
  pixels.setPixelColor(0, pixels.Color(0, 0, 50));
  pixels.show();
}

受信側

  • シリアル通信として受信
     
  • 送信元のノード、受信データの電波強度が付加される
受信側も同様にシリアル通信でデータを受け取るので、USBシリアルをする時などと殆ど処理は変わりません。送信側では「txda 01」というデータを送りましたが、受信される時には、「ヘッダー・送信元のノード・受信データ」の要素が追加された状態でArduinoまで届けられるので、その情報をパースしてあげる必要があります。
#include <Adafruit_NeoPixel.h>
Adafruit_NeoPixel pixels(1, 6, NEO_GRB + NEO_KHZ800);

String mes = "";

void setup() {
  Serial.begin(19200);
  pixels.begin();
}

void loop() {
  while (Serial.available() > 0)
  {
    byte bt = Serial.read();

    //来るデータにはダミー、送信元ID、電波強度の情報が入っているので、実際の情報は12文字目以降に含まれる
    if (bt == '\n') {
      if (mes.substring(12, 13) == "1") pixels.setPixelColor(0, pixels.Color(50, 0, 0));
      if (mes.substring(12, 13) == "2") pixels.setPixelColor(0, pixels.Color(0, 50, 0));
      if (mes.substring(12, 13) == "3") pixels.setPixelColor(0, pixels.Color(0, 0,  50));
      mes = "";
      pixels.show();
    } else {
      mes += char(bt);
    }

  }
}

touchdesignerで受信

  • Arduino Leonardでパススルー
     
  • 直接シリアル変換を付けても良い
文字列のやりとりなので、Touchdesignerに接続することも勿論可能です。今回はArduinoLeonardで受けたシリアル通信をそのままTDに流し込みます。ArduinoUNOの場合はUSBのシリアルとTX/RXは同じラインなのでどちらか片方しか使えませんが、Leonardの場合0/1番ピンはSerial1という別のラインになっているので、シリアル通信を使いながらUSBシリアルでPCともやり取りするという小技が可能になっています。
void setup() {
  Serial1.begin(19200);
  Serial.begin(19200);
  pixels.begin();
}

void loop() {
  while (Serial1.available() > 0)
  {
    Serial.write(Serial1.read());
  }
}

serialDATで文字をパース

  • Arduino内で処理していた物を再現
     
  • Serial DATのコールバックで処理する
IM920から来るデータをTouchdesignerで受け取り、Pythonで解釈します。1,2,3という番号をRGBに割り当てているので、それに応じた条件分岐をしてTOPの色に割り当てています。
def onReceive(dat, rowIndex, message, bytes):
    op('constant1').par.colorr = 0
    op('constant1').par.colorg = 0
    op('constant1').par.colorb = 0

    if message[12] == '1':
        op('constant1').par.colorr = 1

    if message[12] == '2':
        op('constant1').par.colorg = 1

    if message[12] == '3':
        op('constant1').par.colorb = 1

    return

参考:https://tony-mooori.blogspot.com/2017/03/im920arduinoarduino.html