masato-ka's diary

日々思ったこととか、やったことの備忘録。

Wio LTEとRN4020を使ってBLEゲートウェイ化からのSORACOM Harvestで可視化する。

この記事について

先日SORACOMさんとSeeedさん主催の「Wio LTE ユーザイベント」と言うイベントに参加しました。その際に、会場で販売されていたWio LTEを購入したので、利用のレポートとしてこの記事を紹介します。今回はWio LTEとRN4020を接続してBLEセンサビーコンの温度情報をSORACOMのデータ可視化サービスであるSORACOM Harvestで可視化してみました。てんこ盛りの内容のようですがとても手軽に実現できます。

soracom.connpass.com

Wio LTEについて

Wio LTEArduino互換(Arduino IDEでソフトウェアが書ける)でSORACOMのSIM が刺さり単体でLTE通信ができます。また、Groveコネクタで外部のセンサや機器と接続できます。主な端子として Digital Analogの入出力端子、I2C UARTを搭載しています。Seeedさんが製造しており、日本ではSORACOMさんから購入することができます。単体の価格は9800円(税別)です。もちろん技適も通っており、LTE通信を使いセンサデータを送りたい場合には最も簡単なボードになると思います。

soracom.jp

Wio LTEの一般的な使い方はGroveコネクタにセンサを接続して、LTE経由でデータを送受信する使い方になります。今回はWio LTEに直接センサをつながずにBLEのゲートウェイとして利用します。

全体の構成

全体の構成は以下の写真のようになっています。Wio LTEのUART端子に無理やりRN4020を接続しています。また、白いものが[BLEのセンサビーコン、[Wx2Beacon]e(http://masato-ka.hatenablog.com/entry/2017/09/12/223129)です。RN4020とWx2Beaconの詳細についてはそれぞれ過去記事参照ください。 Wio LTEはシリアル経由でRN4020を操作します。RN4020はWio LTEからの指示を受けて、一定時間ごとにセントラルとしてWx2Beaconに接続し、最新のセンサ値を取得します。その後、Wio LTE側でセンサ値をデコードし、SORACOM Harvestに送っています。

f:id:masato-ka:20171212083212j:plain

  • SORACOM Harvestで可視化した温度データ。

f:id:masato-ka:20171212082230p:plain

ソースコードは以下のリポジトリに上がっています。 github.com

以下、ソースコードをかいつまんで紹介します。

RN4020との接続

過去記事で紹介したシリアルからRN4020をセントラルで使う方法をWio LTEのGrove側のシリアルから実行しただけです。Wio LTEとRN4020の結線ではRXとTXはクロスに接続してください。

masato-ka.hatenablog.com

GroveのシリアルはSerialとなります。SerialUSBはPCと接続しているUSBケーブルに割り当てられており、コンソール出力として使っています。

double get_temprature(){
  SerialUSB.println("### Connect to periferal");
  Serial.println("E,1,E6E4B1DA83BC");
  delay(2000);
  trashSerialBuffer();
  SerialUSB.println("#### Read data");
  Serial.println("CHR,0019");
  delay(500);
  copySerialBuffer(buffer);
  String raw_data = String(buffer);
  #ifdef PRINT_DEBUG
    SerialUSB.print("Dump raw_data: ");
    SerialUSB.println(raw_data.substring(2,40));
  #endif
  String data = raw_data.substring(2,40);
  double temp = templature(data.substring(2,6));
  #ifdef PRINT_DEBUG
    SerialUSB.println(temp);
  #endif
  SerialUSB.println("#### Disconnect");
  Serial.println("K");
  delay(500);
  trashSerialBuffer();
  return temp;
}

取得したセンサデータの変換

RN4020から取得されたデータは以下のような形式になっています。先頭のR,と終わりの.はバリです。それ以外は16進数表記の文字列です。つまり2文字で1byteの扱いとなります。またリトルエンディアン表記となります。

R,038C081D14070002007127420D7D1A5907650B.

Wx2Beaconの温度データは2バイト目と3バイト目に格納されています。つまりこの場合"8C08"が温度データに該当します。さらにリトルエンディアンですので"0x088C"となります。これを10進数に変換して0.01をかけると温度の値(セルシウス度)となります。以下が、変換の一連のコードです。上記のコードのようにtemplatureに文字列を渡すと変換できます。

int hex_format_char_to_decimal(const char* hex_char){
  #ifdef PRINT_DEBUG
    SerialUSB.println(hex_char);
    SerialUSB.println(sizeof(hex_char));
  #endif
  if(sizeof(hex_char) != sizeof(char)*4){return -1;}
  int result = 0;
  int base = 0;
  for(int i=0; i < 2; ++i){
    if(65 <= hex_char[i] && hex_char[i] <=70){
     result += hex_char[i]-55;
    }
    if(48 <= hex_char[i] && hex_char[i] <= 57){
     result += hex_char[i]-48;
    }
    base = (16*(1-i)==0)? 1 : 16*(1-i);
    result *= base;
  }
  #ifdef PRINT_DEBUG
    SerialUSB.println(result);
  #endif
  return result;
}


int hex_format_str_to_decimal(String str){
  #ifdef PRINT_DEBUG
    SerialUSB.println("raw:" + str);
    SerialUSB.println(str.length());
  #endif
  if(str.length() != 4){
    SerialUSB.println("break");
    return -1;
  }

  int lsb = hex_format_char_to_decimal(str.substring(0,2).c_str());
  int msb = hex_format_char_to_decimal(str.substring(2,4).c_str());
  if(msb == -1 || lsb == -1){return -1;}
  return (msb<<8) + lsb;
}


double templature(String raw){
  return hex_format_str_to_decimal(raw.c_str()) * 0.01;
}

SORACOM Harvestへの接続

SORACOM Harvestへの接続はWioLTEのサンプルコード通りです。そちらを参考にしていただいた方が良いと思います。 UDPのソケットを開き8541に送りつけます。ユーザやSIMの設定はSORACOMの管理画面から設定しているため不要のようです。これだけで マネージドな可視化サービスに遅れるのは非常にすぐれものです。

void send_to_harvest(char *data){
  int connectId;
  SerialUSB.println("### Open.");
  connectId = Wio.SocketOpen("harvest.soracom.io", 8514, WIOLTE_UDP);
  if (connectId < 0) {
    SerialUSB.println("### ERROR! ###");
    return;  
  }

  SerialUSB.println("### Send.");
  SerialUSB.print("Send:");
  SerialUSB.print(data);
  SerialUSB.println("");
  if (!Wio.SocketSend(connectId, data)) {
    SerialUSB.println("### ERROR! ###");
    return;
  }

  SerialUSB.println("### Receive.");
  int length;
  do {
    length = Wio.SocketReceive(connectId, data, sizeof (data));
    if (length < 0) {
      SerialUSB.println("### ERROR! ###");
      return;
    }
  } while (length == 0);
  SerialUSB.print("Receive:");
  SerialUSB.print(data);
  SerialUSB.println("");

  SerialUSB.println("### Close.");
  if (!Wio.SocketClose(connectId)) {
    SerialUSB.println("### ERROR! ###");
    return;
  }
}

動作の全体像。

これまで紹介したメソッドはloopメソッドで以下のように使われています。 

void loop() {
  char data[100];
  
  double temp = get_temprature();
  sprintf(data,"{\"temp\":%.1f}", temp);
  SerialUSB.println(data);

  send_to_harvest(data);
  
  delay(600000L);
}

まとめ

Wio LTEは簡単にネットワークにつなげ、SORACOMのサービスを使うライブラリも充実しているので、LTE環境で何かしようとする際にはとても強力なツールになりそうです。また、RN4020とつなぐことでIoTゲートウェイっぽい使い方ができるので、利用シーンも広がりそうです。今年の冬休みの工作にいかがでしょうか。またWx2Beaconの温度データだけ使いましたが他にもセンサがついてるので多くの情報の可視化にチャレンジしたいです。

RN4020をBLEセントラルとして利用する。

この記事について

この記事ではRN4020をBLEセントラルデバイスとして利用し、BLEのペリフェラルバイスとやりとりするための方法を紹介します。これまではRN4020をペリフェラルバイスとして利用してきましたが、RN4020自信はセントラルとしても動作することが可能です。

masato-ka.hatenablog.com

RN4020のセントラルとしての利用方法

セントラルとして活用するには以下の方法で行います。

1. セントラル動作モードの設定

RN4020をセントラルとして活用するためにはSRコマンドで動作モードを変更するだけで利用できます。

SR,80000000
R,1

以上でRN4020がセントラルデバイスとして動作始めます。

2. デバイスの検索

続いて、ペリフェラルバイスの検索を行い、接続したいデバイスを発見します。今回は接続対象のデバイスとしてWx2Beaconを利用します。Wx2Beaconの詳細については以下の記事を確認してください。

masato-ka.hatenablog.com

ペリフェラルバイスの検索を行うためにはFコマンドを実行します。以下のように結果が表示されます。

F
62CEEEEE4D99,1,,,-4E
579E9EEEE4DB,0,,11111101C75C5666666A678911111111,-52
E6E4B1DA83BC,1,,,-14
FEA458B80011,1,,,-43

データは「,」区切りのデータとして出力れます。先頭がデバイスのUUIDとなります。また、2つ目はアドレスの種類を表します。接続のために必要になるためこの2つを控えておきます。一番最後がRSSI(電波強度)となります。目的のデバイスをRN4020に最も近づけておき、一番値が大きい(ここでは-14)デバイスを探すとわかりやすいです。今回は「E6E4B1DA83BC,1」を値として記録しておきます。

目的のデバイスが見つかったらXコマンドを使いスキャンを停止します。

3. デバイスへの接続 

目的のデバイスが見つかったらEコマンドを使い接続します。デバイスの検索で記録した「E6E4B1DA83BC,1」を使い接続します。

E,1,E6E4B1DA83BC
AOK
Connected
ConnParam:0028,0004,0190

バイス検索時とは逆に入力します。接続を切断する場合はKを実行します。

K
Connection End

4. キャラクタリスティックの操作

サービス又はキャラクタリスティックの検索はペリフェラルとして利用するのと同様LS又はLCを利用します。ペリフェラルとして利用するときは自身に設定されたサービスとキャラクタリスティックを表示していましたが、セントラルとして動作する場合は接続先デバイスのサービスとキャラクタリスティックを表示します。  今回の場合は以下のように表示されます。

LC
180A
  2A29,000E,02
  2A24,0010,02
  2A25,0012,02
  2A27,0014,02
  2A26,0016,02
0C4C3000770046F4AA96D5E974E32A54
  0C4C3001770046F4AA96D5E974E32A54,0019,02
  0C4C3001770046F4AA96D5E974E32A54,001A,10
  0C4C3002770046F4AA96D5E974E32A54,001C,02
  0C4C3003770046F4AA96D5E974E32A54,001E,0A
  0C4C3004770046F4AA96D5E974E32A54,0020,02
  0C4C3005770046F4AA96D5E974E32A54,0022,02
  0C4C3006770046F4AA96D5E974E32A54,0024,02
  0C4C3006770046F4AA96D5E974E32A54,0025,10
END

WxBeacon2の場合は 0C4C3001770046F4AA96D5E974E32A54,0019,02センサデータを読み出すことができます。先頭からUUID,HandleID,パーミッション(0x02はRead)となっています。このキャラクタリスティックに対してCHRコマンドでデータを読み出します。UUIDではなく、HandleIDを使うことに注意してください。

CHR, 0019
R,038C081D14070002007127420D7D1A5907650B.

対象のデータが取れました。これをデコードすることでWxBeacon2のセンサ情報を取得できます。Arduinoなどのマイコンを使うことで簡単にBLEセントラルデバイスを構築できそうです。

Web Bluetooth API とRN4020のワークショップを開催しました。

この記事について

 この記事では2017/10/20に開催したWeb Bluetooth APIとRN4020のワークショップの模様を記録しています。このワークショップでは以下過去記事の内容をベースに実際に皆さんにWeb Bluetooth APIを使ったアプリケーションとRN4020を使ったBLEデバイスの開発を体験していただきました。

masato-ka.hatenablog.com

募集時のconpassページは以下です。

connpass.com

開催の経緯と目的

このハンズオンはBLE周りのライブラリ情報を集める中で、Web Bluetooth APIと言うウェブブラウザからBLEを制御できるAPIを知ったことがきっかけです。Web Bluetooth APIで簡単にアプリが作れるなら、それに対向してデバイス側も 簡単に作れるものがないかなと探し当てたのがRN4020でした。  この2つで何かやってみたいなと思ったのと、前々からイベントを企画してみたいと考えていたので今回のワークショップを企画しました。  このワークショップを通して、BLE開発の敷居がぐっと下がってきたことを参加者の方に体験いただければよかったと思います。また、自分自身の知識の整理もやっていく予定でした。

開催模様

ワークショップ会場について

今回は友人の@atottoさんに場所を手配いただき、GROOVE X様のセミナールームをお借りすることができました。GROOVE X様はあのPepperの生みの親である林要さんが創業された会社でロボット界隈注目のスタートアップ企業です。社屋や会議室もとてもお洒落な場所でした。写真は入り口でこの裏手にセミナー会場が隠れています。お洒落。

f:id:masato-ka:20171020214426j:plain

ワークショップ内容につてい

今回のワークショップではBLEの基本やWeb Bluetooth API, RN4020の基礎知識を知ってもらう知識説明を30分実施した後、RN4020を利用したデバイス開発とWeb Bluetooth APIを利用したサンプルアプリケーションの開発を行いました。資料はGitHubWikiページで作成し、以下の通りとなっています。

ハンズオン資料へのリンク

Home · masato-ka/bel-key-security-app Wiki · GitHub

全体でハンズオン実施者は6名でしたがそのうち最後まで完了した方が3名、2章のデバイス開発まで完了した方が3名でした。完了しなかった方の大半はWindows PCを利用されていたため、Web Bluetooth APIの機能を確認する手間がかかっていたのが原因のようです。演習時間はおおよそ90分程度でした。

f:id:masato-ka:20171020203545j:plain

実際に回路を組み立てている様子です。資料の実体配線図に沿ってブレットボード上で組み立てを行います。

f:id:masato-ka:20171020203550j:plain

みなさん、デバイスが動くところまで到達したため、BLE開発の敷居が下がったことを理解してもらう点では概ね目的を達成できたかと思います。

反省点

実際に開催してみてよかった点や悪かった面です。

良かった点

主だってよかった点は以下のところです。

  • 動画を使い完成した時の映像を見せられた。
  • GitHubWikiでハンズオン資料を作成した。
  • 良い会場を借りられたこ
  • ハンズオンの資材セットがほぼはけた
  • 時間配分

 今回は資料をGitHubWiki ページで作成しました。間違いが発覚してもその場でコミットして共有するということができました。演習中誰かが見つけた間違いを共有できますし、ハンズオン後も共有できるので非常に便利です。またハンズオンの部品は自腹購入していたのですが、みなさん気に入っていただけた様子で引き取っていただくことができました。この辺は参加者の方に興味を持ってもらうことに成功した証ではないかなと思っています。  今回演習時間は90分でしたが達成率は50%でした。また未達成の方の離脱理由を考えると演習時間としてはちょうど良いか少し短めだと思います。平日夜開催という制約を考えるとちょうどいい時間ではないかと思いました。

悪かった点

逆に悪かった点

  • 演習中に記載漏れに気づく
  • 事前知識が必要な資料構成
  • そもそもWeb Bluetooth APIの実行環境がない人が数名いた。

演習中に資料の記載漏れに気づく点が幾つかありました。良い点であげた通りその場で修正できたのでしが、そこで少し時間を取られていたのでその点はチェックの甘を反省しています。また、回路の組み立てなど部品の詳細な説明がなかった点が気になります。今回の参加者はたまたま回路について知識のある方が多かったため問題ありませんでしたが、そうでない方には少し難しい内容だったかと思います。Web Bluetooth APIの方ではそもそもコピペで動くようにしていたので問題ないと思いますが、Angular.jsやJavaScriptの説明は必要だったかもしれません。また手持ちの環境でWeb Bluetooth APIの環境をお持ちでない方が数名いらっしゃいました。まだまだ対応環境が限られるためこの辺りも課題があると思います。

今後に向けて

 今回は参加者のバックグラウンドに助けられた面もありますが、もう少し内容を整理しないと継続は難しいかなという印象です。Web Bluetooth APIの対応環境を持ってな方でも試せるような事前の環境作りをしたり、参加者のスキル要件をもっと明確化するなど対応が必要かもしれません。  次回開催は未定ですが、別の内容をするにせよまた何かしら実施したいと思っています。その際は今回の反省を踏まえて開催したいです。

RN4020でI2Cの値を読み取る

この記事について

この記事ではRN4020のI2Cを利用する方法について紹介します。RN4020にはI2Cポートが付いています。EEPROMなどを接続しデータを一時的にためておくために利用できます。もちろん他のマイコンと同じようにI2Cポートをもったセンサを接続することができます。そこで、RN4020のI2Cポートに温湿度センサを取り付けて動作させてみました。

RN4020のI2C仕様について

 RN4020は21Pinと22PinがI2Cのポートとなっています。データシート上では21PinがSDA, 22PinがSCAになっていますが、実際には22PinがSDA, 21PinがSCAと逆になっています。(2017/10/16現在)秋月電子のボードも他のブレークアウトボードもデータシートにならって軒並み逆に記載されています。そのため基板の印字と回路図を比較する必要があります。おそらく逆につければ大丈夫です。I2Cバスのプルアップ抵抗はRN4020についていないません。そのため、センサモジュールについていなければ別途つける必要があります。ロジックレベルは3.3Vです。  また、RN4020のI2Cはファームウェアのバージョンが1.20以降で利用できます。現在販売されているものは1.23が多いようです。(最新はバージョン1.3)念のため、シリアルからVコマンドを使ってバージョンを確認しておきましょう。  RN4020はI2Cのマスタとして動作します。スレーブ動作は設定できません。また、EEPROM の読み書きを実行するコマンドがありますが、それ以外は指定データをシリアルバスにそのまま流す低レベルなAPIしかありません。

I2Cのコマンド

RN4020でI2Cを利用するためには以下の5つのコマンドを覚えれば大丈夫です。以下の5つのコマンドの組み合わせでI2Cのスレーブにアクセスします。

コマンド 用途
]A I2Cポートの初期化
]C I2Cのイベント制御
]Z I2Cポートの開放
]W データの書き込み
]R データの取得

I2Cコマンド利用方法

 今回はHDC1000と呼ばれるI2Cインタフェースの温湿度センサから温度の値を読み取る方法を例にとり、コマンドの使い方を説明します。 このセンサは前まで秋月電子通商で手に入りましたが最近は廃盤になったようです。センサのアドレスは7bitアドレスで1000000を持っています。上記のコマンドを使ってHDC1000から温度データを取得するには以下のように実行します。

]A,1,2 //(1)
]C,0 //(2)
]W,80020000 // (3)
]W,8000 //(4)
]C,1 //(5)
]W,81//(6)
]R,02 //(7)
6541 //16進数表記
  • (1) I2Cの初期化

最初の引数1はI2Cのクロックスピードです。100kHzを指定します。4を指定すると400kHzになります。また2番目の引数はGPIOを1,2,3,4,7で指定します。指定したGPIOは出力モードとなり、I2Cのスタート時にHighになります。スレーブの電源として利用することで、普段は電源を切っておくことができます。今回はGPIOを使わずに実験のため3.3Vの電源に直接接続しています。

  • (2) I2Cのスタート

]Cの引数に0コマンドをつけ、I2Cのスタートビットをバスに流します。この時、I2Cの初期化で指定したGPIOがHighになります。

  • (3) HDC1000の初期化

HDC1000はデータの取得方法など個別に細かく設定することができます。起動時に0x02のレジスタに値を書き込みます。今回は0x0000を書き込みます。詳細は以下のデータシートを参考にしてください。

]Wコマンドは指定されたバイト列をMSB側からバスに出力するコマンドです。データにバスを流すためのコマンドですので必ずしもスレーブへのWrite要求を出すコマンドではありません。そのため、I2Cの先頭バイトには7bitのスレーズ指定のアドレスと1byteのRead(1)/Wrie(0)を指定する必要があります。今回、HDC1000は2進数7bit表記で1000000がアドレスになります。最後にWriteを表す0をつけることで書き込みを表します。その後、書き込み先レジスタアドレス0x02と書き込みデータ0x0000を付与します。  実際にこの時の出力をロジックアナライザで確認すると以下の図のようになっています。

f:id:masato-ka:20171017075459p:plain

もしデバイスアドレスが8bit表記であれば左へ1bitシフトしたものにRead/Writeのbitを付け足します。(MSB側は必ず0になっているはず。。。)

引き続き]Wコマンドでレジスタ0x00へアクセスします。HDC1000ではこのジレスタにアクセスすることで、センサないのA/Dが温度の値を変換することになっています。Write要求ですが特にデータは書き込まず問題ありません。同じようにいかに信号の状態を出力しておきます。

  • (5) I2Cリセット

温度を読み取るまでのRN4020側の書き込みは完了したため、一度I2Cのバスを解放します。

(4)から(5)までのロジックアナライザ上での動作になります。

f:id:masato-ka:20171017075506p:plain

  • (6) リード要求

RN4020からリード要求を出します。この場合もバスに信号を流すため]Wコマンドを利用します。0x81はアドレス1000000のLSB側にRead要求の1を足したものになります。 I2CバスにREAD要求のコマンドが出力されます。

  • (7) データの読み取り

I2Cのデータの読み取りはリードコマンド]Rを使います。引数は受信するバイト数でここでは2バイトを表します。HDC1000の場合結果は4桁の16進数で帰ってきます。これを指定された式で計算して温度値を読み取ります。

(5)から(7)までのロジックアナライザ上での動きは以下の通りです。前述の説明と照らし合わせてみてください。

f:id:masato-ka:20171017075453p:plain

以上でRN4020のI2Cの値の読み取りになります。]Wと]Rの使い方に気をつければ他のデバイスやアクセス方法でも問題なく利用できると思います。ロジックアナライザの出力とコマンドを照らし合わせると出力がどうなるか理解できるかと思います。

I2Cスクリプトサンプル

I2Cはもちろんスクリプトモードからも利用できます。上記の例を参考に温度データを一定間隔でNotifyするスクリプトです。キャラクタリスティックには2byteでRead Notifyが指定されています。スクリプトとプライベートサービスの詳細は過去記事を御覧ください。

masato-ka.hatenablog.com

@PW_ON
A

@CONN
]A,1,2
]C,0
]W,80020000
]W,8000
]C,1 
SM,1,00002710

@TMR1
]W,81
$VAR1=]R,02
SHW,000B,$VAR1
SM,2,00002710

@TMR2
]W,8000
]C,1
SM,1,00002710

@DISCON
]Z
A

上記例では温度の変換命令''']W,8000```と読み取り命令を別のタイマーイベントとし、相互に繰り返すようになっています。(お互いのタイマーイベントを指定している。)これはHDC1000の温度変換の結果がくるのを少し待たないといけないためです。(ハードウェア割り込みもありますが今回は不使用です。)

まとめ

今回はRN4020でI2Cを利用してみました。I2Cもスタンドアローンで利用できるので、I2Cのセンサをつないでお手軽に利用することができます。簡単なセンサーデバイスはすぐに作れそうです。注意点としてはデータシート状のI2CのピンSDAとSCLが逆になっている点、]W,]Rのそれぞれの使い方です。ここさえ押さえればすぐに利用できます。データシートは何年もほったらかしのようですが、いつか修正されるのでしょうか。。。

Web Bluetooth APIと自作BLEデバイスで戸締り確認をしてみる。

この記事について

 この記事ではWeb Bluetooth API戸締り確認アプリを紹介します。デバイス側はRN4020を使って実装しました。Web Bluetooth APIとRN4020を使ってBLEのアプリを作ってみたかったので、製作しました。実用性はありませんが、それぞれの使い方を覚えるのには大変良さそうな題材です。

戸締り確認アプリ

戸締り確認アプリは大まかに以下の仕様になっています。

  1. BLE経由で鍵の開閉を確認することができる。
  2. 鍵の状態が変わったらBLE経由で通知が来る。
  3. 鍵が開場した場合にブザーが鳴る。

バイスの紹介

今回RN4020で作るBLEデバイスにはホール素子とブザーが付いています。ホール素子は磁石が近づくと信号を出力するセンサです。自転車の速度計などに利用されています。また、ブザーについてはRN4020のデジタル出力で直接駆動できないため、トランジスタで増幅しています。抵抗値などはかなり適当です。

f:id:masato-ka:20171001123639j:plain

実体配線図っぽいのは以下の通りです。

f:id:masato-ka:20171001132146p:plain

RN4020のサービスとキャラクタリスティックは以下のように設定しました。一つのサービスに開閉のデータを送るキャラクタリスティックとブザーを制御するためのキャラクタリスティックの2つを設定しています。また開閉のキャラクタリスティックについてはReadとNotifyの2つを設定しています。後ほどスクリプトでRN4020のIOポートとつなげるため、データ長は1バイトにしています。(単純な動作なので)

  • サービス
    • UUID 123456789012345678901234567890FF
    • 鍵開閉のキャラクタリスティック
      • UUID 12345678901234567890123456789011
      • Mode Read,Notify
      • Length 1byte(0x02の場合ロック,0x00の場合アンロック)
    • ブザーのキャラクタリスティック
      • UUID 12345678901234567890123456789022
      • Mode Write(応答なし)
      • Length 1byte(0x04の場合に発音,0x00の場合に消音)

実際のコマンドは以下のように設定します。

PS,123456789012345678901234567890FF
PC12345678901234567890123456789011,12,01
PC12345678901234567890123456789022,04,01

実際に指定したスクリプトは以下のスクリプトを設定しました。

@PW_ON
|O,04,00
|O,04,%000E
A

@CONN
SM,1,000F4240

@TMR1
$VAR1 = |I,02
SHW,000B,$VAR1
SM,1,000F4240

@DISCON
A

スクリプトやその他設定の方法については以下を参照してください。

masato-ka.hatenablog.com

Webブライザ側のアプリケーションについて

Webブラウザ側のアプリケーションについては以下のUIを作りました。AugularJSとを利用して作成しています。

f:id:masato-ka:20171001120601p:plain

connectを押すとBLEの接続要求が実行されます。またreadやSubscribe/Unsubscribeでデバイス側のホール素子の値を取得します。

ソースコード全体については以下のリポジトリに置いてあります。

github.com

アプリの実行

アプリの実行時の動作を動画にしてみました。ブザーの音がするので音量は控えめにしてください。

www.youtube.com

バイスへの接続ご、サブスクライブ(デバイスからのNotifyをスタート)を行い、画面上のLock Unlock表示が変わります。また、Alertをセットすることで、Unlock時にブザーが鳴るようになります。

まとめ

Web Bluetooth API とRN4020を使うことで簡単にBLEを使ったアプリケーションを作ることができました。今回は半日程度で両方実装できたので非常にお手軽だったと思います。BLEで何かしようと思った場合、スマフォなどのアプリは作れるけど、そもそも取り扱えるBLEデバイスの種類がないので面白いことができないといった場合にはRN4020でサクッとデバイスを作ってしまうのもいいかもしれません。また、自作のBLEデバイスを作ってみたけれど、コントロールするスマフォアプリを作れない、市販デバイスを気軽にハックしたいという場合はWeb Bluetooth APIを利用するとサクッと見栄えのいいアプリが作れると思います。コンセプトを試したいときなどアイディアの試作に利用できそうです。

今回の作例を使ったワークショップを2017年10月20日に開催予定です。どなたでもご参加いただけます。

connpass.com

BLEモジュールRN4020をスクリプトから制御する。

この記事について

 この記事では前回に引き続き、RN4020を制御する方法について記載しています。前回まではシリアル通信から制御をおこなっていました。しかし、今回はRN4020のスクリプト機能を使って、スタンドアローンで制御する方法を紹介します。RN4020については以下の記事を参照してください。

masato-ka.hatenablog.com

下記写真のようにスマフォのアプリからBLE経由でLEDの制御が可能です。作業時間10分程度でここまでのことが実現できます。

f:id:masato-ka:20170927225702j:plain

RN4020のスクリプト制御

 RN4020ではシリアル制御のコマンドをRN4020上に記憶させることで外部からの制御なしにスタンドアローンで動作させることが可能となります。スクリプトの制御では予め設定されたイベント(電源ONやBLEの接続イベント、タイマーイベントなど)ごとに処理を記載してBLEデバイスとしての振る舞いを設定します。また、I/Oポートの値をキャラクタリスティックに紐づけることができます。

RN4020の初期設定

 まずはじめにRN4020をスクリプト制御する前BLEの動作モードやプライベートサービスの設定を行います。設定については前回の記事で紹介していますので参考にしてください。今回はキャラクタリスティックを1つ設定し、書き込みモードとしました。

+
- Echo On
SF,1 
-AOK
SS,00000001 
-AOK
SR,00000000 
-AOK
PZ 
-AOK
PS,123456789012345678901234567890FF
-AOK
PC,12345678901234567890123456789011,04,01
-AOK
R,1
-Reboot
-CMD

スクリプトの書き込み準備

スクリプトの書き込みを行うためには以下のコマンドを入力します。

WC //スクリプトの初期化を行う。
-AOK
WW // スクリプト書き込みモードにする。
-AOK

これで、シリアルコンソールからスクリプトを書き込む準備ができました。

スクリプトの作成

 今回は上記で設定したキャラクタリスティックに値を書き込むとLEDが光るようなサービスを指定します。以下のスクリプトを1行ずつ入力してください。

@PW_ON//(1)
|0,01,%000A//(2)
A

@CONN//(3)
SM,1,00500000//(4)

@TMR1//(5)
SM,1,00500000//(6)

@DISCON//(7)
A

上記スクリプトの入力が完了したら<ESC>キーを押してください。スクリプト入力モードから抜け出せます。

スクリプトの動作について説明します。

  • (1) 電源が入った場合に呼ばれるイベントで初期化の処理を記載します。ここではAコマンドでアドバタイズを実行しています。
  • (2) PIO1に000A のハンドラを持ったキャラクタリスティックを関連づけています。これによりキャラクタリスティックに書き込みに従ってPIO1を制御できます。
  • (3) セントラルから接続された場合に呼ばれるイベントです。
  • (4) SMコマンドでタイマーをセットしています。タイマー1を5秒ごに実行するように設定しています。
  • (5) タイマー1のイベントが発生した場合に呼び出されます。
  • (6) 再びタイマーをセットし、タイマー1イベントが繰り返し呼ばれるようにします。今回はタイマーループはからの処理ですので飛ばしても構いません。
  • (7) 切断後再度接続ができるようにアドバタイズを再開する。

上ではキャラクタリスティックに値を書き込むことでデバイスの制御をしていますが、もちろん、I/Oの値をキャラクタリスティックにわたしデータを外部に送信することも可能になっています。

例えば@TMR1イベント中で以下のように記載することでAIO0の値をキャラクタリスティックに書き込めます。 これはノティフィケーションの通知のような場合にできる記載方法です。

$VAR1 = @I,0
SHW,000B,$VAR1

また初期化時に以下のように記載すると000Eのハンドラを持つキャラクタリスティックをReadした場合にAIO2の値を読み出すことができます。

%000E = @I,2
  • スクリプトで利用できるイベントは以下のようになっています。
イベント ベントラベル
電源 ON @PW_ON
Timer1 タイムアウト @TMR1
Timer2 タイムアウト @TMR2
Timer3 タイムアウト @TMR3
接続完了 @CONN
切断完了 @DISCON
PIO4( ピン 13) の入力が Low へ変化 @PIOL
PIO4( ピン 13) の入力が High へ変化 @PIOH
高優先度アラート @ALERTH
低優先度アラート @ALERTL
アラート OFF @ALERTO

スクリプトの実行

スクリプトを実行する場合は以下のようにRN4020の動作モードをスクリプトモードにしてから再起動します。

SR,01000000 //ペリフェラルかつスクリプト実行モードにする。
R,1 

スクリプトの消去について

スクリプトモードにして再起動すると他の操作を受け付けません。再起動コマンドと初期化コマンドは受け付けるようになっているためもしスクリプトを消去したい場合は以下のコマンドを実行して初期化してください。

SF,1
R,1

2017/09/28追記:深夜の勢いで上のように書きましたが普通に上で紹介してるWCコマンド使えば消去できると思います。

実行の様子

実際に上記の動作の様子を動画にしました。撮影が下手なので分かりづらいですが、スマートフォン側からRN4020に接続し、設定したキャラクタリスティックの値を変更することでLEDが点灯または消灯する様子がわかると思います。00を書き込んだタイミングでLEDが点灯し、それ以外の値を書き込んだタイミングでLEDが消灯します。


RN4020のスクリプト動作

まとめ

 前回まではシリアルから制御していたため、必ずホストとなるコンピュータが必要になりました。しかしスクリプトを利用することでRN4020単体でもデバイスの動作を実現できることがわかりました。制御文などが十分ではないため動作としてはあまりリッチな動きができそうにありませんが、非常に単純な機能であれば使いどころはありそうです。

BLEモジュールRN4020のIOポートをシリアルから制御する。

この記事について

 この記事ではBLEモジュールRN4020のIOポートを制御する方法について紹介します。RN4020については前回の記事をみてください。

masato-ka.hatenablog.com

RN4020のI/Oポート

 RN4020のI/OポートはアナログI/O(AIO)とデジタルI/O(PIO)の2種類のポートがあります。それぞれシリアルインタフェースから制御するためのコマンドが用意されており、RN4020にスイッチやLED、アナログ出力のセンサを取り付けて値を読み出すことが可能です。

アナログI/Oについて

   RN4020のアナログI/0はAIO0からAIO2までの3ポートあります。入出力電圧のレンジは0Vから1.3Vと低電圧となっています。1mV単位の指定ができ値のレンジは(0x0000〜0x0514)となります。

デジタルI/Oについて

 デジタルI/OはPIO1,PIO2,PIO3,PIO7の4ポートあります。欠番になっているピンも存在しているのですが、基本的にシリアルのフロー制御など他の用途に使われているため使用しません。もちろんI/Oとしても利用することは可能だと思いますが、ユーザガイド上に方法が記載されていません。

ピンアサイ

 モジュール自体のピンアサインはユーザガイドをみてください。ここでは秋月電子通商のブレークアウトボードでのピンアサインを紹介します。以下図の通りのピンアサインになっています。紹介したPIO7についてはこちらでは出ていません。従ってデジタルI/OはPIO1からPIO3までの3ピンのみ利用可能です。またPIO1はボード上のLED制御ピンと兼用になっています。

f:id:masato-ka:20170926001343p:plain

シリアルからのI/O制御

I/Oの制御方法はアナログとシリアルでそれぞれ変わります。それぞれの制御コマンドについて説明していきます。

アナログI/Oの制御

  • アウトプットコマンド

アナログアウトプットのコマンドは@Oです。以下のように使います。

@O,2,0014

最初の引数がポート番号を指し、今回はAIO2を指定しています。さらに0014は出力値を16進数で表しています。20mVがAIO2に出力されるはずです。他のピンについても同様に指定できます。

  • インプットコマンド

アナログインプットは@Iです。以下のように使います。

@I,2
- 0000

最初の引数はアウトプットと同じくポートを表しています。結果としてAIO2のポートの電圧値(ここでは0)が結果として帰ってきます。

デジタルI/Oの制御

  • デジタルアウトプットコマンド

デジタルアウトプットのコマンドは|Oです。以下のように使います。

|O,07,05

最初の引数はピン番号の制御ですが、16進数で指定しています。ここではPIO1,PIO2,PIO3を指定しています。2つ目の引数は出力指定です。こちらも16進数指定でPIO1,PIO3をHighに指定し、PIO2をLowに指定しています。ブレークアウトボードの場合、ボード上のLEDが消灯するはずです。(Highで消灯、Lowで点灯)各PINとレジスタの関係は以下の表のようになっています。複数指定する場合は足し算してください。

ピン番号 レジスタ
PIO1 0x01
PIO2 0x02
PIO3 0x04
PIO7 0x08
  • デジタルインプット

デジタルインプットは同様に上記のレジスタの表に従って以下のように指定します。

|I,01,
-01

これはPIO0の値を読み取り結果が同じくレジスタの形式で帰ってきます。(-はRN4020からの応答を表す)PIO1の値が1になっています。(LEDからの入力電圧があるため)

まとめ

 以上のようにRN4020はシリアルからI/Oを制御することが可能です。しかし単純なI/O制御だけならばシリアル接続側のマイコンで行っても良いと思います。RN4020のスクリプト機能を使うとアナログI/O,デジタルI/Oともに変数に代入したり、キャラクタリスティックのハンドラにバインドすることができます。こちらについてもまとめ次第記事にしたいと思います。