スマホが通じない山奥でZETAでチャットしてみた
こんにちは。TOPPANデジタル株式会社でエンジニアをやらせてもらってます。三上です。今回は「ZETA」を使ったチャットツールを作ってみました。しばしおつきあいください。
イントロダクション
突然ですが、皆さんはスマートフォンの通信が届かないような山奥に行ったことはありますか?私は仕事柄、山奥で作業する機会が多いものですから、作業者同士でコミュニケーションをとりたくても、できない!困る!という経験をたくさんしてきました。みなさんはあまり実感はないかもしれませんが、コミュニケーション取りたいなってこと結構あるんです。そんなとき、「ZETA」を使ったチャットで解決できるかなと思い、今回チャットツールを作ってみました。
「ZETA」はLPWAの通信規格の中でも自営網のネットワーク構築ができちゃいます。「LTE/5G通信が不可能な場所でも使うことができるネットワーク」と言い換えることもできます。私はそんな通信規格を扱っている部署だからこそチャットツール作りたいと思ったのですが、スマホの通信ができない山奥で作業される方って私だけじゃないかも? と思うんです。ということもあり、今回は「ZETA」でチャットをするために必要なハード・ソフトの紹介をしたいと思います。
しかし、山奥なのでスマホの通信ができない。困る。そんな問題を解決するために、今回はZETAネットワークを使ったチャットツールを紹介します。
ZETAとは
本題に入る前に、さも当たり前のように話している「ZETA」について知らない方がいるかもしれないので、少し解説します。と言いつつ、一旦ChatGPTに聞いてみますね。
こういうことらしいです。簡単に言うと、このZETAはLPWAという長距離通信が可能なネットワークの一種になります。補足するならば、LPWAには公衆網と自営網という概念があります。公衆網は通信会社さんが提供しているネットワークで、自営網は自分で環境を整えるネットワークです。これだけ押さえておけばこの記事は読めます。バッチグーです。✊
SPRESENSE™と通信モジュール、クラウドアプリを活用したチャットツールの作成
では、本題に入ります。ZETAを使って作業中にコミュニケーションを。。。と、考えた時にお互いのやりとりはやっぱりスマホでやり取りしたいもの。ということで、スマートフォンとPC間で通信を行うチャットツールを作ってみます。下図が大まかな構成図です。
ここで少し解説です。今回作るメインの物が図1の通信端末部分です。この端末がやることはスマホまたはPCから来たデータをそれぞれデータ送信しています。
TOPPANで提供しているZETAモジュールはSONYさんのSPRESENSEに対応しているため、ポン付けすることができます。このSPRESENSEはめちゃくちゃ便利で、いろんなセンサと組み合わせることができるため簡単にデータロガーみたいなのが作れます。他にもNNC(Neural Network Console)というものを用いることで、比較的簡単にAIモデルを実装することができます。重ねて言いますが、マジで便利です。ぜひ使ってみてください。
また、ZETA基地局というのは端末から「ZETA」通信で送られてきたデータをLTE回線でサーバーにデータを送信します。
ハードウェアの作り方
作成に必要なハードウェアとその役割は下記のとおりです。
ZETA評価ボードTZS9002P
ZETA通信を行う通信モジュール※弊社商材です。購入してくださいSPRESENSE本体
今回使うマイコンM5Atom lite
スマホとBLE通信を行うマイコンスマートフォン(Android)
スマートフォンで文字を入力し、データを送信するため。
というわけで、SPRESENSEとAtomM5、ZETAモジュールを組み合わせたものが写真になります。SPRESENSEとM5Atom liteの接続には専用の接続基盤を用いました。
ソフトウェアの作り方
必要なソフトは下記のとおりです。
SPRESENSEに書き込むファイル
ZETA通信で来たサーバーからのデータをM5Atom liteに送信する
M5Atom liteから来たデータをZETA通信でサーバーに送信するM5Atomに書き込むinoファイル
SPRESENSEから来たデータをBLEでスマートフォンに送信する
BLEでスマートフォンから来たデータをSPRESENSEに送信するスマートフォン側のBLEでデータを送信するためのアプリ
M5Atomと接続し、取得データをチャット形式で表示PC側でデータを閲覧するためのファイル
ZETAServerでAPIを発行しているため、
ZETAモジュールのIDとAPI鍵、秘密鍵を用いてデータを取得するソフトBLESerialライブラリ
BLEでの通信に必要なライブラリです。
ZETA通信実装方法の解説
TOPPANでは、ZETA通信用のライブラリを公開しています。こちらのライブラリは、TZM902DPx.cppとZM902DPx.hの2つです。ライブラリを利用するためには、Arduino™スケッチと同じフォルダに入れます。サンプルスケッチも添付するので使ってみてください。
ZETAの通信を行うことは非常に簡単です。ユーザーがいじる部分は2つで、データの送信部分とデータの受信部分です。
まずデータ送信ですが、ZETAでデータを送信するためにはloop文内部の下記コードの部分のpacket部にデータを乗せて送信すれば可能になります。
Zeta.send(SEND_VARIABLE_LENGTH_DATA, packet, sizeof(packet));
次に受信部分です。downlink_proccess()関数にサーバーからデータが送られてきたときの処理を追加すれば実装可能です。今回は送られてくるデータの1byte目を"C0"としており、2byte目でどの処理を行うかをswitch文で判定しています。
static void downlink_proccess(char *downlink, int size) {
if (downlink[4] != 0xC0) {
return;
}
char rx[16];
char tx[16];
// C0 00 00 00 :STM32 RESET
// C0 01 xx xx :Set Transmit Interval [minutes]
// C0 02 :Get Transmit Interval [minutes]
// C0 03 :Get BATTERY Voltage
// C0 04 xx xx :Set GPS Timeout [minutes]
// C0 05 :Get GPS Timeout [minutes]
// C0 DA + payload : downlinkしたpayloadをそのままuplinkする。ZETA-Pは50yteまで、ZETA-Sは8byteまで
switch (downlink[5]) {
// C0 00 00 00 :RESET
case 0x00:
// ACK応答
Zeta.send(SEND_VARIABLE_LENGTH_DATA, &downlink[4], size - 4 - 2);
// Zeta.read(rx, sizeof(rx));
zeta_downlink_check();
if (downlink[5] == 0x00 && downlink[6] == 0x00 && downlink[7] == 0x00 ) {
Serial.println("reboot");
delay(1000);
LowPower.reboot();
}
break;
// C0 01 xx xx :Set Transmit Interval [minutes]
case 0x01:
// ACK応答
Zeta.send(SEND_VARIABLE_LENGTH_DATA, &downlink[4], size - 4 - 2);
// Zeta.read(rx, sizeof(rx));
================================省略================================
default:
// ACK応答
Zeta.send(SEND_VARIABLE_LENGTH_DATA, &downlink[4], size - 4 - 2);
// Zeta.read(rx, sizeof(rx));
zeta_downlink_check();
break;
}
}
また今回はZETAをテーマで記事を書いたいるため、M5Atomのinoファイルやスマホアプリなどの説明は省略します。
今回はこの2つを良しなに変更すれば実装可能です。実装する機能は下記の2つです。
loop文
M5Atomからシリアル通信で送られてきたデータを、サーバーに送信するdownlink_proccess()関数
サーバーから送られてきたデータをM5Atomに送信する。
まずloop文から説明すると、bleSerial.available()でM5Atomから送信されたデータのチェックを行います。データがあった場合にはZETAでデータを送信します。
void loop() {
if (isRssiReq) {
isRssiReq = false;
uint8_t rssi = zeta.get_rssi();
sprintf(ble_tx, "RSSI=-%ddBm", rssi);
zeta.send(SEND_VARIABLE_LENGTH_DATA, ble_tx, strlen(ble_tx));
bleSerial.print(ble_tx);
}
// put your main code here, to run repeatedly:
zeta_downlink_check();
if (bleSerial.available()) {
int n = 0;
delay(500);
while (bleSerial.available()) {
int c = bleSerial.read();
if (c != -1) {
ble_rx[n++] = c;
delay(1);
}
}
ble_rx[n] = '\0';
if (n > 0) {
Serial.println(ble_rx);
zeta.send(SEND_VARIABLE_LENGTH_DATA, ble_rx, n);
}
}
}
downlink_proccess()関数に関しても同様でデータをシリアルでM5Atomに送信します。
static void downlink_proccess(char *downlink, int size) {
for (int i = 0; i < size - 4 - 2; i++) {
bleSerial.write(downlink[4+i]);
delay(1);
}
// bleSerial.write(&downlink[4], size - 4 - 2);
// bleSerial.flush();
Serial.print("bleSerial : ");
for (int i = 0; i < size - 4 - 2; i++) {
Serial.print(downlink[4+i], HEX);
Serial.print(" ");
}
Serial.println();
Serial.flush();
}
では変更したコードで実際に動かしてみます。
実行結果
スマートフォンで文字を送信してみます。
端末の電源を付けた状態で、スマホアプリを立ち上げるとアプリ上でConectと表示されます。こちらが表示されると、端末側とBLEで接続できました。
こちらでデータを送信するとAtomM5⇒SPRESENSE⇒ZETAモジュール経由でデータが送信されます。
今回は、「今日のご飯何?」と送ってみます。一般家庭でよくある母との会話です。すると、PC側アプリではRXの部分でデータが表示されます。
こちらの見方ですがRXが受信データ(Receiver)TXが送信データ(Transmitter)となります。写真3のように、RXの部分に受信データとして先程送信したデータ(今日のご飯何?)が表示されました。
次にデータの送信を行ってみます。やり方は先程と逆で、PCアプリ上でテキストを入力してエンターキーを押して送信です。今日は佃煮が食べたい気分なので、「佃煮です。」と入力して送信してみます。するとスマホアプリ側でもデータが飛んできました。
今回用いたコードは下記のとおりですが、PC版のソフトについてはAPIを使って表示しているため、付属のjsonファイルにAPIキーと通信するZETA端末のIDを入力する必要があります。
なお、ZETA Allianceに加入すると、機器や今回用いたZETAServerの無償レンタルが可能です。
基本的には団体・法人様向けですが、特別会員として学生、教育機関の方もご入会可能です。ぜひ入会してください。
ZETA Allianceはあなたの入会を待っています。
まとめと展望
今回はZETAとSPRESENSEで双方向通信を行う端末を作ってみました。後半はスマホアプリを用いての双方向通信を行いましたが、前半の内容でも入力機器の処理を追加実装することでチャットアプリを作ることができます。テキストの送受信という比較的簡単な内容でしたが、いかがでしたでしょうか。
次回以降は、以下のような記事を公開していきたいと思います。
・Raspberry Pi Pico W (BLE機能付き低価格マイコンボード)+ZETA R3
でBLE-ZETAゲートウェイを作ってみた。
----------------------------------------------------------------------------------
※ SPRESENSEおよびロゴは、ソニーグループ(株)またはその関連会社の登録商標または商標です。