免責事項
本記事を参考にして製作した家電や回路に関して、著者は一切の責任を負いません。内容を十分理解した上で、自己責任で作業を行ってください。
1.ECHONET Lite家電の動作原理
ECHONET Liteは家電などのIoT機器がエコー(言葉)で通じ合うように考え作られています。
ECHONET Liteの元になったECHONETという規格があります。
「ECHONETはEnergy Conservation & Homecare Networkの略。省エネルギーとホームヘルスケアを実現するネットワークという意味であり、また、「ECHO」=「こだま」の意味も併用し、呼びかけに応える、反応するという意味を持たせている。 」とECHONET Lite規格書全体目次に記載があります。
ECHONET LiteはECHONET規格をより発展させたものです。
1-1. ECHONET Liteの電文構成
通信はUDPの3610ポートを使用します。
ECHONET Liteでエアコンの電源をONにする時の電文を簡易化したものを下記に示します。
| ポート番号 | おまじない1 | おまじない2 | 識別番号 | 送信元機器番号 | 送信先機器番号 | サービス | 機能 | データ |
|---|---|---|---|---|---|---|---|---|
| port | EHD1 | EHD2 | TID | SEOJ | DEOJ | ESV | EPC | EDT |
| 3610 | 0x01 | 0x08 | 0x0001 | 0x05FF01 | 0x13001 | 0x61 | 0x80 | 0x30 |
| ECHONET Liteポート | ECHONET Lite識別1 | ECHONET Lite識別2 | 識別番号 | コントローラ | エアコン | 設定 | 動作状態 | ON |
1-2.ECHONET Liteのサービス
ECHONET Liteには大きく3つのサービスがあります。
ECHONET Lite機器はこれらのサービスに対応できるように作られています。
細かい部分を理解したい方は第2部 ECHONET Lite通信ミドルウェア仕様 を読んでください
1-2-a. SET
設定する時に使います
例:コントローラがエアコンの電源をONにするときは以下のような処理を行っています。
1-2-b. GET
データを取得する時に使います
例:コントローラがエアコンの温度データを取得するときは以下のような処理を行っています。
1-2-c. INF
情報を通知する時に使います
例:エアコンがコントローラに電源がONになったことをお知らせする際は以下の処理を行っています。
2. 要件を定義しよう
2-1. APPENDIX ECHONET機器オブジェクト詳細規定を読もう
ECHONET Liteで対応可能な機器機能の全てが書かれています。
ECHONET Lite規格の家電を作る際はこの規格書に適合するように作ります。
APPENDIX ECHONET機器オブジェクト詳細規定

2-2. 作る家電と機能を決めよう
製作する家電を決めましょう。
今回は単機能照明を例に製作します。
APPENDIX ECHONET機器オブジェクト詳細規定単機能照明のページ(pp.433)は以下のように書かれています。

今回は搭載プロパティ(機能)を動作状態(ON/OFF)と照度レベル設定(調光)とします。
1-3. 構成図を作成しよう
通信と制御をするためのWi-Fi搭載マイクロコンピュータと光らせるためのLEDを用意します。
3. 照明用の配線を作ろう
3-1. 材料を用意しよう
-
ESP32系の開発ボードならほぼ何でも可(EspressifSystems製又はXIAO製がお勧め)
今回の説明ではESP-WROOM-32を使用します。 - LED 5mm砲弾型
- 1/4W抵抗 220~1000[Ω]
- ジャンパー線 2本
- ブレットボード
3-2. 配線をしよう
3-2-a. ブレットボードにESP32系の開発ボードを挿そう
力を入れ過ぎて怪我をしないように気をつけてください
アンテナに力を入れないようにしてください。折れます。
3-2-b. LEDの極性を確認してブレットボードに挿そう
3-2-c. 抵抗を挿そう
3-2-d. +側の配線をしよう
3-2-e. -側の配線をしよう
4.プログラムを書こう
4-1. ESP32のボードライブラリをインストールする
ESP32のライブラリは必ずV3.0以上を使用してください
V3.0.0未満のボードライブラリはPWM(電圧出力)の仕様が異なり、プログラムが動作しません
4-1-a. Arduino IDEを起動する
4-1-b. ファイルを押す
4-1-c. 基本設定を押す
4-1-d. OK上にあるボタンを押す
4-1-e. 「クリックして非公式のボードをサポートするURLのリスト」を表示を押す
4-1-f. ESP32の欄を探してURLをコピーする
4-1-g. URLを張り付けて、OKを押す
4-1-h. OKを押す
4-1-i. Arduino IDEを再起動する
4-1-j. 左側の灰色の上から2個目のボタンを押す
4-1-k. 「ESP32」と入力して検索する
4-1-l. Espressif Systemsのライブラリの「インストール」ボタンを押す
4-1-m. 削除が表示されたらインストール完了
4-2. Arduino用ECHONET Liteライブラリをインストールしよう
Arduino用ECHONET LiteライブラリEL_dev_arduinoを使用します。
このライブラリを使用することで簡単にECHONET Lite対応のデバイスやコントローラを作れます。
EL_dev_arduinoはArduinoのECHONET Liteプロトコル通信をサポートします.
(ECHONET Liteプロトコルはスマートハウス機器の通信プロトコルです.)
本モジュールはECHONET Lite認証を受けたものではありませんので、商品化する際には開発者自らが認証を受ける必要があります。
本ライブラリは神奈川工科杉村研究室で開発中のライブラリです。
MIT License
Copyright (c) 2018 Hiroshi SUGIMURA
4-2-a.Arduino IDEを起動
4-2-b.ライブラリを選択
4-2-c.検索バーにECHONET Liteを入力
4-2-d.インストールをクリック
4-2-e.削除が表示されたらインストール完了
5.PWMのプログラムを書こう
5-1. ESP32でPWMをする方法
ESP32は通常のArudinoとPWMの仕様が異なり、analogWite関数は使えません。
ESP32はledcWrite関数を使います。
PWMの設定は以下形式でします。
ledcAttach(2,20000,8);// 2番ピンのPWMを20kHzの8bitでセット
PWMの出力値を指定する場合は以下の形式で書きます。
ledcWrite(2, 255); // 2番ピンを255の出力にする
5-2. 実際にLEDの明るさが段階的に変わるプログラムを書いてみよう
#define LUMP_pin 2 //LUMP_pinをIOpinの2番に指定
//マイコンボードに合わせて変更してください
void setup() //起動時の実行する
{
ledcAttach(LUMP_pin,20000,8);// LUMP_pinのPWMを20kHzの8bitでセット
ledcWrite(LUMP_pin, 0);// LUMP_pinのPWM出力を0にする
delay(1000);//1000ms待つ
}
void loop() //無限にループして、実行し続ける
{
for (int i=0; i<=255; i+=63) //iの初期値を0にして、iの値が255になるまで、iの値に31を足す
{
ledcWrite(LUMP_pin, i); //LUMP_pinをiのPWM出力にする
delay(1000);//1000ms待つ
}
for (int i=252; 0<=i; i-=63) //iの初期値を252にして、iの値が0になるまで、iの値から31を引く
{
ledcWrite(LUMP_pin, i); //LUMP_pinをiのPWM出力にする
delay(1000);//1000ms待つ
}
}
5-3. 書き込み
5-3-a. PCとESP32をUSBケーブルで接続する
5-3-b. ボードの部分を押す
5-3-c. ポートを選択する(マウスなどの別でデバイスを選ばないように注意)
5-3-d. ボードの欄にESP32 dev Moduleと入力する。
XIAO_ESP32C3の場合はXIAO ESP32C3と入力する。
XIAO_ESP32C6の場合はXIAO ESP32C6と入力する。
XIAO_ESP32S3の場合はXIAO ESP32S3と入力する。
ESP32-S2-DevKitの場合はESP32S2 dev Moduleと入力する。
ESP32-S3-DevKitの場合はESP32S3 dev Moduleと入力する。

5-3-e. ESP32 dev Moduleを選択する
XIAO_ESP32C3の場合はXIAO_ESP32C3を選択する。
XIAO_ESP32C6の場合はXIAO_ESP32C6を選択する。
XIAO_ESP32S3の場合はXIAO_ESP32S3を選択する。
ESP32-S2-DevKitの場合はESP32S2_dev_Moduleを選択する。
ESP32-S3-DevKitの場合はESP32S3_dev_Moduleを選択する。

5-3-f. OKを押す
5-3-g. 書き込みボタンを押す
5-3-g. 書込み完了
5-4. 動作確認
6. ECHONET Lite単機能照明(ON/OFFのみ)を作ってみよう
6-1. とりあえずプログラムを書いてみよう
以下のプログラムをコピペする
Wi-FiのSSIDとパスワードを今いる場所のWi-Fi用に変更する
#include <Arduino.h>
#include <WiFi.h>
#include "EL.h"
//--------------LED
#define LUMP_pin 2 //LUMP_pinをIOpinの3番に指定
bool Lflag = false;
uint8_t BRIGHTNESS = 100;//照度初期値を100にする
//--------------WIFI
#define WIFI_SSID "SSID"
#define WIFI_PASS "PASS"
WiFiUDP elUDP;
IPAddress myip;
//--------------EL
#define OBJ_NUM 1
EL echo(elUDP, { { 0x02, 0x91, 0x01 } } ); //クラス02 単機能照明91 インスタンスコード 01
void printNetData();
//====================================================================
// user用のcallback
// 受信したらこの関数が呼ばれるので、SetやGetに対して動けばよい、基本はSETだけ動けばよい
// 戻り値や引数は決まっている
// bool (*ELCallback) ( tid, seoj, deoj, esv, opc, epc, pdc, edt);
bool callback(byte tid[], byte seoj[], byte deoj[], byte esv, byte opc, byte epc, byte pdc, byte edt[]) {
bool ret = false; // デフォルトで失敗としておく
if (deoj[0] != 0x02 || deoj[1] != 0x91) { return false; } // 照明ではないので無視
if (deoj[2] != 0x00 && deoj[2] != 0x01) { return false; } // インスタンスがないので無視
// -----------------------------------
// ESVがSETとかGETとかで動作をかえる、基本的にはSETのみ対応すればよい
switch (esv) {
// -----------------------------------
// 動作状態の変更 Set対応
case EL_SETI:
case EL_SETC:
switch (epc) {
case 0x80: // 電源 0x80
if (edt[0] == 0x30) { // ON 0x30
Serial.println("ON"); // シリアル
digitalWrite(LUMP_pin, HIGH); //LEDを指定の明るさBRIGHTNESSで点灯
Lflag = true;
echo.update(0, 0x80, { 0x30 }); // EL更新 ON
ret = true; // 処理できたので成功
}
else if (edt[0] == 0x31) { // OFF 0x31
Serial.println("OFF"); // シリアル
digitalWrite(LUMP_pin, LOW); //LEDを指定の明るさを0にする
Lflag = false;
echo.update(0, 0x80, { 0x31 }); // ELの更新 OFF
ret = true; // 処理できたので成功
}
break;
else {
ret = false; // 処理できない範囲は失敗
}
break;
}
break; // SETI, SETCここまで
case EL_GET:
break;
default: // 基本はtrueを返却
ret = true;
break;
}
return ret;
}
//====================================================================
// setup
void setup() {
Serial.begin(115200); // シリアル開始
pinMode(LUMP_pin,OUTPUT);
digitalWrite(LUMP_pin, LOW);// LUMP_pinの出力をOFFにする
//Wi-Fiの接続
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
printNetData(); // to serial (debug)
// print your WiFi IP address:
myip = WiFi.localIP();
echo.begin(callback); // EL 起動シーケンス
// 初期値設定(ライブラリでも処理済みだが書き換えるならココ)
echo.update(0, 0x80, { 0x31 }); // off
echo.update(0, 0x81, { 0xFF }); // 場所不定
echo.update(0, 0x82, { 0x00, 0x00, 0x52, 0x01 }); // Release R rev.1
// 識別番号はライブラリによる初期設定が[0xfe + メーカーコード + macアドレス12桁 + 0]
echo.update(0, 0x88, { 0x42 }); // 異常なし
echo.update(0, 0x8A, { 0x00, 0x00, 0x77 }); // 神奈川工科大学(000077)
echo.update(0, 0x8E, { 0x07, 0xE9, 0x07, 0x0C }); // 製造年月日(2025/07/13)
echo.update(0, 0x9D, { 0x80 }); // INFプロパティマップ
echo.update(0, 0x9E, { 0x80}); // Setプロパティマップ
echo.update(0, 0x9F, { 0x80, 0x81, 0x82, 0x83, 0x88, 0x8A, 0x8E, 0x9D, 0x9E, 0x9F }); // Getプロパティマップ
echo.printAll(); // 全設定値の確認
// 一般照明の状態,繋がった宣言として立ち上がったことをコントローラに知らせるINFを飛ばす
const byte deoj[] = { 0x05, 0xFF, 0x01 };
const byte edt[] = { 0x01, 0x31 };
echo.sendMultiOPC1(deoj, EL_INF, 0x80, edt);
}
//====================================================================
// main loop
void loop() {
echo.recvProcess();
delay(100);
}
//////////////////////////////////////////////////////////////////////
// debug用
//////////////////////////////////////////////////////////////////////
void printNetData() {
Serial.println("-----------------------------------");
// IP
// print your WiFi shield's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
IPAddress dgwip = WiFi.gatewayIP();
Serial.print("DGW Address: ");
Serial.println(dgwip);
IPAddress smip = WiFi.subnetMask();
Serial.print("SM Address: ");
Serial.println(smip);
byte mac[6];
WiFi.macAddress(mac);
Serial.print("Arduino MAC: ");
Serial.print(mac[5], HEX);
Serial.print(":");
Serial.print(mac[4], HEX);
Serial.print(":");
Serial.print(mac[3], HEX);
Serial.print(":");
Serial.print(mac[2], HEX);
Serial.print(":");
Serial.print(mac[1], HEX);
Serial.print(":");
Serial.println(mac[0], HEX);
Serial.print("M5 MAC: ");
Serial.println(WiFi.macAddress());
Serial.print("M5 MAC(AP): ");
Serial.println(WiFi.softAPmacAddress());
Serial.println("-----------------------------------");
}
//////////////////////////////////////////////////////////////////////
// EOF
//////////////////////////////////////////////////////////////////////
6-2. 書込み
不明な点があれば5-3. 書き込みを参照してください
6-3. 動作テスト
この章はiPhone又はiPad用のアプリケーションで動作テストをします。
iPhone又はiPadが無い場合は7-3. 動作テストの方法をお試しください
6-3-a. シリアルモニターを表示
6-3-b. シリアルモニターをスクロールしてIPアドレスを探す
6-3-c. EL Controllerを用いて動作確認をする
- EL Controllerをダウンロードしてください
-
EL Controllerが入った端末をプログラムで書き込んだWi-Fiルーターと同じネットに接続する -
EL Controllerを立ち上げてください - メモしたIPアドレスと同じIPアドレスの機器を押す
- ONボタンを押す(画面上の青いボタンが押せます)ー>LEDは光る?
- OFFボタンを押す(画面上の青いボタンが押せます)ー>LEDの光は消える?
6-4. プログラムの解説
基本的にはプログラムのコメント文読んでね
setup関数内の[echo.update]で各プロパティの初期設定をしています。
recvProcess関数内で呼び出しに対する対応を書いています。
7. ECHONET Lite単機能照明(ON/OFF+調光)を作ってみよう
できる方は6.で作ったECHONET Liteの単機能照明のプログラムに調光機能を追加してみてください。
PWMの関数は5.を参考にすれば作れます。
7-1. プログラムを書いてみよう
以下のプログラムをコピペする
Wi-FiのSSIDとパスワードを今いる場所のWi-Fi用に変更する
/*
ライブラリの使い方。
1.APPENDIX ECHONET機器オブジェクト詳細規定を読んで使う機能を決める。https://echonet.jp/spec_object_rr3/
2.IOpinを#defineを用いてマイコンボードの使いたいピン番号を設定する。
3.setup関数内でIOpinの初期設定をする。
4.40行目くらいから始まるcallback関数のswhcin文内に、APPENDIX ECHONET機器オブジェクト詳細規定に基づく動作を書く。
5.使えるAPPENDIX ECHONET機器オブジェクト番号をまとめて120行目辺りの設定部に列挙する。
6.マイコンボードに書き込む。
7.ssngなどを用いてECHONET Liteの電文を送信して所定の動作をするかテストする。
完成
*/
#include <Arduino.h>
#include <WiFi.h>
#include "EL.h"
//--------------LED
#define LUMP_pin 2 //LUMP_pinをIOpinの4番に指定
bool Lflag = false;
byte BRIGHTNESS = 0x64;
//--------------WIFI
#define WIFI_SSID "SSID"
#define WIFI_PASS "PASS"
WiFiUDP elUDP;
IPAddress myip;
//--------------EL
#define OBJ_NUM 1
EL echo(elUDP, { { 0x02, 0x91, 0x01 } } ); //クラス02 単機能照明91 インスタンスコード 01
void printNetData();
//====================================================================
// user用のcallback
// 受信したらこの関数が呼ばれるので、SetやGetに対して動けばよい、基本はSETだけ動けばよい
// 戻り値や引数は決まっている
// bool (*ELCallback) ( tid, seoj, deoj, esv, opc, epc, pdc, edt);
bool callback(byte tid[], byte seoj[], byte deoj[], byte esv, byte opc, byte epc, byte pdc, byte edt[]) {
bool ret = false; // デフォルトで失敗としておく
if (deoj[0] != 0x02 || deoj[1] != 0x91) { return false; } // 照明ではないので無視
if (deoj[2] != 0x00 && deoj[2] != 0x01) { return false; } // インスタンスがないので無視
// -----------------------------------
// ESVがSETとかGETとかで動作をかえる、基本的にはSETのみ対応すればよい
switch (esv) {
// -----------------------------------
// 動作状態の変更 Set対応
case EL_SETI:
case EL_SETC:
switch (epc) {
case 0x80: // 電源 0x80
if (edt[0] == 0x30) { // ON 0x30
Serial.println("ON"); // シリアル
ledcWrite(LUMP_pin, int((BRIGHTNESS*255)/100)); //LEDを指定の明るさBRIGHTNESSで点灯
Lflag = true;
echo.update(0, 0x80, { 0x30 }); // EL更新 ON
ret = true; // 処理できたので成功
}
else if (edt[0] == 0x31) { // OFF 0x31
Serial.println("OFF"); // シリアル
ledcWrite(LUMP_pin, 0); //LEDを指定の明るさを0にする
Lflag = false;
echo.update(0, 0x80, { 0x31 }); // ELの更新 OFF
ret = true; // 処理できたので成功
}
break;
case 0xB0: // 照度レベル 0xB0
if (0 <= edt[0] && edt[0] <= 100) { // [0--100]
Serial.printf("照度レベル B0: %d\n", edt[0]); // 設定した値にする
BRIGHTNESS = int(edt[0]); // [0~100段階を0~255(8it範囲)段階に変換
if(Lflag) {
ledcWrite(LUMP_pin, int((BRIGHTNESS*255)/100)); //LEDを指定の明るさBRIGHTNESSで点灯
}
echo.update(0, epc, { edt[0] }); // ELの更新 照度
ret = true; // 処理できたので成功
}
else {
ret = false; // 処理できない範囲は失敗
}
break;
}
break; // SETI, SETCここまで
case EL_GET:
break;
default: // 基本はtrueを返却
ret = true;
break;
}
return ret;
}
//====================================================================
// main loop
void setup() {
Serial.begin(115200); // シリアル開始
pinMode(LUMP_pin,OUTPUT);
ledcAttach(LUMP_pin,20000,8);// LUMP_pinのPWMを20kHzの8bitでセット
ledcWrite(LUMP_pin, 0);// LUMP_pinのPWM出力を0にする
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
printNetData(); // to serial (debug)
// print your WiFi IP address:
myip = WiFi.localIP();
echo.begin(callback); // EL 起動シーケンス
// 初期値設定(ライブラリでも処理済みだが書き換えるならココ)
echo.update(0, 0x80, { 0x31 }); // off
echo.update(0, 0x81, { 0xFF }); // 場所不定
echo.update(0, 0x82, { 0x00, 0x00, 0x52, 0x01 }); // Release R rev.1
//echo.update(0, 0x83, { 0x00 }); // 識別番号未設定
// ライブラリによる初期設定が[0xfe + メーカーコード + macアドレス12桁 + 0]
echo.update(0, 0x88, { 0x42 }); // 異常なし
echo.update(0, 0x8A, { 0x00, 0x00, 0x77 }); // 神奈川工科大学(000077)
echo.update(0, 0x8E, { 0x07, 0xE8, 0x01, 0x01 }); // 製造年月日(2024/01/01)
echo.update(0, 0xB0, { 0x64 }); // 照度通常灯
echo.update(0, 0x9D, { 0x80, 0xB0 }); // INFプロパティマップ
echo.update(0, 0x9E, { 0x80, 0xB0 }); // Setプロパティマップ
echo.update(0, 0x9F, { 0x80, 0x81, 0x82, 0x83, 0x88, 0x8A, 0x8E, 0xB0, 0x9D, 0x9E, 0x9F }); // Getプロパティマップ
echo.printAll(); // 全設定値の確認
// 一般照明の状態,繋がった宣言として立ち上がったことをコントローラに知らせるINFを飛ばす
const byte deoj[] = { 0x05, 0xFF, 0x01 };
const byte edt[] = { 0x01, 0x31 };
echo.sendMultiOPC1(deoj, EL_INF, 0x80, edt);
}
//====================================================================
// main loop
void loop() {
echo.recvProcess();
delay(10);
}
//////////////////////////////////////////////////////////////////////
// debug用
//////////////////////////////////////////////////////////////////////
void printNetData() {
Serial.println("-----------------------------------");
// IP
// print your WiFi shield's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
IPAddress dgwip = WiFi.gatewayIP();
Serial.print("DGW Address: ");
Serial.println(dgwip);
IPAddress smip = WiFi.subnetMask();
Serial.print("SM Address: ");
Serial.println(smip);
byte mac[6];
WiFi.macAddress(mac);
Serial.print("Arduino MAC: ");
Serial.print(mac[5], HEX);
Serial.print(":");
Serial.print(mac[4], HEX);
Serial.print(":");
Serial.print(mac[3], HEX);
Serial.print(":");
Serial.print(mac[2], HEX);
Serial.print(":");
Serial.print(mac[1], HEX);
Serial.print(":");
Serial.println(mac[0], HEX);
Serial.print("M5 MAC: ");
Serial.println(WiFi.macAddress());
Serial.print("M5 MAC(AP): ");
Serial.println(WiFi.softAPmacAddress());
Serial.println("-----------------------------------");
}
//////////////////////////////////////////////////////////////////////
// EOF
//////////////////////////////////////////////////////////////////////
7-2. 書込み
不明な点があれば5-3. 書き込みを参照してください
7-3. 動作テスト
7-3-a. シリアルモニターを表示
7-3-b. シリアルモニターをスクロールしてIPアドレスを探す
7-3-c. EL Controllerを用いて動作確認をする
-
SSNGをダウンロードしてください
-
SSNGが入った端末をプログラムで書き込んだWi-Fiルーターと同じネットに接続する -
SSNGを立ち上げてください -
セキュリティやネットの警告や許可の問い合わせが来たら必ず許可をしてください
許可をしないと後で面倒な設定作業が必要になります。 -
EPCの欄に照度のプロパティである
0xB0、EDTの欄に50%の16進数データである0x32を入力する -
SENDを押すー>LEDの明るさは50%になる? -
EDTの欄にOFFのデータである
0x31を入力する -
SENDを押すー>LEDの光は消える? 照明からのResはある?
7-4. プログラムの解説
基本的にはプログラムのコメント文読んでね
setup関数内の[echo.update]で各プロパティの初期設定をしています。
recvProcess関数内で呼び出しに対する対応を書いています。
今回のプログラムは照度プロパティの0xB0追記に必用な部分を書いています。
6のプログラムとの差分を読んで、プロパティを追加するときに必用な要素を見つけてください。
8. 楽しいECHONET Lite家電自作Lifeを
販売する時は正しくECHONET Liteの認証を通して、ECHONET Liteコンソーシアムに加入して販売するようにしてください


































