pdf-icon

Arduino入門

2. デバイス&サンプル

Module Gateway H2 Arduino 使用チュートリアル

本チュートリアルでは、Module Gateway H2 を使用して Zigbee および Thread Arduino サンプルプログラムを実行し、ネットワーク通信を実現する方法を紹介します。

ボードマネージャーバージョン要件
Zigbee および Thread の機能は、新しい ESP32 Arduino ボードマネージャーバージョンの使用と、いくつかのパーティションテーブル設定操作が必要です。本チュートリアルは v3.1.1 バージョンに基づいて実装されます。以下のインストールチュートリアルを参照して設定してください。

1. 準備作業

  • 1.環境設定: Arduino IDE 入門チュートリアル を参照して IDE のインストールを完了してください。

    設定画面の「追加のボードマネージャー URL」の入力欄を探し、以下の URL を追加してください:

https://espressif.github.io/arduino-esp32/package_esp32_dev_index.json

ボードマネージャーで ESP32 を検索し、ボードのインストールを完了してください。
注: この手順では多数のツールチェーンをダウンロードする必要があり、ダウンロードに失敗する場合は、ネットワーク環境を変更するかプロキシの設定を試みてください。

Module Gateway H2
本チュートリアルでは、Module Gateway H2ESP32 Downloader を使用してデモを行います。Module Gateway H2 のコアモジュールは ESP32-H2-MINI-1-N2 を採用しており、独立して動作する能力を持っています。本チュートリアルでは、ESP32 Downloader を介して直接サンプルプログラムを Module Gateway H2 に書き込み、独立したデバイスとして使用します。

2. カスタムパーティションテーブル

Partitions
Module Gateway H2 のコアモジュールは 2MB フラッシュ版の ESP32-H2-MINI-1-N2 を使用しているため、プログラムをコンパイルする前に使用するパーティションテーブルを調整する必要があります。
デフォルトのパーティションテーブルオプションには 2MB 版の設定が提供されていないため、custom オプションを使用します。このオプションを有効にする際は、カスタムパーティションテーブルファイルを用意し、プロジェクトファイル (.ino) と同じディレクトリに配置し、partitions.csv と命名してください。以下の各サンプルプログラムでは異なるパーティションテーブルが使用される場合があるので、各サンプルの具体的な説明を参照してください。

3. Zigbee

Coordinator & End Device
本サンプルでは、2 台の Module Gateway H2 を使用し、それぞれに Zigbee OnOff Switch (Coordinator) と Zigbee OnOff Light (End Device) のプログラムを書き込みます。
コーディネーター (Coordinator) は起動後、自動的にネットワークを作成し、デバイスの参加を待ち、デバイスが参加してバインディングが完了すると、間隔をおいてライトのオン/オフ指令を送信します。
エンドデバイス (End Device) は起動後、Coordinator からの制御指令を受け取り、現在の LED 状態を表示します。

Zigbee OnOff Light (End Device)

Arduino IDE ツールメニューの設定:

  • 正しいボードを選択:Tools -> Board: ESP32H2 Dev Module
  • フラッシュ消去を有効にする:Tools -> Erase All Flash Before Sketch Upload: Enable (無効にすると接続に失敗する可能性があります)
  • フラッシュサイズを選択:Tools -> Flash Size: 2MB
  • エンドデバイスモードを選択:Tools -> Zigbee mode: Zigbee ED (end device)
  • Zigbee パーティションスキームを選択:Tools -> Partition Scheme: custom
Zigbee End Device パーティションテーブル設定
以下の Zigbee サンプルプログラムはこのパーティションテーブル設定を使用してコンパイルされます。プログラムをコンパイルする前に必ず custom パーティションテーブルオプションを有効にし、以下のパーティションテーブルをコピーして partitions.csv という名前でプロジェクトファイル (.ino) と同じディレクトリに保存してください。
  • Zigbee 2MB with spiffs
# Name,     Type, SubType, Offset,  Size, Flags
nvs,        data, nvs,     0x9000,  0x5000,
otadata,    data, ota,     0xe000,  0x2000,
app0,       app,  ota_0,   0x10000, 0xC0000,
app1,       app,  ota_1,   0xd0000, 0xC0000,
spiffs,     data, spiffs,  0x190000,0x5a000,
zb_storage, data, fat,     0x1ea000,0x4000,
zb_fct,     data, fat,     0x1ee000,0x1000,
coredump,   data, coredump,0x1f0000,0x10000,
cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
#ifndef ZIGBEE_MODE_ED
#error "Tools->Zigbee mode で Zigbee エンドデバイスモードが選択されていません"
#endif
#include "Zigbee.h"
/* Zigbee 電球の設定 */
#define ZIGBEE_LIGHT_ENDPOINT 10
uint8_t led = RGB_BUILTIN;
uint8_t button = BOOT_PIN;
ZigbeeLight zbLight = ZigbeeLight(ZIGBEE_LIGHT_ENDPOINT);
/********************* RGB LED 関数 **************************/
void setLED(bool value) {
if(value){
Serial.println("LED ON!");
} else {
Serial.println("LED OFF!");
}
digitalWrite(led, value);
}
/********************* Arduino 関数 **************************/
void setup() {
Serial.begin(115200);
// LED の初期化と消灯 (もし LED_PIN が RGB_BUILTIN なら、内部で rgbLedWrite() が使用されます)
pinMode(led, OUTPUT);
digitalWrite(led, LOW);
// ファクトリーリセット用ボタンの初期化
pinMode(button, INPUT_PULLUP);
// オプション: Zigbee デバイスの名前とモデルを設定
zbLight.setManufacturerAndModel("Espressif", "ZBLightBulb");
// ライト変更時のコールバック関数を設定
zbLight.onLightChange(setLED);
// Zigbee Core にエンドポイントを追加
Serial.println("Zigbee Core に ZigbeeLight エンドポイントを追加中");
Zigbee.addEndpoint(&zbLight);
// すべてのエンドポイントが登録されたら、Zigbee を開始。デフォルトでは ZIGBEE_END_DEVICE として動作します
if (!Zigbee.begin()) {
Serial.println("Zigbee の起動に失敗しました!");
Serial.println("再起動します...");
ESP.restart();
}
Serial.println("ネットワークに接続中");
while (!Zigbee.connected()) {
Serial.print(".");
delay(100);
}
Serial.println();
}
void loop() {
// ファクトリーリセット用ボタンのチェック
if (digitalRead(button) == LOW) { // ボタンが押された場合
// チャタリング防止処理
delay(100);
int startTime = millis();
while (digitalRead(button) == LOW) {
delay(50);
if ((millis() - startTime) > 3000) {
// 3 秒以上ボタンが押された場合、Zigbee を工場出荷状態にリセットし再起動
Serial.println("Zigbee を工場出荷状態にリセットし、1 秒後に再起動します。");
delay(1000);
Zigbee.factoryReset();
}
}
// ボタン押下でライトの状態を切り替え
zbLight.setLight(!zbLight.getLightState());
}
delay(100);
}

Zigbee OnOff Switch (Coordinator)

Arduino IDE ツールメニューの設定:

  • 正しいボードを選択:Tools -> Board: ESP32H2 Dev Module
  • フラッシュ消去を有効にする:Tools -> Erase All Flash Before Sketch Upload: Enable (無効にすると接続に失敗する可能性があります)
  • フラッシュサイズを選択:Tools -> Flash Size: 2MB
  • コーディネーターモードを選択:Tools -> Zigbee mode: Zigbee ZCZR (coordinator/router)
  • Zigbee パーティションスキームを選択:Tools -> Partition Scheme: custom
Zigbee Coordinator パーティションテーブル設定
以下の Zigbee サンプルプログラムはこのパーティションテーブル設定を使用してコンパイルされます。プログラムをコンパイルする前に必ず custom パーティションテーブルオプションを有効にし、以下のパーティションテーブルをコピーして partitions.csv という名前でプロジェクトファイル (.ino) と同じディレクトリに保存してください。
  • Zigbee ZCZR 2MB with spiffs
# Name,     Type, SubType, Offset,  Size, Flags
nvs,        data, nvs,     0x9000,  0x5000,
otadata,    data, ota,     0xe000,  0x2000,
app0,       app,  ota_0,   0x10000, 0xC0000,
app1,       app,  ota_1,   0xd0000, 0xC0000,
spiffs,     data, spiffs,  0x190000,0x5a000,
zb_storage, data, fat,     0x1ea000,0x4000,
zb_fct,     data, fat,     0x1ee000,0x1000,
rcp_fw,     data, spiffs,  0x1ef000,0x1000,
coredump,   data, coredump,0x1f0000,0x10000,
cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
#ifndef ZIGBEE_MODE_ZCZR
#error "Tools->Zigbee mode で Zigbee コーディネーターモードが選択されていません"
#endif
#include "Zigbee.h"
#define SWITCH_ENDPOINT_NUMBER 5
#define TOGGLE_INTERVAL 5000 // 切り替え間隔(ミリ秒)
ZigbeeSwitch zbSwitch = ZigbeeSwitch(SWITCH_ENDPOINT_NUMBER);
void setup() {
Serial.begin(115200);
// オプション: Zigbee デバイスの名前とモデルを設定
zbSwitch.setManufacturerAndModel("Espressif", "ZigbeeSwitch");
// オプション: 複数のライトがスイッチにバインドできるようにする
zbSwitch.allowMultipleBinding(true);
// Zigbee Core にエンドポイントを追加
Serial.println("Zigbee Core に ZigbeeSwitch エンドポイントを追加中");
Zigbee.addEndpoint(&zbSwitch);
// 起動後 180 秒間、ネットワークをオープンにする
Zigbee.setRebootOpenNetwork(180);
// すべてのエンドポイントが登録されたら、ZIGBEE_COORDINATOR モードで Zigbee を開始
if (!Zigbee.begin(ZIGBEE_COORDINATOR)) {
Serial.println("Zigbee の起動に失敗しました!");
Serial.println("再起動します...");
ESP.restart();
}
Serial.println("スイッチにバインドされるライトを待機中");
// スイッチがライトにバインドされるのを待つ:
while (!zbSwitch.bound()) {
Serial.printf(".");
delay(500);
}
// オプション: バインドされたデバイス一覧を表示し、メーカーとモデル名を読み取る
std::list<zb_device_params_t *> boundLights = zbSwitch.getBoundDevices();
for (const auto &device : boundLights) {
Serial.printf("エンドポイント %d のデバイス、ショートアドレス: 0x%x\r\n", device->endpoint, device->short_addr);
Serial.printf(
"IEEE アドレス: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\r\n", device->ieee_addr[7], device->ieee_addr[6], device->ieee_addr[5], device->ieee_addr[4],
device->ieee_addr[3], device->ieee_addr[2], device->ieee_addr[1], device->ieee_addr[0]
);
char *manufacturer = zbSwitch.readManufacturer(device->endpoint, device->short_addr, device->ieee_addr);
char *model = zbSwitch.readModel(device->endpoint, device->short_addr, device->ieee_addr);
if (manufacturer != nullptr) {
Serial.printf("ライトのメーカー: %s\r\n", manufacturer);
}
if (model != nullptr) {
Serial.printf("ライトのモデル: %s\r\n", model);
}
}
Serial.println();
}
void loop() {
static unsigned long lastToggleTime = 0;
// 一定間隔でライトの状態を切り替える
if (millis() - lastToggleTime > TOGGLE_INTERVAL) {
lastToggleTime = millis();
Serial.println("ライトの状態を切り替えます...");
zbSwitch.lightToggle();
}
// 10 秒ごとにバインドされたライトを表示
static uint32_t lastPrint = 0;
if (millis() - lastPrint > 10000) {
lastPrint = millis();
zbSwitch.printBoundDevices(Serial);
}
}

使用手順

    1. コーディネーターが既に動作しネットワークを作成していることを確認し、OnOff Light のコードをエンドデバイスに書き込みます。
    1. デバイス起動後、自動的にネットワークを検索して参加し、OnOff Switch は定期的にライトの切り替え指令を送信します。

4. Zigbee ネットワークスキャン

Arduino IDE ツールメニューの設定:

  • 正しいボードを選択:Tools -> Board: ESP32H2 Dev Module
  • フラッシュ消去を有効にする:Tools -> Erase All Flash Before Sketch Upload: Enable (無効にすると接続に失敗する可能性があります)
  • フラッシュサイズを選択:Tools -> Flash Size: 2MB
  • コーディネーターモードを選択:Tools -> Zigbee mode: Zigbee ZCZR (coordinator/router)
  • Zigbee パーティションスキームを選択:Tools -> Partition Scheme: custom
Zigbee サンプルパーティションテーブル設定
以下の Zigbee サンプルプログラムはこのパーティションテーブル設定を使用してコンパイルされます。プログラムをコンパイルする前に必ず custom パーティションテーブルオプションを有効にし、以下のパーティションテーブルを partitions.csv という名前でプロジェクトファイル (.ino) と同じディレクトリに保存してください。
  • Zigbee ZCZR 2MB with spiffs
# Name,     Type, SubType, Offset,  Size, Flags
nvs,        data, nvs,     0x9000,  0x5000,
otadata,    data, ota,     0xe000,  0x2000,
app0,       app,  ota_0,   0x10000, 0xC0000,
app1,       app,  ota_1,   0xd0000, 0xC0000,
spiffs,     data, spiffs,  0x190000,0x5a000,
zb_storage, data, fat,     0x1ea000,0x4000,
zb_fct,     data, fat,     0x1ee000,0x1000,
rcp_fw,     data, spiffs,  0x1ef000,0x1000,
coredump,   data, coredump,0x1f0000,0x10000,
Zigbee ネットワークスキャン
本サンプルでは、Module Gateway H2 を使用して Zigbee ネットワークのスキャンを実行し、ネットワーク情報をシリアルポートに出力します。
cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
#if !defined(ZIGBEE_MODE_ED) && !defined(ZIGBEE_MODE_ZCZR)
#error "Tools->Zigbee mode で Zigbee デバイスモードが選択されていません"
#endif
#include "Zigbee.h"
#ifdef ZIGBEE_MODE_ZCZR
zigbee_role_t role = ZIGBEE_ROUTER; // または ZIGBEE_COORDINATOR に設定可能ですが、自身はスキャンしません
#else
zigbee_role_t role = ZIGBEE_END_DEVICE;
#endif
void printScannedNetworks(uint16_t networksFound) {
if (networksFound == 0) {
Serial.println("ネットワークが見つかりませんでした");
} else {
zigbee_scan_result_t *scan_result = Zigbee.getScanResult();
Serial.println("\nスキャン完了");
Serial.print(networksFound);
Serial.println(" 件のネットワークが見つかりました:");
Serial.println("Nr | PAN ID | CH | Permit Joining | Router Capacity | End Device Capacity | Extended PAN ID");
for (int i = 0; i < networksFound; ++i) {
// 各ネットワークの全情報を出力
Serial.printf("%2d", i + 1);
Serial.print(" | ");
Serial.printf("0x%04hx", scan_result[i].short_pan_id);
Serial.print(" | ");
Serial.printf("%2d", scan_result[i].logic_channel);
Serial.print(" | ");
Serial.printf("%-14.14s", scan_result[i].permit_joining ? "Yes" : "No");
Serial.print(" | ");
Serial.printf("%-15.15s", scan_result[i].router_capacity ? "Yes" : "No");
Serial.print(" | ");
Serial.printf("%-19.19s", scan_result[i].end_device_capacity ? "Yes" : "No");
Serial.print(" | ");
Serial.printf(
"%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
scan_result[i].extended_pan_id[7],
scan_result[i].extended_pan_id[6],
scan_result[i].extended_pan_id[5],
scan_result[i].extended_pan_id[4],
scan_result[i].extended_pan_id[3],
scan_result[i].extended_pan_id[2],
scan_result[i].extended_pan_id[1],
scan_result[i].extended_pan_id[0]
);
Serial.println();
delay(10);
}
Serial.println("");
// 以下のコードのためにメモリを解放するため、スキャン結果を削除
Zigbee.scanDelete();
}
}
void setup() {
Serial.begin(115200);
// スキャン専用に、エンドポイントなしで Zigbee スタックを初期化
if (!Zigbee.begin(role)) {
Serial.println("Zigbee の起動に失敗しました!");
Serial.println("再起動します...");
ESP.restart();
}
Serial.println("セットアップ完了、Zigbee ネットワークスキャンを開始します...");
// デフォルトパラメータ (全チャンネル、スキャン時間 5) で Zigbee ネットワークスキャンを開始
Zigbee.scanNetworks();
}
void loop() {
// Zigbee ネットワークスキャンの進行状況を確認
int16_t ZigbeeScanStatus = Zigbee.scanComplete();
if (ZigbeeScanStatus < 0) { // スキャン中またはエラーが発生
if (ZigbeeScanStatus == ZB_SCAN_FAILED) {
Serial.println("Zigbee スキャンに失敗しました。再度開始します。");
delay(1000);
Zigbee.scanNetworks();
}
delay(100);
// もうひとつの選択肢はステータス ZB_SCAN_RUNNING - 待機します。
} else { // 0 件以上の無線ネットワークが見つかった
printScannedNetworks(ZigbeeScanStatus);
delay(1000);
Zigbee.scanNetworks(); // 再度スキャン開始...
}
// ループ内で他の処理も可能です...
}

使用手順

  • 1.デバイス起動後、自動的にスキャンが開始され、周辺にアクティブな Zigbee ネットワークが存在する場合、各スキャン完了後に結果が表示され、次のスキャンが自動的に開始されます。

5. OpenThread

サンプルプログラム
メニューパス File -> Examples -> OpenThread で OpenThread 関連のサンプルプログラムを確認できます。プログラムをコンパイルする前に、以下のパーティションテーブル設定等の情報を参照してください。

Arduino IDE ツールメニューの設定:

  • 正しいボードを選択:Tools -> Board: ESP32H2 Dev Module
  • フラッシュ消去を有効にする:Tools -> Erase All Flash Before Sketch Upload: Enable (無効にすると接続に失敗する可能性があります)
  • フラッシュサイズを選択:Tools -> Flash Size: 2MB
  • Zigbee パーティションスキームを選択:Tools -> Partition Scheme: Minimal SPIFFS (1.3MB APP/700K SPIFFS)
On This Page