M5 Atome Lite・Atom Matrixでおうちハック! ECHONET Lite によるスマートハウス操作 実践編
※このページは、神奈川工科大学 コミュニケーションロボティクス研究室および 電気電子工学科/ホームエレクトロニクス開発学科の実習用チュートリアル用のページです。
https://scrapbox.io/files/683184f93a5f2d7cd25167de.mp4
※入門編はこちら
M5 Atome Lite・Atom Matrixでおうちハック! ECHONET Lite によるスマートハウス操作 入門編
1. やりたいこと
Atom Lite、Atom Matrixでスマート家電を操作する
具体的にやること
Atom Lite、Atom Matrix からUDP通信でECHONET Lite電文を送りスマート家電を操作
2. 対象機器
照明(Toshiba) 192.168.0.15
エアコン(Toshiba) 192.168.0.9
3. IoTルームでの構成 ※神奈川工科大学電気電子情報工学科の施設です
code:構成
Atom Lite/Matrix (Wifi/UDP) ──┬── 照明 192.168.0.15 /3610 (東芝ホームゲートウェイからBluetooth接続)
└──エアコン 192.168.0.9 /3610
Atom Lite/Marix から UDP通信でECHONET Liteコマンドを投げて制御
照明 ON/OFF
エアコン ON/OFF
4. サンプルプログラム
サンプル① Atome Liteのスイッチを用いてEchonet lite 照明のON-OFF
※SSIDとパスワードのところだけ書き換えれば照明のオンオフができます。
code: Switch_UDP_IoTR.ino
//Part1: ライブラリのインクルード・変数の宣言
#include <M5Atom.h>
#include <WiFi.h>
#include <WiFiUdp.h>
#define WIFI_SSID "*******" // IoT-roomのSSIDの設定
#define WIFI_PASS "*******" // パスワード
// Wifi設定
static WiFiUDP wifiUdp;
static const char *kRemoteIpadr = "192.168.0.15"; // ECHONET Lite機器(照明)のIP
static const int kRmoteUdpPort = 3610;
// ECHONET LiteのON/OFFデータ
byte SendBufferON[] = {0x10,0x81,0x00,0x00,0x05,0xFF,0x01,0x02,0x90,0x01,0x60,0x01,0x80,0x01,0x30};
byte SendBufferOFF[] = {0x10,0x81,0x00,0x00,0x05,0xFF,0x01,0x02,0x90,0x01,0x60,0x01,0x80,0x01,0x31};
bool lightIsOn = false;
bool lastButtonState = false;
//Part2: setup関数
void setup() {
M5.begin(true, false, true);
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) {
Serial.println("Connecting to WiFi...");
delay(1000);
}
Serial.println("WiFi connected");
// WiFi接続成功時にLEDを白色に点灯
M5.dis.drawpix(0, 0xFFFFFF);
}
//Part3: loop関数
void loop() {
M5.update();
bool currentButtonState = M5.Btn.isPressed();
if (currentButtonState && !lastButtonState) {
if (lightIsOn) {
// ECHONET Liteコマンド送信処理1:照明ONのとき -> 照明OFFに
wifiUdp.beginPacket(kRemoteIpadr, kRmoteUdpPort);
wifiUdp.write((const uint8_t*)SendBufferOFF, sizeof(SendBufferOFF));
wifiUdp.endPacket();
Serial.println("Light OFF");
// LEDを赤に設定
M5.dis.drawpix(0, 0xFF0000);
} else {
// ECHONET Liteコマンド送信処理2:照明OFFのとき -> 照明ONに
wifiUdp.beginPacket(kRemoteIpadr, kRmoteUdpPort);
wifiUdp.write((const uint8_t*)SendBufferON, sizeof(SendBufferON));
wifiUdp.endPacket();
Serial.println("Light ON");
// LEDを緑に設定
M5.dis.drawpix(0, 0x00FF00);
}
lightIsOn = !lightIsOn; // 状態フラグをトグル(反転切り替え)
}
lastButtonState = currentButtonState;
delay(50); // チャタリング対策
}
サンプル② Atome Matrixの加速度センサ情報を用いたEchonet lite 照明のON-OFF
SSIDとパスワードのところだけ書き換えれば照明のオンオフができます。
code: Accel_UDP_IoTR.ino
#include <M5Atom.h>
#include <WiFi.h>
#include <WiFiUdp.h>
#define WIFI_SSID "******" // IoT-roomのSSIDの設定 ※変更の必要あり
#define WIFI_PASS "******" // パスワード  ※変更の必要あり
//Wifi設定
static WiFiUDP wifiUdp;
static const char *kRemoteIpadr = "192.168.0.15"; //E204リビング照明アドレス
static const int kRmoteUdpPort = 3610;
//Echonet-lite用変数の設定
//wifiUdp.writeで送信するためには
//①byte型の配列で設定→②const uint8_t*にキャスト
//という手順を踏む
byte SendBufferON[] ={0x10,0x81,0x00,0x00,0x05,0xFF,0x01,0x02,0x90,0x01,0x60,0x01,0x80,0x01,0x30};
byte SendBufferOFF[] ={0x10,0x81,0x00,0x00,0x05,0xFF,0x01,0x02,0x90,0x01,0x60,0x01,0x80,0x01,0x31};
float accX = 0, accY = 0, accZ = 0;
float x, y, z;
int FallAsleep_flag = 0;
bool IMU6886Flag = false;
void setup()
{
M5.begin(true, false, true);
if (M5.IMU.Init() != 0)
IMU6886Flag = false;
else
IMU6886Flag = true;
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) {
Serial.println("Connecting to WiFi...");
delay(1000);
}
}
void loop()
{
if (IMU6886Flag == true)
{
M5.IMU.getAccelData(&accX, &accY, &accZ); //スマホの寝落ちはピッチ(accY)で見れそう
if(fabsf(accY)<0.1){ //スマホが水平状態になったら
FallAsleep_flag++; //寝落ちフラグをカウント
if(FallAsleep_flag>10){ //寝落ちフラグが10を超過したら照明OFF
Serial.printf("Get up! %d \n", FallAsleep_flag);
wifiUdp.beginPacket(kRemoteIpadr, kRmoteUdpPort);
wifiUdp.write((const uint8_t*)SendBufferOFF, sizeof(SendBufferOFF));
wifiUdp.endPacket();
}else{
Serial.printf("%d \n", FallAsleep_flag);
}
}else{ //水平以外になったらカウントリセットして照明ON
FallAsleep_flag = 0;
Serial.printf("%d \n", FallAsleep_flag);
wifiUdp.beginPacket(kRemoteIpadr, kRmoteUdpPort);
wifiUdp.write((const uint8_t*)SendBufferON, sizeof(SendBufferON));
wifiUdp.endPacket();
delay(1000);
}
}
delay(500);
M5.update();
}
実装例
https://scrapbox.io/files/6831850096309cd84b0f37fa.mp4
https://scrapbox.io/files/683185084627d4f8b0dabeee.mp4
5. その他
UDP 通信/ECHONET Lite送信時の注意点
wifiUdp.writeで送信するためには下記の手順を踏む必要がある
①byte型の配列で電文設定
→②wifiUdp.write関数を使うときにconst uint8_t*にキャスト
電文の例
照明
byte LightON[] ={0x10,0x81,0x00,0x00,0x05,0xFF,0x01,0x02,0x90,0x01,0x60,0x01,0x80,0x01,0x30};
byte LightOFF[] ={0x10,0x81,0x00,0x00,0x05,0xFF,0x01,0x02,0x90,0x01,0x60,0x01,0x80,0x01,0x31};
エアコン
byte AirconON[] ={0x10,0x81,0x00,0x01,0x05,0xFF,0x01,0x01,0x30,0x01,0x60,0x01,0x80,0x01,0x30};
byte AirconOFF[] ={0x10,0x81,0x00,0x01,0x05,0xFF,0x01,0x01,0x30,0x01,0x60,0x01,0x80,0x01,0x31};
6. 参考
ECHONET Lite対応の部屋のエアコンをPython3から操作してみた
ECHONET Lite規格書のページ
ECHONET Liteリファレンス:ECHONET-Lite_Ver.1.14(02).pdf
※これを読めば電文をつくれます
#ECHONET-Lite #スマートハウス #IoT #ものづくりプロジェクトII
https://gyazo.com/71c7de59f100448c29cdb7f29fbd171b
Communication Robotics Lab.