1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ESP32でECHONET Lite対応機器をつくるチュートリアル

Last updated at Posted at 2024-05-24

1. はじめに

スマートホーム通信規格であるECHONET Liteに対応したデバイスをつくるチュートリアル的な記事です。ここでは、一般照明と定義されるものをつくる手順を紹介します。

完成品は写真のようになります。

IMG_9892.jpg


また、以下の記事のアップデート版のようなものであり併読を推奨します。

---本記事を読むにあたって---

  • ECHONET Liteの電文理解
  • ECHONET機器オブジェクト詳細規定
  • Arduino IDEでのコーディング
  • 簡単な電子回路

これらの知識が必要です。

また、当記事の内容は一切の責任を負いかねますのでご了承ください。
書いてあることだけでは何も事故は起きないと思いますが...

2. 使用機材

  • ESP32搭載マイコン(Arduino IDEで利用できるもの)
    ESP32-S3-DevKitなど、既製品を利用すると便利です。当記事では、S3のDevKitを使用します。

esp32-s3-dev.jpg

  • マイコン内蔵フルカラーテープLED
    秋月電子で販売されているマイコン内蔵LEDです。素子の個別制御が可能であり、ライブラリも用意されているため扱いやすいです。

  • その他
    ジャンパ線

以下あると便利なアイテム
  • ACアダプタと変換端子台
    LEDテープの消費電力を補うためのものです。基板からの供給で十分ですが、ほかの素子と合わせる場合は推奨です。

ACアダプタ

変換端子台

3. 環境設定

Arduino IDEを利用します。レガシー版(1.x.x)ではなく、メジャー版(2.x.x)を導入してください。


はじめに、ボードマネージャの設定をします。ESP32搭載基板をArduino IDEに対応させます。 ファイル -> 基本設定を開く

IDE1.png

追加のボードマネージャのURLに以下のアドレスを記載、OKをクリックして保存します。

https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json

IDE2.png

左側のボードマネージャアイコンをクリックして開き、検索欄に"esp32"と入力します。出てきたものから、Espressif Systemsの提供するボードマネージャをインストールします。

IDE3.png

つぎに、ライブラリを導入します。ボードマネージャと同様にアイコンをクリックして開き、以下のライブラリをインストールします。

  • Adafruit NeoPixel by Adafruit
  • EL_dev_arduino by Hiroshi SUGIMURA

~~~ライブラリの紹介~~~

EL_dev_arduinoはECHONET Liteの通信をサポートするモジュールです。神奈川工科大学 杉村研究室で開発を進めています。

4. プログラムの書き込み

以下にサンプルコードを記述します。Arduino IDEにコピー&ペーストしてそのまま利用できます。
6-7,19,20行目は環境に応じて書き換えが必要です。

ソースコードを表示(折りたたみ)
#include <WiFi.h>
#include "EL.h"
#include <Adafruit_NeoPixel.h>

//--------------WIFI
#define WIFI_SSID "ここにSSID"
#define WIFI_PASS "ここにKEY"

WiFiUDP elUDP;
IPAddress myip;

//--------------EL
#define OBJ_NUM 1

EL echo(elUDP, { { 0x02, 0x90, 0x01 } } );
//クラスグループコード 住宅・設備関連機器:0x02, クラスコード 一般照明 : 0x90, インスタンスコード 01

//--------------LED
#define LED_PIN 6      // NeoPixelの出力ピン番号
#define LED_NUM 7      // LEDの連結数(素子の個数)
#define LUMINANCE 255  // 輝度の制限(最大値 : 255)

Adafruit_NeoPixel strip(LED_NUM, LED_PIN, NEO_GRB + NEO_KHZ800);

//--------------VARIABLES
uint8_t LED_R = 255, LED_G = 255, LED_B = 255, BRIGHTNESS = LUMINANCE;

//====================================================================
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] != 0x90) { 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:
          if (edt[0] == 0x30) {
            Serial.println("電源ON 80 : 30");
            strip.clear();
            strip.setBrightness(BRIGHTNESS);
            for (int i = 0; i < LED_NUM; i++)
              strip.setPixelColor(i, strip.Color(LED_R, LED_G, LED_B));
            strip.show();
            echo.update(0, epc, { 0x30 });
            echo.update(0, 0xB6, { 0x42 });
            ret = true;
          }
          else if (edt[0] == 0x31) {
            Serial.println("電源OFF 80 : 31");
            strip.clear();
            strip.show();
            echo.update(0, epc, { 0x31 });
            ret = true;
          }
          else {
            ret = false;
          }
          break;

        // 照度の設定 edtを[0x00-0x64]で指定することで明るさに反映
        case 0xB0:
          if (0 <= edt[0] && edt[0] <= 100) {
            Serial.printf("照度レベル B0 : %d\n", edt[0]);
            strip.clear();
            BRIGHTNESS = int(edt[0]) * (LUMINANCE / 100);
            strip.setBrightness(BRIGHTNESS);
            for (int i = 0; i < LED_NUM; i++)
              strip.setPixelColor(i, strip.Color(LED_R, LED_G, LED_B));
            strip.show();
            echo.update(0, epc, { edt[0] });
            ret = true;
          }
          else {
            ret = false;
          }
          break;

        // LED点灯モードの設定 edtを[0x41-0x45]で指定してモードの変更
        case 0xB6:
          switch (edt[0]) {
            case 0x41:
              Serial.println("点灯モード 自動 B6 : 41");
              LED_R = LED_G = LED_B = 255;  // 白
              strip.clear();
              strip.setBrightness(LUMINANCE * 0.7);
              for (int i = 0; i < LED_NUM; i++)
                strip.setPixelColor(i, strip.Color(LED_R, LED_G, LED_B));
              strip.show();
              echo.update(0, epc, { edt[0] });
              echo.update(0, 0xC0, { LED_R, LED_G, LED_B });
              ret = true;
              break;

            case 0x42:
              Serial.println("点灯モード 通常灯 B6 : 42");
              LED_R = LED_G = LED_B = 255;  // 白
              strip.clear();
              strip.setBrightness(LUMINANCE);
              for (int i = 0; i < LED_NUM; i++)
                strip.setPixelColor(i, strip.Color(LED_R, LED_G, LED_B));
              strip.show();
              echo.update(0, epc, { edt[0] });
              echo.update(0, 0xC0, { LED_R, LED_G, LED_B });
              ret = true;
              break;

            case 0x43:
              Serial.println("点灯モード 常夜灯 B6 : 43");
              LED_R = 255, LED_G = 48, LED_G = 0;
              strip.clear();
              strip.setBrightness(LUMINANCE * 0.2);
              for (int i = 0; i < LED_NUM; i++)
                strip.setPixelColor(i, strip.Color(LED_R, LED_G, LED_B));
              strip.show();
              echo.update(0, epc, { edt[0] });
              echo.update(0, 0xC0, { LED_R, LED_G, LED_B });
              ret = true;
              break;

            case 0x45:
              Serial.println("点灯モード カラー灯 B6 : 45");
              LED_R = 0, LED_G = 0, LED_B = 255;
              strip.clear();
              strip.setBrightness(LUMINANCE * 0.5);
              for (int i = 0; i < LED_NUM; i++)
                strip.setPixelColor(i, strip.Color(LED_R, LED_G, LED_B));
              strip.show();
              echo.update(0, epc, { edt[0] });
              echo.update(0, 0xC0, { LED_R, LED_G, LED_B });
              ret = true;
              break;

            default:
              ret = false;
              break;
          }
          break;

        // カラー灯モード時RGB設定 edtの6桁でカラーコード指定
        case 0xC0:
          if (0 <= edt[0] && edt[0] <= 255) {
            if(0 <= edt[1] && edt[1] <= 255) {
              if(0 <= edt[2] && edt[2] <= 255) {
                LED_R = edt[0], LED_G = edt[1], LED_B = edt[2];
                Serial.printf("C0 : %d, %d, %d\n", LED_R, LED_G, LED_B);
                  strip.clear();
                for (int i = 0; i < LED_NUM; i++)
                  strip.setPixelColor(i, strip.Color(LED_R, LED_G, LED_B));
                strip.show();
                echo.update(0, epc, { LED_R, LED_G, LED_B });
                echo.update(0, 0xB6, { 0x45 });
                ret = true;
              }
            }
          }
          break;
      }
      // SETI, SETCここまで
      break;
    
    case EL_GET:
      break;

    // 基本はtrueを返却
    default:
      ret = true;
      break;
  }

  return ret;
}


//====================================================================
// main loop
void setup() {

  // シリアル開始
  Serial.begin(115200);

  // LED制御開始
  strip.begin();
  strip.clear();
  strip.setBrightness(0);
  strip.show();

  WiFi.begin(WIFI_SSID, WIFI_PASS);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(1000);
  }

  // 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 + メーカーコード6桁 + macアドレス12桁 + 0x0e, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00]
  echo.update(0, 0x88, { 0x42 });                                                                          // 異常なし
  echo.update(0, 0x8A, { 0x00, 0x00, 0x77 });                                                              // 神奈川工科大学(000077)
  echo.update(0, 0x8E, { 0x07, 0xE8, 0x01, 0x01 });                                                        // 製造年月日(2023/01/01)
  echo.update(0, 0xB0, { BRIGHTNESS });                                                                    // 照度
  echo.update(0, 0xB6, { 0x42 });                                                                          // 通常灯
  echo.update(0, 0xC0, { LED_R, LED_G, LED_B });                                                           // 色設定(白)
  echo.update(0, 0x9D, { 0x80, 0xD6 });                                                                    // INFプロパティマップ
  echo.update(0, 0x9E, { 0x80, 0xB0, 0xB6, 0xC0 });                                                        // Setプロパティマップ
  echo.update(0, 0x9F, { 0x80, 0x81, 0x82, 0x83, 0x88, 0x8A, 0x8E, 0xB0, 0xB6, 0xC0, 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(300);
}

5. 動かしてみる

書込みが終わると、自動的にWi-Fiへの接続を試みます。PCとの接続を解除して、LEDテープを基板とつなげましょう。

LEDテープを点灯させる際は、必ずリールからほどきましょう。かなり発熱します。

LEDT-B.jpg

電源を併用するのであれば、端子台を活用して組みましょう。

LEDT-D.jpg

PCに接続している場合、Arduino IDEのシリアルモニタから動作を確認できます。

IDE4.jpg

SSNG(ECHONET Liteツール)やEL Lightning(iPhone用アプリ)での表示も確認できます。

SSNG1.jpg

EL_APP1.PNG

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?