PR

ESP32-WROOM-32EとTWELITEの特徴を活かした無線通信

組み込みエンジニア
本記事はプロモーションが含まれています。

こんにちは、ENGかぴです。

ESP32-WROOM-32EとTWELITE(トワイライト)でWiFi通信とZigBee通信の特徴を活かした通信システムを作ることができます。ZigBee通信で子機と親機の通信を行い、WiFi通信で温湿度センサーの情報を表示する方法をまとめました。

温湿度センサーであるSHT35とトワイライト(以下TWELITEとする)を組み合わせた子機で温湿度情報をZigBee通信し、ESP32-WROOM-32E(以下ESP32とする)とTWELITEを組み合わせた親機で温湿度情報を無線受信します。ESP32はWebサーバーを実装して温湿度情報をグラフ表示します。

ESP32-WROOM-32E開発ボード(秋月電子)を使用しArduino IDEで開発を行います。温湿度センサーはAE-SHT35(秋月電子:以下SHT35とする)を使用しています。 TWELITEはTWELITE-DIP-RED(モノワイヤレス)を使用しています。

ESP32を使って動作確認したことをまとめています。

ESP32-WROOM-32Eで学べるソフト開発と標準ライブラリの使い方

TWELITEで動作確認したことについてまとめています。

トワイライト(TWELITE)のソフト開発と無線通信でできること

ESP32とTWELITEの関係

ESP32とTWELITEの関係
ESP32とTWELITEの関係

ESP32とTWELITEの関係を説明します。ESP32とTWELITEは無線通信モジュールです。ESP32はWiFi通信が使用できるため大容量のデータを伝送することができますが、電波が届きにくく近距離通信になってしまいます。

TWELITEはZigBee通信で一度に通信できるデータ量は少なくなりますが、低消費電流で中距離通信できます。電波強度が高いTWELITE-REDを使用すると見通し距離で1km~2kmの通信ができます。

WiFi通信の大容量のデータが伝送できる特徴とZigBee通信の低消費電流で中距離通信ができる特徴を組み合わせることで、WiFi通信では届かない範囲のセンサーのデータを取得することができます。

子機のTWELITEはSHT35からI2C通信で温湿度データを取得し、一定周期で親機のTWELITEに無線送信します。

親機のTWELITEは子機から受信したデータをESP32にシリアル通信で送信します。ESP32は取得した温湿度データを履歴保存しながらスマホなどの通信端末(クライアント)からの接続を待機します。クライアントから接続要求を受けるとWebサーバーが応答して温湿度データの履歴を表示します。

参考記事としてTWELITEとArduino UNOをシリアル通信する方法をまとめています。ESP32でも同様の方法でシリアル通信できます。

Arduinoとトワイライト(TWELITE)でセンサー情報を表示する

広告
漠然としたキャリア形成の不安を打ち破る!

親機の構成

親機の構成
親機の構成

ESP32とTWELITEを組み合わせた親機の構成です。回路図の番号はESP32の左上を1ピンとした時反時計回りにピンを数えた場合の番号としています。ピン番号横の()内の番号はシルク印刷されているピンの名称です。

TWELITEの電源はESP32の3V3(3.3V)とGNDを使用します。ESP32はTWELITEからシリアル通信で電文を受信するためRX2を使用します。TWELITEはESP32に電文を送信するためTXを使用します。

ESP32はWebサーバーでクライアントからの接続を待機します。接続要求があればHTTPデータで応答し温湿度データの履歴を表示します。

ESP32の参考記事

温湿度データの取得方法及びWebサーバーを実装する方法を下記記事にまとめています。

ESP32-WROOM-32EでWebServerを実装する

温湿度データの履歴を表示する前提としてChartライブラリをESP32のFLASHに書き込む必要があります。Chartライブラリを書き込む方法を下記記事にまとめています。

ESP32-WROOM-32EにSDカードのファイルをアップロードする

Chart.jsを使ってブラウザー上にグラフ表示する方法を下記記事まとめています。

Chart.jsを使ってデータをブラウザー上でグラフ表示する

以下の説明はChartライブラリがFLASHに書き込まれていることが前提です。

SPIFFSでFLASHのファイルを参照する

FLASHのファイルにアクセスするためにSPIFFSライブラリを使用します。SPIFFSライブラリの初期化とWebサーバーがファイルを参照できるようにします。

#include <SPIFFS.h>
WebServer Wserver(80);

SPIFFS.begin();
Wserver.serveStatic("/myfavicon.ico",SPIFFS,"/myfavicon.ico");
Wserver.serveStatic("/chart.min.js",SPIFFS, "/chart.umd.js");

SPIFFSライブラリを使用するためにSPIFFS.hをインクルードします。begin()関数でSPIFFSに関する初期化を行います。

WebサーバーライブラリのserverStatic()関数でFLASHに書き込んだChartライブラリやファビコンのファイルをSPIFFSを使って参照できるようにします。

スポンサーリンク

HTMLデータの生成

void HtmlSet(void){
  String str = "";

  str += "<head>";
  str += "<link rel='shortcut icon' href='/myfavicon.ico' />"; //ファビコンを指定
  str += "<script src = '/chart.umd.js'></script>"; //chart.umd.jsを読み込み 
  str += "</head>";

HTMLデータを生成してブラウザに表示します。HTMLデータの<head>部分にファビコンを使用する場合は使用するファイルを指定します。<script>でchart.umd.jsを参照する指定を行います。前述でWebサーバーがFLASHのファイルを参照できるChartライブラリが使用できるようになります。

float tempdat[CHART_SZ];//温度の履歴の配列
String str="";

str += "datasets: [{";
str += "label: '温度',";
str += "fill: false,";
str += "borderColor: 'red',";
str += "borderWidth: 1,";
str += "pointRadius: 0,";
str += "pointHoverBorderWidth: 10,";
str += "data: [";
  for(uint16_t i = 0; i< CHART_SZ; i++ ){
    str += tempdat[i]; 
    if(i != CHART_SZ-1 )str += ",";
  }
str += "]";
str += "}, {";

Chart.jsはHTTPファイルと関連付けられた配列であればX軸やY軸の値を配列名で指定するとグラフ表示ができますが、温湿度の履歴はESP32のRAMに格納しているため関連性がなく配列名を直接指定することができません。

11~16行目のように配列を文字列で追加してグラフのデータをセットする必要があります。例のようにdata[]に配列のデータを追加してHTMLデータを生成しています。

例)文字列追加の様子
配列の一番目を追加:data[25.03,
配列の二番目を追加:data[25.03,25.05,
配列のN番目を追加:data[25.03,25.05,・・・,25.07,
配列の追加が完了:data[25.03,25.05,・・・,25.07,・・・,25.04]

一文字でも間違うと表示できなくなるためテキストファイルなどでHTML形式で文章を生成しGoogle Chromeで開いて表示できることを確認しておくとよいでしょう。

ESP32のString型は65535バイト分(2バイト)までしか対応していないため文字の増やし過ぎには注意が必要です。 RAM領域を圧迫してスタックオーバーする可能性もあるため文字列が大きくならないように管理が必要です。

【クリエイターズファクトリー】卒業がない!挫折する心配なし!Webスクール説明会申し込み

シリアル通信に使用する電文

シリアル通信の電文の構成
シリアル通信の電文の構成

ESP32とTWELITE間のシリアル通信に使用する電文です。ヘッダは先頭を示すために使用します。アスキー文字で’T’、’W’の2バイト構成にしていますが、本記事の電文の判定には’T’のみを使用しています。

サイズはCHから湿度までのデータ部のバイト数とします。CHは子機が複数あるときに子機の番号を識別するために使用します。

タイムスタンプはTWELITEの親機が子機から受信した時点でのカウント値を4バイトでセットします。

温度、湿度はそれぞれ2バイトデータです。TWELITEの子機から100倍値のデータで無線受信するためこれらの値を100で割ると温度、湿度のデータに換算できます。

SUMはヘッダから湿度までのすべてのデータを加算していた結果の下位1バイトのデータをセットします。

TWELITEの処理

TWELITEの親機は子機から無線受信するとESP32にシリアル通信でデータを送信します。下記記事にアプリケーションIDやチャンネル番号の設定など親機の処理についてまとめています。

トワイライト(TWELITE)で親機を実装し子機から無線受信する

本記事ではアプリケーションID及びチャンネル番号の一致を確認して温度、湿度の情報を無線受信しています。

//TWELITE親機の無線受信処理
void receive() {
  uint16_t temp;
  uint16_t humi;

  auto&& rx = the_twelite.receiver.read(); //データを受信
  auto&& np = expand_bytes(rx.get_payload().begin(),rx.get_payload().end()
          ,temp
          ,humi
  );

  txdata.cnl = int(rx.get_addr_src_lid()); //子機のアドレス
  txdata.temp[0] = temp & 0xFF;
  txdata.temp[1] = temp >> 8;
  txdata.humi[0] = humi & 0xFF;
  txdata.humi[1] = humi >> 8;
  SerialTxSet(); //データを送信する
}

TWELITEの受信機が無線受信したパケットからデータを取得します。

the_twelite.receiver.read()関数でパケットのデータを読み込みます。expand_bytes()関数でパケットのペイロード(ユーザーが指定したデータ)を取得し、temp,humiに格納します。

txdataは送信用のデータを格納する変数です。txdataに送信用のデータをセットします。例ではrx.get_addr_src_lid()関数で取得した子機のアドレスと温度湿度のデータを指定しています。温度(temp)、湿度(humi)は2バイトデータで構成しているので1バイトデータに置き換えてセットします。

void SerialTxSet(void){
  uint8_t *adrs;

  adrs =&txdata.header[0];
  for(uint8_t i = 0; i < allsz; i++ ){//電文のサイズ
    Serial << (*adrs);
    adrs++;
  }
}

ポインタでtxdataの先頭(ヘッダ)のアドレスを指定し、ポインタを更新しながらSerialでデータ(*adrsはポインタに格納している値)を送信します。

PR:技術系の通信教育講座ならJTEX

ESP32の処理(シリアル通信)

ESP32はTWELITEから受信した電文を処理します。下記記事にTWELITEとArduino UNO間でシリアル通信する方法をまとめています。

トワイライト(TWELITE)とArduino間でシリアル通信する

参考記事と同様の考え方ですが、電文の構成を変更してESP32とTWELITEの間でシリアル通信を行います。ESP32はTWELITEから受信した電文に合致する場合に電文を受け入れます。

void Rcvmain(void){
 
  if( esp32Rcv.buf[ rp ] != HEADER_1 ){ //ヘッダの確認
    //電文のヘッダーが不一致
  }
  else{
    //受信したデータのサイズ確認
    sumchk = CalcSum(&Rcvdata[3], datsz); //SUMの計算
    if( sumchk == Rcvdata[allsz-1]){//SUMのチェック
      Sht35Set(true);  //履歴データにセット
    }
}

受信データのスタートがHEADER1(’T’)であれば電文のスタートとみなします。ヘッダの後はサイズが続くためサイズを確認して電文の全体のサイズを確認します。

受信したデータをサイズ分確認しますが、取得したデータの健全性を確認するため取得したデータのSUMを計算し、電文の最後に付加しているSUMと一致するか確認します。SUMが一致すると正常なデータとして温湿度データを履歴データに格納します。

履歴データを準備する

uint16_t temp=0;
uint16_t humi=0;
float temp_f;
float humi_f;

  temp = (Rcvdata[9] << 8) + Rcvdata[8]; //2byteデータを生成
  humi = (Rcvdata[11] << 8) + Rcvdata[10];
  temp_f = (float)temp/100; //100倍値なので100で割って換算
  humi_f = (float)humi/100;

  memmove( &tempdat[1], &tempdat[0],(CHART_SZ-1)*sizeof(float));
  memmove( &humiddat[1], &humiddat[0],(CHART_SZ-1)*sizeof(float));
  tempdat[0] = temp;
  humiddat[0] = humi;
}

Chart.jsで表示する履歴データを生成します。シリアル通信で取得したデータを配列の先頭に新しいデータが更新されるように格納します。

memmove()関数で配列の先頭から配列の最後尾よりも-1した範囲を配列の1つ分だけずらすことで配列の先頭を空けてから最新のデータを配列の先頭に格納します。

最新のデータがグラフの最後尾に表示する場合はChart.jsのオプションのX軸のスケールのreverseをtrueにすることでX軸のスケールの向きを反対にすることができます。

スポンサーリンク

子機の構成

子機の構成
子機の構成

TWELITEとTWE-EH-S及びSHT35を組み合わせた子機の構成です。TWELITEの電源にTWE-EH-Sに付属した太陽光パネルを使用しています。基本的な動作は下記記事の構成を流用しています。

トワイライト(TWELITE)の自作アプリとソーラーモジュールで無線通信

参考記事のモノスティックがTWELITE-DIPの親機に置き換わったイメージです。

TWELITEはI2C通信でSHT35から温湿度データを取得し、親機のTWELITEに無線送信します。下記記事にTWELITEでSHT35のデータを取得する方法をまとめています。

トワイライト(TWELITE)でSHT35のデータを取得する

14(12)ピンはGNDに接続した状態で子機の電源を入れるとインタラクティブモードに遷移します。子機の設定をトワイライターを使用せずに行う場合に使用します。トワイライターを使用する場合はMWSTAGEのインタラクティブモードを選択すると設定画面に遷移します。

MWSTAGEのインタラクティブモード画面
MWSTAGEのインタラクティブモード画面

アプリケーションID(Application ID)とチャンネル番号(Channel)を親機に合わせて設定します。子機の番号(Device ID)を区別する場合はデバイス番号を1~239を指定します。254は区別なしの子機になります。

PR:スキマ時間で自己啓発!スマホで学べる人気のオンライン資格講座【スタディング】まずは気になる講座を無料で体験しよう!

動作確認

ESP32のWiFiの範囲がTWELITEで範囲が拡張されていることを確認します。子機の電源は電気二重層コンデンサに3.3Vまで充電したものを使用しています。以下の手順で動作確認を行いました。

  1. 親機をシリアルモニターに接続する。
  2. 親機のアクセスポイントが検知できない距離をスマホで確認する。自宅を出るとすぐに検知ができなくなった。
  3. 検知できなくなった場所から少し離れた場所に子機を設置し、電源をONする。
  4. シリアルモニターで子機と通信できていることを確認する。
  5. スマホからアクセスポイントに接続し、履歴を確認する。

子機を設置してシリアルモニターを確認するとTWELITEから受信した温湿度データが表示されていました。

シリアルモニタの結果
シリアルモニタの結果

子機は6秒毎(タイムスタンプtsが6秒毎に更新)にスリープからウェイクアップし、温湿度データを親機に無線送信していることが確認できました。次にスマホでWiFiで温湿度データの履歴を確認しました。

温湿度情報のグラフ表示の結果
温湿度情報のグラフ表示の結果

WiFiのアクセスポイント「EngKapi1」を選択しパスワードに「11112222」を入力してアクセスポイントに接続します。

Google ChromeでIPアドレス「192.168.4.1」を指定するとESP32のWebサーバーが応答し、温湿度データの履歴が表示されることが確認できました。また、IPアドレス「192.168.4.1/ti」のように存在しないURLを指定するとFile Not Foundが表示されることも確認できました。

アクセスポイント、パスワード、IPアドレスはソースコードで変更している場合は指定したものと置き換えて接続してください。

WiFiがカバーできない範囲をZigBeeが補完することで遠隔地のセンサーの状態を管理することができるようになり応用範囲が広がります。

広告

ソースコード全体

ソースコードは記事作成時点において動作確認できていますが、使用しているライブラリの更新により動作が保証できなくなる可能性があります。また、ソースコードを使用したことによって生じた不利益などの一切の責任を負いかねます。参考資料としてお使いください。

リンクからZIPファイル形式のファイルをダウンロードし、任意の場所に展開していただくとテキストファイルが生成されます。

ソースコードをダウンロード

TWELITEのソースコードはMWSTAGEの環境でアクトのソースファイルにコピーすると使用できます。

親機のESP32はSerial2のRX2、TX2のデフォルトピンがライブラリの更新により記事作成時より変わっているためbegin()関数でデータビット及びピンを指定して初期化を行っています。

本ソースコードでグラフ表示するためにChart.jsライブラリをESP32 Sketch Data Uploadまたは下記の参考記事による方法でFLASHにファイルを書き込む必要があります。

ESP32-WROOM-32EにSDカードのファイルをアップロードする

またChart.jsのバージョンが4.0.0以上ならchart.umd.js(旧バージョンではchart.min.js)を使用します。

子機のTWELITEの無線送信のタイミングは動作確認では6秒にしていますが、実用性を考慮してソースコードでは600秒にしています。

TWELITEの開発環境であるMWSTAGEのアクトを使用してTWELITE-DIPにソースコードを書き込むことで動作します。

関連リンク

Arduinoのライブラリを使って動作確認を行ったことを下記リンクにまとめています。

Arduinoで学べるマイコンのソフト開発と標準ライブラリの使い方

Seeeduino XIAOで学べるソフト開発と標準ライブラリの使い方

ESP32-WROOM-32Eで学べるソフト開発と標準ライブラリの使い方

TWELITEを使ってソフト開発したことについてまとめています。

トワイライト(TWELITE)のソフト開発と無線通信でできること

広告
マイベスト3年連続1位を獲得した実績を持つ実践型のプログラミングスクール

最後まで、読んでいただきありがとうございました。

タイトルとURLをコピーしました