組み込みをよく知らないコードメインの開発系エンジニアの記事です。
備忘録と製品の紹介用に書きました。
製品の紹介
ひとことで製品を説明すると、技適の通っているESP32にE-Paperのディスプレイとケースがセットになった製品です。
この製品がいいなと思ったところ
- 良い点
- 最初からケースに入っている
- WiFi,BLEの技適が通っている
- ディスプレイがe-paperで省エネ
- USB-Cでシリアル接続ができる
- 送料込みで3500円(アリペイ初回登録割引あり)
 
- 残念な点
- 電源以外から電力供給する時の難易度がそこそこ高い。後述。
 
成果物の紹介
こういう組み込み系はWindowsの方がツールが揃っていたりと強いのですが、
今回、 M1 Mac + VSCode + MictoPython で開発しました。
開発に必要なコード量
MicroPythonでの開発は初めてでしたが、200行も書けばWiFiのON/OFF、お天気API取得からディスプレイに表示と基本的な実装ができました。
GitHubのリポジトリ
動作イメージですが、こんな表示です。
備忘録用のメモ
フォントの作成
馴染みのあるTrueTypeフォント(TTFフォント)は使えません。変わりにというか、ビットマップフォントが使えます。
サイズや文字種は決めうちして作成します。
決め打ちと言ってもTTFフォントからワンライナーで抽出できますので難しくはありません。
小さいサイズであればアルファベットの26文字くらいはデータサイズ的にも余裕ですが、大きく表示したい時は文字種を厳選してデータサイズを小さくする必要があります。
フォントを作成するライブラリの紹介
MicroPythonでフォントを作成するには、peterhinch/micropython-font-to-pyで配布しているfont_to_py.pyを利用します。 ※ 他にも色々なやり方があります。
$ curl -LO https://raw.githubusercontent.com/peterhinch/micropython-font-to-py/c24761448e6ef1c40716b9b2b629e6fa37b2c9d2/font_to_py.py
fonts.googleからさわらびフォント(日本語)をダウンロード
今回の天気情報であれば文字種は0123456789.℃:%の14種類になります。
$ python font_to_py.py -c " 0123456789.℃:%" SawarabiGothic-Regular.ttf 32 SawarabiGothicRegularNumeric32.py 
例) 曜日を追加する例です。
$ python font_to_py.py -c " 0123456789.℃:%日月火水木金土日" SawarabiGothic-Regular.ttf 32 SawarabiGothicRegularNumeric32.py 
天気画像の作成
ディスプレイは白黒のみ対応してますのでモノクロのビットマップ画像を用意します。
今回はerikflowers/weather-iconsのSVGファイルを必要なファイルを取り出してリネームして利用しました。
実際にはこんな感じで用意しました。
モノクロ画像の変換には、ImageMagickのconvertコマンドでsvgをpngに変換した後、icons.py にアイコンファイルをまとめます。
1. ImageMagickのconvertコマンドでsvgをpngに変換
$ for i in `ls *.svg`; convert -size 128x128 $i $i.png
2. icons.py にアイコンファイルをまとめる処理
CrowPanel用のモノクロ画像の作成にはTimHanewich/MicroPython-SSD130のコードを利用しました。
下記からダウンロードします。
$ curl -LO https://raw.githubusercontent.com/TimHanewich/MicroPython-SSD1306/refs/heads/master/src/convert.py
下記の処理を実行します。
import convert
import os
import glob
flist = glob.glob("weather/*.png")
buffer_list = []
for fname in flist:
    name = os.path.basename(fname)
    name, _, _ = name.split(".")
    converted = convert.image_to_buffer(fname)
    buffer = converted[0]
    data = "'{}': {}".format(name, buffer)
    buffer_list.append(data)
with open("icons.py", "w") as f:
    f.write("weather_icons = {\n  " + ",\n  ".join(buffer_list) + "\n}")
Open-Meteo API
気温、降水量、天気、日の入りと、様々な情報が取得できます。
非商用であれば無料で利用できます。APIキーは必要ありません。
Open-Meteo APIとAPI実行結果のサンプル
APIの実行結果はJsonで返ります。
{"latitude":52.5,"longitude":13.5,"generationtime_ms":0.035762786865234375,"utc_offset_seconds":0,"timezone":"GMT","timezone_abbreviation":"GMT","elevation":38.0,"hourly_units":{"time":"iso8601","temperature_2m":"°C","is_day":"","weather_code":"wmo code","precipitation":"mm"},"hourly":{"time":["2025-07-23T00:00","2025-07-23T01:00","2025-07-23T02:00","2025-07-23T03:00","2025-07-23T04:00","2025-07-23T05:00","2025-07-23T06:00","2025-07-23T07:00","2025-07-23T08:00","2025-07-23T09:00","2025-07-23T10:00","2025-07-23T11:00","2025-07-23T12:00","2025-07-23T13:00","2025-07-23T14:00","2025-07-23T15:00","2025-07-23T16:00","2025-07-23T17:00","2025-07-23T18:00","2025-07-23T19:00","2025-07-23T20:00","2025-07-23T21:00","2025-07-23T22:00","2025-07-23T23:00","2025-07-24T00:00","2025-07-24T01:00","2025-07-24T02:00","2025-07-24T03:00","2025-07-24T04:00","2025-07-24T05:00","2025-07-24T06:00","2025-07-24T07:00","2025-07-24T08:00","2025-07-24T09:00","2025-07-24T10:00","2025-07-24T11:00","2025-07-24T12:00","2025-07-24T13:00","2025-07-24T14:00","2025-07-24T15:00","2025-07-24T16:00","2025-07-24T17:00","2025-07-24T18:00","2025-07-24T19:00","2025-07-24T20:00","2025-07-24T21:00","2025-07-24T22:00","2025-07-24T23:00","2025-07-25T00:00","2025-07-25T01:00","2025-07-25T02:00","2025-07-25T03:00","2025-07-25T04:00","2025-07-25T05:00","2025-07-25T06:00","2025-07-25T07:00","2025-07-25T08:00","2025-07-25T09:00","2025-07-25T10:00","2025-07-25T11:00","2025-07-25T12:00","2025-07-25T13:00","2025-07-25T14:00","2025-07-25T15:00","2025-07-25T16:00","2025-07-25T17:00","2025-07-25T18:00","2025-07-25T19:00","2025-07-25T20:00","2025-07-25T21:00","2025-07-25T22:00","2025-07-25T23:00"],"temperature_2m":[17.6,17.6,17.8,18.0,18.2,18.4,18.4,18.3,18.0,17.8,17.5,17.2,17.0,17.0,17.1,17.2,17.3,17.5,17.5,17.6,17.8,17.9,18.0,18.0,18.0,18.0,17.9,17.6,17.5,17.5,17.8,18.4,19.2,20.2,21.2,22.1,22.6,22.9,23.0,23.0,22.8,22.5,22.2,21.8,21.2,20.6,20.0,19.4,19.0,18.8,18.5,18.4,18.4,18.5,18.9,19.5,20.4,21.4,22.4,23.2,23.8,24.0,23.9,23.7,23.4,23.0,22.6,22.2,21.7,21.1,20.6,20.1],"is_day":[0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0],"weather_code":[51,51,51,51,51,51,51,53,53,53,53,53,53,61,61,61,61,61,61,51,51,51,51,51,51,2,2,2,3,3,3,3,3,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1],"precipitation":[0.40,0.20,0.20,0.20,0.20,0.20,0.20,0.80,0.80,0.80,0.80,0.80,0.80,1.30,1.30,1.30,1.30,1.30,1.30,0.10,0.10,0.10,0.10,0.10,0.10,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,-0.00,-0.00,-0.00,-0.00,-0.00,-0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00]}}
今回利用したAPIのパラメータ
| Parameter | 説明 | 
|---|---|
| latitude, longitude | WGS84地理座標 | 
| timezone | タイムゾーンデータベースの任意のタイムゾーン名がサポートされます。タイムゾーンとしてautoが設定されている場合、座標は自動的にローカルタイムゾーンに解決されます。 | 
| forecast_days | デフォルトでは7日間の予測が返されます。最大11日間の予測が可能です。 | 
今回利用した時間ごとのパラメータ
| 変数 | 単位 | 説明 | 
|---|---|---|
| temperature_2m | °C (°F) | 地上2メートルの気温 | 
| weather_code | WMO code | 気象状況を数値コードで表します。WMOの気象解釈コードに従ってください。詳細は下の表を参照 | 
| precipitation_probability | % | 過去1時間に0.1mm以上の降水量が発生する確率 | 
| is_day | 0,1 | 現在のタイムステップ 1=昼間, 0=夜間 | 
WMO 気象解釈コード (WW)
WMOのコードにあわせて天気の画像を出力しています。
| Code | 説明 | 
|---|---|
| 0 | Clear sky | 
| 1, 2, 3 | Mainly clear, partly cloudy, and overcast | 
| 45, 48 | Fog and depositing rime fog | 
| 51, 53, 55 | Drizzle: Light, moderate, and dense intensity | 
| 56, 57 | Freezing Drizzle: Light and dense intensity | 
| 61, 63, 65 | Rain: Slight, moderate and heavy intensity | 
| 66, 67 | Freezing Rain: Light and heavy intensity | 
| 71, 73, 75 | Snow fall: Slight, moderate, and heavy intensity | 
| 77 | Snow grains | 
| 80, 81, 82 | Rain showers: Slight, moderate, and violent | 
| 85, 86 | Snow showers slight and heavy | 
| 95 * | Thunderstorm: Slight or moderate | 
| 96, 99 * | Thunderstorm with slight and heavy hail | 
消費電力の下げ方
CPUのクロック周波数を変更することで消費電力を少なく保つことができます。
20,40,60,80,160,240MHzで設定が可能です。
import machine
machine.freq(240000000) # 240MHzで設定
print(machine.freq()) # 現在の設定を確認
WiFiも使わない時はON/OFFを切り替えることで少ない消費電力で利用できます。
※ 電力チェッカーを持っていないので詳細なデータはありません;;
電源以外から電力供給する時の難易度がそこそこ高い
CrowPanel 5.75は外部電源用のコネクタ(JST-SH 1mm 2pin)を持っていますが、日本では既製品があまり出回っていないらしく入手が面倒そうです。
GPIOやUSB-Cから電源供給する手も無くはないのですが、あまりスマートではないのが悩ましいですね。
おわりに
製品の紹介と、開発に必要とした情報をまとめました。
興味がある方はお試しください。アリペイでは注文してから10日かからず届きました。
なんとなくクレカ登録は怖いので、購入時はPayPalを利用しました。



