M5CoreS3 SEを使って、自宅用の「お天気Kiosk」を作ってみました。きっかけはシンプルで、毎朝スマホを開かずに天気を一目で確認したいと思ったことと、せっかく持っているM5デバイスを"ちゃんと日常で使うもの"にしたかったからです。
この記事では、設計の考え方・実装コードのポイント・詰まった箇所の解決策まで、実際に作ってみてわかったことをまとめます。M5CoreS3 SEやM5Stack系デバイスで似たようなものを作りたい方の参考になれば幸いです。

M5CoreS3 SEとボトムバッテリーの組み合わせを選んだ理由
今回ベースに選んだのはM5CoreS3 SE。M5Stackシリーズの中でも比較的コンパクトで、240×320のフルカラーLCDを搭載しており、情報表示デバイスとして非常に使いやすいスペックを持っています。
そこに組み合わせたのが、以前使っていたM5Core GO用のボトムバッテリーです。このボトムバッテリーには充電池のほかにNeoPixel互換のLEDが搭載されており、単なる電源としてだけでなく「視覚的な情報表示デバイス」としても活用できます。
スペック概要
- M5CoreS3 SE: ESP32-S3搭載、2.0インチIPSタッチスクリーン(240×320px)、Wi-Fi対応、MicroPython / UIFlow2対応
- M5Core GOボトムバッテリー: 700mAh内蔵バッテリー、NeoPixel LEDバー搭載、M5Stack標準バスで接続
- 天気データ取得API: OpenWeatherMap API(無料プランで十分)
M5CoreS3 SEを選んだ最大の理由は「UIFlowとMicroPythonの両方が使えること」と「Wi-Fiが内蔵されていること」です。外部モジュール不要でAPIにアクセスできるため、配線がすっきりします。
お天気Kioskの設計思想:「ながら見」に最適化したUI
このKioskのポイントは、「視認性の高さ」と「ながら見で情報が入ること」です。朝の支度中や作業の合間に画面をチラッと見るだけで必要な情報が入ってくることを目標に設計しました。
表示する情報を絞り込む
画面に表示する情報として最初に検討したのは以下の項目です。
- 現在の天気(アイコン表示)
- 最高気温・最低気温
- 風速
- UV指数
- 湿度
- 降水確率
- 週間天気予報
しかし実際にプロトタイプを作って使ってみると、情報が多すぎると「パッと見てわかる」感が損なわれることがわかりました。最終的には天気アイコン・最高最低気温・風速・UV指数の4項目に絞り、それぞれのフォントサイズを最大化することで、2〜3メートル離れた位置からでも読み取れるデザインにしています。
LEDカラーを天気連動にして「環境表示」として機能させる
ボトムバッテリーのLEDバーを天気状態に応じて色変化させるのが、このKioskの個人的なお気に入りポイントです。
- 晴れ: 明るい黄色〜オレンジ
- 曇り: 薄いグレー〜白
- 雨: 青〜青紫
- 雪: 白〜水色の点滅
これにより、画面を直接見なくても視界の端でなんとなく天気がわかるようになりました。デスクに置いておくだけで情報が入ってくる「環境表示デバイス」として機能しています。
実装コードのポイントと詰まりポイントまとめ
実装自体はそこまで複雑ではありませんが、実際に作ってみると意外な落とし穴がいくつかありました。同じように作ろうとしている人が詰まりやすいポイントをまとめておきます。
天気データの取得と更新タイミング
天気データはOpenWeatherMap APIからJSONで取得しています。無料プランは60回/分のリクエスト制限があるため、更新間隔は15〜30分に設定するのが無難です。MicroPythonでの実装例(概略)は以下の通りです。
import urequests
import ujson
API_KEY = "your_api_key"
CITY_ID = "1857910" # 例:名古屋のCity ID
URL = f"http://api.openweathermap.org/data/2.5/weather?id={CITY_ID}&appid={API_KEY}&units=metric&lang=ja"
def fetch_weather():
try:
res = urequests.get(URL)
data = ujson.loads(res.text)
temp_max = data["main"]["temp_max"]
temp_min = data["main"]["temp_min"]
weather_id = data["weather"][0]["id"]
wind_speed = data["wind"]["speed"]
return temp_max, temp_min, weather_id, wind_speed
except Exception as e:
print(f"Error: {e}")
return None
詰まりポイント①:SSL証明書エラー
MicroPythonでHTTPSのAPIにアクセスすると、SSL証明書の検証でエラーが出ることがあります。開発段階では ssl=False で回避できますが、本番環境ではHTTPエンドポイントを使うか、証明書バンドルを設定する必要があります。OpenWeatherMap APIはHTTPでも利用可能なので、開発段階はHTTPを使うのが手軽です。
詰まりポイント②:NeoPixel LEDの輝度管理
ボトムバッテリーのLEDを点灯させ続けると、夜間に眩しくて邪魔になります。時刻に応じて輝度を変える(昼間は100%、夜間は10%)か、設定時間帯はLEDを消灯するロジックを追加するとよいでしょう。RTC(リアルタイムクロック)モジュールがない場合は、Wi-Fi接続後にNTPサーバーから時刻を取得する方法が使えます。
詰まりポイント③:メモリ不足でクラッシュ
MicroPythonはRAMが限られています(ESP32-S3でも約320KB程度)。画像アイコンをビットマップで持とうとすると一瞬でメモリが枯渇します。アイコンはできるだけシンプルな図形(円・多角形)をコードで描画するか、小さいサイズ(32x32px以下)のJPEG/PNGにするのが現実的です。
ペットの水交換アラート機能の追加:実用性を一歩踏み込む
このKioskには、天気表示だけでなくペットの水交換アラート機能も実装しています。これが意外と便利で、毎日の生活サイクルに自然に組み込まれました。
仕組みはシンプルで、「最後に水交換した日」をEEPROM(不揮発性メモリ)に保存しておき、4日経過したらポップアップと短いブザー音で通知する、というものです。日々のルーティンって、忙しいと抜けがちになるので、こういう「軽い強制力」があると安心できます。
この機能を作って気づいたこと
単なるガジェット遊びで終わらず、生活の質を少し上げてくれるのがこういう仕組みのいいところだと改めて実感しました。「こんな小さな機能を追加するだけで、毎日ちょっと快適になる」という体験は、IoT工作の醍醐味の一つです。
同様の発想で、以下のような機能も追加できます。
- 観葉植物への水やりリマインダー(3日毎など)
- 薬の飲み忘れ防止アラート(毎朝8時など)
- ゴミ出し曜日の前夜通知
- 冷蔵庫内食材の賞味期限管理(手入力式)
使い続けてわかったこと・今後の拡張アイデア
完成してからは、デスクの上に常設しています。スマホを見る回数が少し減ったのと、朝の動きがスムーズになったのが一番の変化です。LEDの色が変わるだけでちょっと楽しいのもポイントで、こういう「ちょっとした満足感」って、日常に効いてきます。
使い続けてわかった改善点
- UV指数は曇りの日にほとんど見ないため、代わりに「体感温度」を表示したほうが実用的だった
- 定期的なWi-Fi再接続処理を入れないと、長時間稼働で切断されたまま古いデータが表示され続ける
- 電力消費を抑えるためにDeepSleepを活用すると、バッテリー持ちが大幅に改善した
今後の拡張アイデア
M5シリーズは拡張性が高いため、今後は以下のような発展形も面白そうです。
- 室内環境センサー(温湿度・CO2)と連動して「換気アラート」を追加
- 家族のカレンダーAPIと接続してスケジュール表示
- 車のメンテナンスリマインダー(オイル交換・タイヤ空気圧チェック)
- 帰宅時間を通知するLINE Messaging APIとの連携
ガジェットを触る時間も楽しいですが、こうやって実際に役立つ形に落とし込めると満足度が一気に上がります。同じようにM5デバイスを持っている方は、ぜひ「自分専用のKiosk」を作ってみてください。工夫次第でいくらでも育てられるのが手作りガジェットの醍醐味です。
#M5Stack #M5CoreS3SE #IoT #電子工作 #MicroPython #お天気Kiosk #ESP32 #自作ガジェット