← カレンダーダイマー(公開ページ)

限定公開・noindex の開発記録 / 2026-10-10 / 担当: 組込み(Ws)

壁のスイッチプレートに入る「照明制御付き 24 時間カレンダータイマー」を作る
M5Stack 版を ESP32-S3 基板へ完全移植し、四季の色温度タイマーを足すまで

限定公開・noindex の開発記録。数値には〔仕様〕〔実測〕〔推定〕を付けている。


1. 何を作ったか

これまで M5Stack Core2 で動かしていた「カレンダーダイマー」(季節×時間帯で照明シーンを自動で切り替えるタイマー) を、壁のスイッチプレートに収まる自作基板 SW6LCD_RTC に移した。

昼 (秋 12〜18 時) の表示。右端の 2 本が色温度バー、その下が色見本
昼 (秋の昼時間帯) の表示。日付の右の 5500K が今の色温度。右端の 2 本のバーは DMX CH11・CH12 の値 (白い部分が値、上の暖色が残り。M5 版の DMX モニターと同じ描き方)、その下の 2 つの四角はバーと同じ配色 (値 0 = 暖色 〜 255 = 白) で今の値を示す色見本。

2. 移植の方針: 「書き直さない」

M5 版のファームは約 1 万 4 千行。DMX のシーン計算だけで 3,600 行ある。これを新しく書き直すと、現場で動いている M5 版と挙動がずれる。そこで M5 のコードをそのまま持ってきて、ハードに触る部分だけ差し替える 方針にした。

部分M5 版SW6 版
DMX シーンエンジン (Scene0〜20、1/f ゆらぎ・RGBW パターン・フェード)dmx_scene_controller.cppほぼ無改変。DMX を送り出す 2 か所だけ差し替え
季節タイマー・時刻表・保存 (EEPROM)schedule_manager.cpp無改変 (読み込むヘッダだけ変更)
Web 画面 (時刻表・シーンの編集)LittleFS の index.html + WebSocket同じ index.html をファームに埋め込み (書込みは 1 回で済む)
コマンド (RUN / SET / DMX / SCENE / PARAM …)BLE (WebBT) の中に組み込みBLE から切り離して、シリアル・WebSocket・HTTP 共通に
画面320×240 (左に時計とカレンダー、右に DMX モニター)240×240 に左パネルを同じ座標・フォント・色で配置、右端は色温度バー
操作タッチ + A/B/C ボタン押しボタン 6 個 (2 段 × 3 列。右の列 = 色温度/シーンの +/−、左下 = TIME ON/OFF、中下 = 時刻表どおりに戻す、中上長押し = 時刻表の編集、左上 = 時刻合わせ。LED は押したボタンだけ光る)

M5 の DMX 出力は esp_dmx ライブラリだったが、SW6 は同じ ESP32-S3 系の他の機種で実績のある「UART2 を直接たたく」方式にした。フレームの中身と送る間隔 (変化時 25ms・変化なし 100ms) は M5 のまま。


3. 新機能: 四季の色温度タイマー

M5 版でも DMX の CH11・CH12 は「色温度」のチャンネルで、時間帯ごとに値が決まっていた (朝 180 / 昼 255 / 夕 120 / 夜 10)。ただし 4 季節とも同じ値 だった。

SW6 版ではこれを 季節 × 時間帯の表 にして、Web から編集できるようにした。値は 0 = 2700K (電球色) 〜 255 = 6500K (昼光色)。初期値は、体内時計に合わせる一般的な考え方 (朝はやや白、昼は白、夕方は暖色、夜は電球色。夏は全体に白寄り、冬は暖色寄り) で次のようにした。

季節朝昼夕夜
春5000K6000K3500K2700K
夏5500K6500K4000K3000K
秋5000K5500K3500K2700K
冬4500K5000K3000K2700K
切替時間15 分10 分15 分15 分
夕方 (3500K) の表示
夕方の時間帯。色温度バーの白い部分が下がり、色見本も暖色寄りになる。
夜 (2700K) の表示
夜の時間帯 (冬)。バーはすべて暖色 (値 0 = 2700K)。季節名・時間帯名の色も M5 版と同じ。

Web の設定画面 (/ct)

スマホやパソコンのブラウザで本体の IP を開くと、M5 と同じ画面の右上に「色温度タイマー設定」が出る。設定画面では次のことができる。


4. 時刻の正確さ

M5 Core2 版SW6 版
RTCBM8563 + 水晶、温度補償なし (精度規定は未確認。一般的な水晶なら月 ±52 秒〔推定〕)DS3231MZ+、温度補償つき ±5ppm = 月 ±13 秒〔仕様〕
時刻合わせ起動時に NTP、その後 WiFi を切る。毎日 0:00:59 に再起動NTP を 1 時間ごと。設定でいつでも OFF にでき、OFF なら RTC だけで動く
実測NTP より約 1 秒遅れ (2026-10-10 に 1 回測定)〔実測〕NTP 同期直後の補正量 0 秒〔実測〕。長期のずれは測定中

参考: 同種の市販デジタルタイムスイッチ (オムロン 24 時間式) の月差は ±15 秒 (25℃)。SW6 は NTP なしでも同等以上、NTP ありなら常に 1 秒未満。

コードを読み比べて分かったこととして、M5 版の「毎日 0:00:59 の再起動」と「起動するたびに RTC を 1 秒進める補正」が組み合わさると、NTP がない環境では毎日 1 秒ずつ進む作りになっていた (月 +30 秒〔推定〕)。SW6 版ではこの 2 つを外した。再起動しないので、深夜に DMX が一瞬途切れることもなくなった。


5. 移植でつまずいたところ

  1. 時計の色が水色になった: 液晶ライブラリ (LovyanGFX) は、色の値を 32 ビットの変数で渡すと 24 ビット色として解釈する。16 ビット色の黄緑を 32 ビット変数に入れていたため水色になった。色は必ず 16 ビット型で持つ。
  2. Web 画面が空で返ってきた: 115KB の HTML を、ライブラリが文字列として丸ごとメモリにコピーしようとして失敗していた (応答は 200 なのに 0 バイト)。フラッシュから直接送る形に変えて解決。
  3. 時刻表の一部が 0 になった: M5 版は「編集画面を開いたときに 4 季節分を読み込む」作り。SW6 には編集画面がないため読み込みが抜け、閉じる操作で他の季節を 0 で保存してしまった。起動時と編集開始時に 4 季節を読むようにして解決し、値も元に戻した。
  4. 色温度の表示が 3510K になった: 0〜255 の 1 段は約 15K なので、10K 単位で表示すると設定値 (3500K) と合わない。50K 単位にして、設定した K と表示が一致するようにした。
  5. 起動後、NTP が数分同期しないことがあった: WiFi がつながる前に NTP を始めていたため、最初の問い合わせが失敗すると再試行まで待たされた。WiFi がつながった時点で開始し、60 秒同期しなければやり直すようにしたところ、接続から約 2 秒で同期するようになった。

どれも実機の写真・ログで見つけて直した。


6. これから

限定公開の開発記録です。公開ページ「カレンダーダイマー」からはリンクしていません。 使い方は、限定公開の 取扱説明書 にあります。