M5StickCPlusとWi-SUN HAT(BP35A1)でスマートメーターと通信してみた。

スマートメーターと通信して電力消費量をみてみた。

ROHM BP35A1が引き出しに入っていたので image02

M5StickC/Plus用Wi-SUN HATキットをM5StickCとともに買ってみた。

image01

で。組み立てて。 image03

image04

image05

image06

サポートページどおり M5Burnerでファームウエアを書くまでは順調で。

「VS Code」をインストールし「M5StickC」を接続する

の所でどうしても「Add M5Stack」がでないのでうまくいかなかった。
一回休み。

仕方がないので自分でファームウエアを書く

どうしてもうまくいかないので諦めて自分で書くことにした。

最初はArduino IDEで書いていたんだけど書き込みが遅いので, VSCode + PlatformIOに変えました。

GitHubに置いときます

ビルドメッセージはこんなかんじ

*  実行するタスク: C:\Users\aki\.platformio\penv\Scripts\platformio.exe run --environment m5stick-c 

Processing m5stick-c (platform: espressif32; board: m5stick-c; framework: arduino)
----------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/espressif32/m5stick-c.html

PLATFORM: Espressif 32 (5.0.0) > M5Stick-C
HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash
DEBUG: Current (cmsis-dap) External (cmsis-dap, esp-bridge, esp-prog, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa)
PACKAGES: 
 - framework-arduinoespressif32 @ 3.20003.220626 (2.0.3) 
 - tool-esptoolpy @ 1.30300.0 (3.3.0) 
 - toolchain-xtensa-esp32 @ 8.4.0+2021r2-patch3
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 33 compatible libraries
Scanning dependencies...
Dependency Graph
|-- M5StickCPlus @ 0.0.8
|   |-- SPI @ 2.0.0
|   |-- Wire @ 2.0.0
|   |-- FS @ 2.0.0
|   |-- SPIFFS @ 2.0.0
|   |   |-- FS @ 2.0.0
Building in release mode
Compiling .pio\build\m5stick-c\src\main.cpp.o
Linking .pio\build\m5stick-c\firmware.elf
Retrieving maximum program size .pio\build\m5stick-c\firmware.elf
Checking size .pio\build\m5stick-c\firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [=         ]   5.6% (used 18368 bytes from 327680 bytes)
Flash: [===       ]  25.5% (used 333789 bytes from 1310720 bytes)
Building .pio\build\m5stick-c\firmware.bin
esptool.py v3.3
Creating esp32 image...
Merged 2 ELF sections
Successfully created esp32 image.
====================================== [SUCCESS] Took 10.24 seconds ======================================
 *  ターミナルはタスクで再利用されます、閉じるには任意のキーを押してください。 

PlatformIOとVSCodeを使ってビルドしてください。

platformio.ini に書いてあるようにArduinoフレームワークの上で動きます。

  • platform = espressif32
  • board = m5stick-c
  • framework = arduino

あと C++17 で書いてあるのでよろしく(PlatformIO標準で入るはず)。

実行

image07

通信ログ

通信の確認を目的に -DCORE_DEBUG_LEVEL=5 なのでログが大量に出る。

Web上に先人がおいてくれていたログが役にたったので自分もログを置いときます。
IDとパスワードそれにIPv6アドレスは0に置き換えてあります。

リンク置いときます

これはこんな流れですわ。
参考リンク1

ログ行の

  • [SEND]はこちらから送信したメッセージ
  • [RECEIVE]は受信したメッセージ
  • [MAIN]はプログラムからのメッセージ

とします。

1.始まり
エコーバックOFF, セッション終了(おまじないみたいなもん。開発中は何度もM5StickCが再起動するんで)

[  1668][D][main.cpp:912] write_with_crln(): [SEND] SKSREG SFE 0
[  1670][D][main.cpp:912] write_with_crln(): [SEND] SKTERM

1.BルートIDとパスワードの設定

[  2678][D][main.cpp:912] write_with_crln(): [SEND] SKSETPWD C 000000000000
[  2682][D][main.cpp:905] read_line_without_crln(): [RECEIVE] OK
[  2685][D][main.cpp:912] write_with_crln(): [SEND] SKSETRBID 00000000000000000000000000000000
[  2693][D][main.cpp:905] read_line_without_crln(): [RECEIVE] OK

1.スキャン
EVENT 22 アクティブスキャンの完了報告まで継続する。

[  2699][D][main.cpp:912] write_with_crln(): [SEND] SKSCAN 2 FFFFFFFF 4
[  2703][D][main.cpp:905] read_line_without_crln(): [RECEIVE] OK
[  7375][D][main.cpp:912] write_with_crln(): [SEND] SKSCAN 2 FFFFFFFF 5
[  7378][D][main.cpp:905] read_line_without_crln(): [RECEIVE] OK
[  8021][D][main.cpp:572] operator()(): [MAIN] EVENT "NUM":"22","SENDER":"0000:0000:0000:0000:0000:0000:0000:0000"
[  8022][D][main.cpp:912] write_with_crln(): [SEND] SKSCAN 2 FFFFFFFF 6
[  8030][D][main.cpp:905] read_line_without_crln(): [RECEIVE] OK
[ 24700][D][main.cpp:572] operator()(): [MAIN] EVENT "NUM":"20","SENDER":"0000:0000:0000:0000:0000:0000:0000:0000"
[ 25353][D][main.cpp:905] read_line_without_crln(): [RECEIVE]   Channel:3B
[ 25354][D][main.cpp:905] read_line_without_crln(): [RECEIVE]   Channel Page:09
[ 25356][D][main.cpp:905] read_line_without_crln(): [RECEIVE]   Pan ID:0000
[ 25363][D][main.cpp:905] read_line_without_crln(): [RECEIVE]   Addr:0000000000000000
[ 25370][D][main.cpp:905] read_line_without_crln(): [RECEIVE]   LQI:B2
[ 25377][D][main.cpp:905] read_line_without_crln(): [RECEIVE]   PairID:00000000
[ 25384][D][main.cpp:572] operator()(): [MAIN] EPANDESC "Addr":"0000000000000000","Channel":"3B","Channel Page":"09","LQI":"B2","PairID":"00000000","Pan ID":"0000"
[ 26040][D][main.cpp:572] operator()(): [MAIN] EVENT "NUM":"22","SENDER":"0000:0000:0000:0000:0000:0000:0000:0000"

1.見つけたスマートメーターのアドレスをIPv6アドレスに変換する。

[ 26049][D][main.cpp:912] write_with_crln(): [SEND] SKLL64 0000000000000000
[ 26152][D][main.cpp:905] read_line_without_crln(): [RECEIVE] 0000:0000:0000:0000:0000:0000:0000:0000
[ 26152][D][main.cpp:612] connect(): [MAIN] ipv6_address: "0000:0000:0000:0000:0000:0000:0000:0000",channel: "3B",pan_id: "0000"

1.チャンネル設定

[ 26166][D][main.cpp:912] write_with_crln(): [SEND] SKSREG S2 3B
[ 26169][D][main.cpp:905] read_line_without_crln(): [RECEIVE] OK

1.PAN ID設定

[ 26177][D][main.cpp:912] write_with_crln(): [SEND] SKSREG S3 0000
[ 26181][D][main.cpp:905] read_line_without_crln(): [RECEIVE] OK

1.スマートメーターに接続する

[ 26190][D][main.cpp:912] write_with_crln(): [SEND] SKJOIN 0000:0000:0000:0000:0000:0000:0000:0000
[ 26202][D][main.cpp:905] read_line_without_crln(): [RECEIVE] OK
[ 29529][D][main.cpp:656] connect(): [MAIN] Connected
[ 29533][D][main.cpp:519] boot(): [MAIN] connection successful
[ 29534][D][main.cpp:1089] setup(): [MAIN] setup success

接続成功。

  1. 係数取得

係数はありません。つまり1倍とのことで

[ 29563][D][main.cpp:1027] send_measurement_request(): [MAIN] request coefficient
[ 29564][D][main.cpp:712] send_request(): [MAIN] SKSENDTO 1 0000:0000:0000:0000:0000:0000:0000:0000 0E1A 1 000E 
[ 29721][D][main.cpp:905] read_line_without_crln(): [RECEIVE] EVENT 21 0000:0000:0000:0000:0000:0000:0000:0000 00
[ 29721][D][main.cpp:905] read_line_without_crln(): [RECEIVE] OK
[ 29933][D][main.cpp:1132] loop(): [MAIN] ERXUDP "DATA":"1081000102880105FF015201D300","DATALEN":"000E","DEST":"0000:0000:0000:0000:0000:0000:0000:0000","LPORT":"0E1A","RPORT":"0E1A","SECURED":"1","SENDER":"0000:0000:0000:0000:0000:0000:0000:0000","SENDERLLA":"0000000000000000"
[ 29946][D][main.cpp:1173] loop(): [MAIN] EHD1:10,EHD2:81,TID:0001,SEOJ:028801,DEOJ:05FF01,ESV:52,OPC:01,EPC:D3,PDC:00,EDT:
[ 29957][D][main.cpp:1223] loop(): [MAIN] no coefficient
  1. 0xD5メッセージ。インスタンスリストの配信

接続成功すると送られてくる。無視する。

[ 32617][D][main.cpp:1132] loop(): [MAIN] ERXUDP "DATA":"108103610EF0010EF0017301D50401028801","DATALEN":"0012","DEST":"FF02:0000:0000:0000:0000:0000:0000:0001","LPORT":"0E1A","RPORT":"0E1A","SECURED":"1","SENDER":"0000:0000:0000:0000:0000:0000:0000:0000","SENDERLLA":"0000000000000000"
[ 32631][D][main.cpp:1173] loop(): [MAIN] EHD1:10,EHD2:81,TID:0361,SEOJ:0EF001,DEOJ:0EF001,ESV:73,OPC:01,EPC:D5,PDC:04,EDT:01028801
[ 32643][D][main.cpp:1182] loop(): [MAIN] instances list
[ 32648][D][main.cpp:1188] loop(): [MAIN] total number of instances: 1
[ 32654][D][main.cpp:1197] loop(): [MAIN] list of object code(EOJ): 028801

1.単位取得
小数点以下2位と返事があった。

[ 50204][D][main.cpp:1027] send_measurement_request(): [MAIN] request unit for whm
[ 50205][D][main.cpp:712] send_request(): [MAIN] SKSENDTO 1 0000:0000:0000:0000:0000:0000:0000:0000 0E1A 1 000E 
[ 50334][D][main.cpp:905] read_line_without_crln(): [RECEIVE] EVENT 21 0000:0000:0000:0000:0000:0000:0000:0000 00
[ 50334][D][main.cpp:905] read_line_without_crln(): [RECEIVE] OK
[ 50801][D][main.cpp:1132] loop(): [MAIN] ERXUDP "DATA":"1081000102880105FF017201E10102","DATALEN":"000F","DEST":"0000:0000:0000:0000:0000:0000:0000:0000","LPORT":"0E1A","RPORT":"0E1A","SECURED":"1","SENDER":"0000:0000:0000:0000:0000:0000:0000:0000","SENDERLLA":"0000000000000000"
[ 50815][D][main.cpp:1173] loop(): [MAIN] EHD1:10,EHD2:81,TID:0001,SEOJ:028801,DEOJ:05FF01,ESV:72,OPC:01,EPC:E1,PDC:01,EDT:02
[ 50826][D][main.cpp:1240] loop(): [MAIN] *0.01 kwh

1.有効桁数取得
7桁と返事があった。

[ 70770][D][main.cpp:1027] send_measurement_request(): [MAIN] request number of effective digits
[ 70771][D][main.cpp:712] send_request(): [MAIN] SKSENDTO 1 0000:0000:0000:0000:0000:0000:0000:0000 0E1A 1 000E 
[ 70951][D][main.cpp:905] read_line_without_crln(): [RECEIVE] EVENT 21 0000:0000:0000:0000:0000:0000:0000:0000 00
[ 70951][D][main.cpp:905] read_line_without_crln(): [RECEIVE] OK
[ 71417][D][main.cpp:1132] loop(): [MAIN] ERXUDP "DATA":"1081000102880105FF017201D70107","DATALEN":"000F","DEST":"0000:0000:0000:0000:0000:0000:0000:0000","LPORT":"0E1A","RPORT":"0E1A","SECURED":"1","SENDER":"0000:0000:0000:0000:0000:0000:0000:0000","SENDERLLA":"0000000000000000"
[ 71431][D][main.cpp:1173] loop(): [MAIN] EHD1:10,EHD2:81,TID:0001,SEOJ:028801,DEOJ:05FF01,ESV:72,OPC:01,EPC:D7,PDC:01,EDT:07
[ 71442][D][main.cpp:1230] loop(): [MAIN] 7 effective digits.

1.積算電力量取得
2022/8/1 20:00:00 76999つまり769.99kwhと返事があった。
スマートメーターに表示されている値と同じなので確認してくる。
このメッセージは毎時 0分と30分に自動的に配信される。

[ 91387][D][main.cpp:1027] send_measurement_request(): [MAIN] request amounts of electric power
[ 91388][D][main.cpp:712] send_request(): [MAIN] SKSENDTO 1 0000:0000:0000:0000:0000:0000:0000:0000 0E1A 1 000E 
[ 91530][D][main.cpp:905] read_line_without_crln(): [RECEIVE] EVENT 21 0000:0000:0000:0000:0000:0000:0000:0000 00
[ 91531][D][main.cpp:905] read_line_without_crln(): [RECEIVE] OK
[ 91946][D][main.cpp:1132] loop(): [MAIN] ERXUDP "DATA":"1081000102880105FF017201EA0B07E6080114000000012CC7","DATALEN":"0019","DEST":"0000:0000:0000:0000:0000:0000:0000:0000","LPORT":"0E1A","RPORT":"0E1A","SECURED":"1","SENDER":"0000:0000:0000:0000:0000:0000:0000:0000","SENDERLLA":"0000000000000000"
[ 91962][D][main.cpp:1173] loop(): [MAIN] EHD1:10,EHD2:81,TID:0001,SEOJ:028801,DEOJ:05FF01,ESV:72,OPC:01,EPC:EA,PDC:0B,EDT:07E6080114000000012CC7
[ 91974][D][main.cpp:1282] loop(): [MAIN] 2022/ 8/ 1 20:00:00 76999
[ 91980][D][main.cpp:1286] loop(): [MAIN] coeff: 1
[ 91985][D][main.cpp:1289] loop(): [MAIN] unit: *0.01 kwh

1.瞬時電力取得
1192 Wと返事があった

[111991][D][main.cpp:1027] send_measurement_request(): [MAIN] request inst-epower
[111992][D][main.cpp:712] send_request(): [MAIN] SKSENDTO 1 0000:0000:0000:0000:0000:0000:0000:0000 0E1A 1 000E 
[112107][D][main.cpp:905] read_line_without_crln(): [RECEIVE] EVENT 21 0000:0000:0000:0000:0000:0000:0000:0000 00
[112107][D][main.cpp:905] read_line_without_crln(): [RECEIVE] OK
[112472][D][main.cpp:1132] loop(): [MAIN] ERXUDP "DATA":"1081000102880105FF017201E704000004A8","DATALEN":"0012","DEST":"0000:0000:0000:0000:0000:0000:0000:0000","LPORT":"0E1A","RPORT":"0E1A","SECURED":"1","SENDER":"0000:0000:0000:0000:0000:0000:0000:0000","SENDERLLA":"0000000000000000"
[112486][D][main.cpp:1173] loop(): [MAIN] EHD1:10,EHD2:81,TID:0001,SEOJ:028801,DEOJ:05FF01,ESV:72,OPC:01,EPC:E7,PDC:04,EDT:000004A8
[112498][D][main.cpp:1252] loop(): [MAIN] 1192 W

1.瞬時電流取得
R相9.0A, T相3.0Aと返事があった

[132551][D][main.cpp:1027] send_measurement_request(): [MAIN] request inst-current
[132552][D][main.cpp:712] send_request(): [MAIN] SKSENDTO 1 0000:0000:0000:0000:0000:0000:0000:0000 0E1A 1 000E 
[132712][D][main.cpp:905] read_line_without_crln(): [RECEIVE] EVENT 21 0000:0000:0000:0000:0000:0000:0000:0000 00
[132713][D][main.cpp:905] read_line_without_crln(): [RECEIVE] OK
[133077][D][main.cpp:1132] loop(): [MAIN] ERXUDP "DATA":"1081000102880105FF017201E80400620022","DATALEN":"0012","DEST":"0000:0000:0000:0000:0000:0000:0000:0000","LPORT":"0E1A","RPORT":"0E1A","SECURED":"1","SENDER":"0000:0000:0000:0000:0000:0000:0000:0000","SENDERLLA":"0000000000000000"
[133091][D][main.cpp:1173] loop(): [MAIN] EHD1:10,EHD2:81,TID:0001,SEOJ:028801,DEOJ:05FF01,ESV:72,OPC:01,EPC:E8,PDC:04,EDT:00620022
[133103][D][main.cpp:1266] loop(): [MAIN] R: 9.0 A, T: 3.0 A

あとは電力取得, 電流取得の繰り返し。

しばらくして 20時30分になったので送られて来た。
2022/8/1 20:30:00 77058つまり770.58kwhと配信されている。

[541757][D][main.cpp:1173] loop(): [MAIN] EHD1:10,EHD2:81,TID:0362,SEOJ:028801,DEOJ:05FF01,ESV:73,OPC:01,EPC:EA,PDC:0B,EDT:07E60801141E0000012D02
[541769][D][main.cpp:1282] loop(): [MAIN] 2022/ 8/ 1 20:30:00 77058
[541775][D][main.cpp:1286] loop(): [MAIN] coeff: 1
[541780][D][main.cpp:1289] loop(): [MAIN] unit: *0.01 kwh

BP35A1とかなかなか値段がはるのでファームウエアの書き込みに挫折しているともったいないところだった。
ネット上の情報でここまでたどり着けた。 お金が無駄にならなくてよかった。

参考