NanoC6 Zigbee Arduino に関連するサンプルプログラム。
このサンプルは、Zigbee コーディネータ(Coordinator)を設定し、サーモスタットとして使用して以下の機能を実現する方法を示します。
Arduino IDE ツールメニュー設定:
Tools -> Board: M5NanoC6Tools -> USB CDC On Boot: EnabledTools -> Erase All Flash Before Sketch Upload: Enabled(無効の場合、接続失敗の可能性あり)Tools -> Flash Size: 4MBTools -> Partition Scheme: Zigbee ZCZR 4MB with spiffsTools -> Zigbee mode: Zigbee ZCZR (coordinator/router)Tools -> Port
#ifndef ZIGBEE_MODE_ZCZR
#error "Zigbee coordinator mode is not selected in Tools->Zigbee mode"
#endif
#include "Zigbee.h"
// 定義エンドポイント番号
#define THERMOSTAT_ENDPOINT_NUMBER 5
// Zigbee サーモスタットオブジェクトを作成(温度データ受信)
ZigbeeThermostat zbThermostat = ZigbeeThermostat(THERMOSTAT_ENDPOINT_NUMBER);
// 温度データ変数
float sensor_temp = 0.0;
float sensor_max_temp = 120.0;
float sensor_min_temp = -40.0;
float sensor_tolerance = 1.0;
// 温度受信コールバック関数
void receiveSensorTemp(float temperature) {
Serial.printf("Temperature received: %.2f°C\n", temperature);
sensor_temp = temperature;
}
// センサー設定受信コールバック関数
void receiveSensorConfig(float min_temp, float max_temp, float tolerance) {
Serial.printf("Sensor config: min=%.2f°C, max=%.2f°C, tolerance=%.2f°C\n",
min_temp, max_temp, tolerance);
sensor_min_temp = min_temp;
sensor_max_temp = max_temp;
sensor_tolerance = tolerance;
}
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("=== NanoC6 Zigbee Coordinator ===");
// コールバック関数を設定
zbThermostat.onTempReceive(receiveSensorTemp);
zbThermostat.onConfigReceive(receiveSensorConfig);
// デバイス情報を設定
zbThermostat.setManufacturerAndModel("Espressif", "ZigbeeThermostat");
// エンドポイントを追加
Zigbee.addEndpoint(&zbThermostat);
// ネットワークを 180 秒間オープン
Zigbee.setRebootOpenNetwork(180);
// コーディネータを起動
Serial.println("Starting Zigbee Coordinator...");
if (!Zigbee.begin(ZIGBEE_COORDINATOR)) {
Serial.println("Zigbee failed to start!");
Serial.println("Rebooting...");
ESP.restart();
}
Serial.println("Zigbee Coordinator started");
Serial.println("Network is open for 180 seconds");
Serial.println("Waiting for temperature sensor to bind...");
// End Device のバインドを待機
while (!zbThermostat.bound()) {
Serial.print(".");
delay(500);
}
Serial.println("\nTemperature sensor bound successfully!");
// レポート間隔を一度だけ設定
zbThermostat.setTemperatureReporting(0, 10, 2);
Serial.println("Temperature reporting configured");
// センサー設定を取得
zbThermostat.getSensorSettings();
}
void loop() {
// 定期的に温度データを表示
static uint32_t last_print = 0;
if (millis() - last_print > 10000) {
last_print = millis();
int temp_percent = (int)((sensor_temp - sensor_min_temp) /
(sensor_max_temp - sensor_min_temp) * 100);
Serial.printf("Current temperature: %.2f°C (%d%%)\n",
sensor_temp, temp_percent);
}
delay(100);
}
このサンプルは、Zigbee エンドデバイス(End Device)を設定し、家庭用オートメーション(HA)温度センサーとして使用する方法を示します。
Arduino IDE ツールメニュー設定:
Tools -> Board: M5NanoC6Tools -> USB CDC On Boot: EnabledTools -> Erase All Flash Before Sketch Upload: Enabled(無効の場合、接続失敗の可能性あり)Tools -> Flash Size: 4MBTools -> Partition Scheme: Zigbee ZCZR 4MB with spiffsTools -> Zigbee mode: Zigbee ED (end device)Tools -> Port
#ifndef ZIGBEE_MODE_ED
#error "Zigbee end device mode is not selected in Tools->Zigbee mode"
#endif
#include "Zigbee.h"
#include <Wire.h>
// 定義エンドポイント番号
#define TEMP_SENSOR_ENDPOINT_NUMBER 10
// 定義 SHT30 I2C アドレス
#define SHT30_I2C_ADDR 0x44
// NanoH2 Grove インターフェースの I2C ピン
#define I2C_SDA 2 // G2 = GPIO2 (黄色線)
#define I2C_SCL 1 // G1 = GPIO1 (白色線)
// Zigbee 温度センサーオブジェクトを作成
ZigbeeTempSensor zbTempSensor = ZigbeeTempSensor(TEMP_SENSOR_ENDPOINT_NUMBER);
// 温度データ変数
float temperature = 0.0;
// タスク同期フラグ
volatile bool temp_updated = false;
/************************ SHT30 温度読み取り関数(温度のみ)*****************************/
bool readSHT30Temperature(float &temp) {
// 測定コマンド送信(高再現性測定)
Wire.beginTransmission(SHT30_I2C_ADDR);
Wire.write(0x2C);
Wire.write(0x06);
if (Wire.endTransmission() != 0) {
Serial.println("SHT30 communication failed!");
return false;
}
delay(20);
Wire.requestFrom(SHT30_I2C_ADDR, 6);
if (Wire.available() < 6) {
Serial.println("SHT30 data not available!");
return false;
}
uint8_t tempData[3];
for (int i = 0; i < 3; i++) {
tempData[i] = Wire.read();
}
for (int i = 0; i < 3; i++) {
Wire.read();
}
uint16_t rawTemp = (tempData[0] << 8) | tempData[1];
temp = -45.0 + 175.0 * ((float)rawTemp / 65535.0);
if (temp < -40.0 || temp > 125.0) {
Serial.printf("Invalid temperature: %.2f°C\n", temp);
return false;
}
return true;
}
/************************ 温度読み取りタスク *****************************/
static void temp_sensor_value_update(void *arg) {
for (;;) {
if (readSHT30Temperature(temperature)) {
Serial.printf("Temperature: %.2f°C\n", temperature);
zbTempSensor.setTemperature(temperature);
temp_updated = true;
} else {
Serial.println("Failed to read SHT30");
}
delay(10000);
}
}
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("=== NanoC6 End Device + Unit ENV III (Temperature Only) ===");
Wire.begin(I2C_SDA, I2C_SCL, 100000);
Serial.printf("I2C initialized (SDA=GPIO%d, SCL=GPIO%d, 100kHz)\n",
I2C_SDA, I2C_SCL);
delay(100);
Serial.println("Scanning I2C bus...");
Wire.beginTransmission(SHT30_I2C_ADDR);
uint8_t error = Wire.endTransmission();
if (error == 0) {
Serial.println("SHT30 detected at address 0x44");
} else {
Serial.printf("SHT30 not found! Error code: %d\n", error);
Serial.println("\n Expected wiring:");
Serial.println(" - Black (GND) → GND");
Serial.println(" - Red (5V) → 5V");
Serial.println(" - Yellow (SDA) → G2 (GPIO2)");
Serial.println(" - White (SCL) → G1 (GPIO1)");
while (1) delay(1000);
}
zbTempSensor.setManufacturerAndModel("Espressif", "TempSensor");
zbTempSensor.setMinMaxValue(-40, 120);
zbTempSensor.setTolerance(1);
Zigbee.addEndpoint(&zbTempSensor);
Serial.println("Starting Zigbee End Device...");
if (!Zigbee.begin()) {
Serial.println("Zigbee failed to start!");
Serial.println("Rebooting in 5 seconds...");
delay(5000);
ESP.restart();
}
Serial.println("Zigbee End Device started");
Serial.println("Connecting to network...");
while (!Zigbee.connected()) {
Serial.print(".");
delay(1000);
}
Serial.println("\nConnected to Zigbee network!");
xTaskCreate(temp_sensor_value_update, "temp_sensor_update", 4096, NULL, 10, NULL);
zbTempSensor.setReporting(1, 0, 1);
Serial.println("Temperature reporting configured");
}
void loop() {
if (temp_updated) {
temp_updated = false;
zbTempSensor.reportTemperature();
Serial.println("Temperature reported to Coordinator");
}
delay(100);
}
このサンプルは、周囲の Zigbee ネットワークをスキャンし、ネットワーク情報をシリアルに表示します。
#if !defined(ZIGBEE_MODE_ED) && !defined(ZIGBEE_MODE_ZCZR)
#error "Zigbee device mode is not selected in Tools->Zigbee mode"
#endif
#include "Zigbee.h"
#ifdef ZIGBEE_MODE_ZCZR
zigbee_role_t role = ZIGBEE_ROUTER;
#else
zigbee_role_t role = ZIGBEE_END_DEVICE;
#endif
void printScannedNetworks(uint16_t networksFound) {
if (networksFound == 0) {
Serial.println("No networks found");
} else {
zigbee_scan_result_t *scan_result = Zigbee.getScanResult();
Serial.println("\nScan done");
Serial.print(networksFound);
Serial.println(" networks found:");
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);
if (!Zigbee.begin(role)) {
Serial.println("Zigbee failed to start!");
Serial.println("Rebooting...");
ESP.restart();
}
Serial.println("Setup done, starting Zigbee network scan...");
Zigbee.scanNetworks();
}
void loop() {
int16_t ZigbeeScanStatus = Zigbee.scanComplete();
if (ZigbeeScanStatus < 0) {
if (ZigbeeScanStatus == ZB_SCAN_FAILED) {
Serial.println("Zigbee scan has failed. Starting again.");
delay(1000);
Zigbee.scanNetworks();
}
delay(100);
} else {
printScannedNetworks(ZigbeeScanStatus);
delay(1000);
Zigbee.scanNetworks();
}
}
このサンプルは、Zigbee コーディネータを設定し、ButtonA を検出してエンドデバイスの青色 LED を制御します。
Arduino IDE ツールメニュー設定:
Tools -> Board: M5NanoC6Tools -> USB CDC On Boot: EnabledTools -> Erase All Flash Before Sketch Upload: EnabledTools -> Flash Size: 4MBTools -> Partition Scheme: Zigbee ZCZR 4MB with spiffsTools -> Zigbee mode: Zigbee ZCZR (coordinator/router)Tools -> Port
#ifndef ZIGBEE_MODE_ZCZR
#error "Zigbee coordinator mode is not selected in Tools->Zigbee mode"
#endif
#include "Zigbee.h"
#define SWITCH_ENDPOINT_NUMBER 5
#define BUTTON_A_PIN 9
ZigbeeSwitch zbSwitch = ZigbeeSwitch(SWITCH_ENDPOINT_NUMBER);
bool led_state = false;
unsigned long last_button_press = 0;
const unsigned long debounce_delay = 200;
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("=== NanoC6 Zigbee Coordinator (ButtonA Controller) ===");
pinMode(BUTTON_A_PIN, INPUT_PULLUP);
Serial.println("ButtonA (G9/GPIO9) initialized");
zbSwitch.setManufacturerAndModel("Espressif", "ZigbeeSwitch");
Zigbee.addEndpoint(&zbSwitch);
Zigbee.setRebootOpenNetwork(180);
Serial.println("Starting Zigbee Coordinator...");
if (!Zigbee.begin(ZIGBEE_COORDINATOR)) {
Serial.println("Zigbee failed to start!");
ESP.restart();
}
Serial.println("Zigbee Coordinator started");
Serial.println("Waiting for LED device to bind...");
while (!zbSwitch.bound()) {
Serial.print(".");
delay(500);
}
Serial.println("\nLED device bound successfully!");
Serial.println("\nPress ButtonA to toggle LED");
}
void loop() {
if (digitalRead(BUTTON_A_PIN) == LOW) {
unsigned long current_time = millis();
if (current_time - last_button_press > debounce_delay) {
last_button_press = current_time;
led_state = !led_state;
if (led_state) {
Serial.println("Sending ON command...");
zbSwitch.lightOn();
} else {
Serial.println("Sending OFF command...");
zbSwitch.lightOff();
}
while (digitalRead(BUTTON_A_PIN) == LOW) {
delay(10);
}
}
}
delay(10);
}
このサンプルは、Zigbee エンドデバイスを設定し、コーディネータからのコマンドで青色 LED を制御します。
Arduino IDE ツールメニュー設定:
Tools -> Board: M5NanoC6Tools -> USB CDC On Boot: EnabledTools -> Erase All Flash Before Sketch Upload: EnabledTools -> Flash Size: 4MBTools -> Partition Scheme: Zigbee ZCZR 4MB with spiffsTools -> Zigbee mode: Zigbee ED (end device)Tools -> Port
#ifndef ZIGBEE_MODE_ED
#error "Zigbee end device mode is not selected in Tools->Zigbee mode"
#endif
#include "Zigbee.h"
#define LIGHT_ENDPOINT_NUMBER 10
#define BLUE_LED_PIN 7
ZigbeeLight zbLight = ZigbeeLight(LIGHT_ENDPOINT_NUMBER);
void setLED(bool state) {
digitalWrite(BLUE_LED_PIN, state ? HIGH : LOW);
}
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("=== NanoC6 Zigbee End Device (LED) ===");
pinMode(BLUE_LED_PIN, OUTPUT);
digitalWrite(BLUE_LED_PIN, HIGH);
Serial.println("Blue LED (G4/GPIO4) initialized");
zbLight.setManufacturerAndModel("Espressif", "ZigbeeLight");
zbLight.onLightChange(setLED);
Zigbee.addEndpoint(&zbLight);
Serial.println("Starting Zigbee End Device...");
if (!Zigbee.begin()) {
Serial.println("Zigbee failed to start!");
delay(5000);
ESP.restart();
}
Serial.println("Zigbee End Device started");
Serial.println("Searching for Zigbee network...");
while (!Zigbee.connected()) {
Serial.print(".");
delay(1000);
}
Serial.println("\nConnected to Zigbee network!");
Serial.println("Waiting for commands from Coordinator...");
}
void loop() {
delay(100);
}