M5Stack系マイコンの多機種対応コーディングのコツ
複数機種のM5Sack系マイコンに対応するコードを書くコツをまとめます。
1. 背景と目的
M5Stack系マイコンは商品ラインナップが広く、次から次への新しい商品が販売されています。そのため、例えば、M5Atomを前提にコーディングを開始したとしても、途中でM5AtomS3に変更したいなど、マイコン変更したい場合や、複数種類のマイコンで同様の動きをさせたい場合などが出てきます。
マイコンボード毎にコードを分けるのは手間です。一つのコードで複数のマイコンボードに対応するコードを書くと便利です。
このようなコードを書くためには、M5Unifiedのライブラリを活用する方法と、ボード選択で定義されるマクロを活用する方法があります。最近はM5Unifiedを用いることが多いのですが、以前はマクロを利用していました。マクロを活用して書いたコードをベースに手を加えようとしたら、M5Stackボード用ソフトのアップデートに伴い、コンパイル時にエラーが出るようになってしまいました。。
本記事では、24/06/28時点で最新バージョンであるM5Stackボード用ソフトver2.1.1における、ボード選択で定義されるマクロを整理します。
2. ボード選択で定義されるマクロとは?
コンパイル時にボードを選択すると、このボード選択時に自動的にARDUINO_*マクロが定義されます。下記記事が参考になります。
3. M5Stack系マイコンのマクロ
これまで、下記サイトを参考に、ボード選択で定義されるマクロを利用していました。
2024/07/28確認時点において、上記記事に書かれたM5Stackボード用ソフトverは2.0.2です。一方、2024/07/28時点の最新のverは2.1.1です。このバージョン変更に伴い、マクロの文字列にいくつか変更があり、コンパイルエラーが出るようになってしまいました。
ver2.1.1のマクロを調べると下記の通りでした。
$ grep build.board ~/Library/Arduino15/packages/m5stack/hardware/esp32/2.1.1/boards.txt
m5stack_core.build.board=M5STACK_CORE
m5stack_fire.build.board=M5STACK_FIRE
m5stack_core2.build.board=M5STACK_CORE2
m5stack_tough.build.board=M5STACK_TOUGH
m5stack_station.build.board=M5STACK_STATION
m5stack_stickc.build.board=M5STACK_STICKC
m5stack_stickc_plus.build.board=M5STACK_STICKC_PLUS
m5stack_stickc_plus2.build.board=M5STACK_STICKC_PLUS2
m5stack_atom.build.board=M5STACK_ATOM
m5stack_atoms3.build.board=M5STACK_ATOMS3
m5stack_cores3.build.board=M5STACK_CORES3
m5stack_timer_cam.build.board=M5STACK_TIMER_CAM
m5stack_unit_cam.build.board=M5STACK_UNIT_CAM
m5stack_unit_cams3.build.board=M5STACK_UNIT_CAMS3
m5stack_poe_cam.build.board=M5STACK_POE_CAM
m5stack_paper.build.board=M5STACK_PAPER
m5stack_coreink.build.board=M5STACK_COREINK
m5stack_stamp_pico.build.board=M5STACK_STAMP_PICO
m5stack_stamp_c3.build.board=M5STACK_STAMP_C3
m5stack_stamp_s3.build.board=M5STACK_STAMP_S3
m5stack_capsule.build.board=M5STACK_CAPSULE
m5stack_cardputer.build.board=M5STACK_CARDPUTER
m5stack_dial.build.board=M5STACK_DIAL
m5stack_dinmeter.build.board=m5stack_dinmeter
上記から、ボード選択で定義されるマクロを一覧にすると下記の通りです。
• M5STACK_CORE
• M5STACK_FIRE
• M5STACK_CORE2
• M5STACK_TOUGH
• M5STACK_STATION
• M5STACK_STICKC
• M5STACK_STICKC_PLUS
• M5STACK_STICKC_PLUS2
• M5STACK_ATOM
• M5STACK_ATOMS3
• M5STACK_CORES3
• M5STACK_TIMER_CAM
• M5STACK_UNIT_CAM
• M5STACK_UNIT_CAMS3
• M5STACK_POE_CAM
• M5STACK_PAPER
• M5STACK_COREINK
• M5STACK_STAMP_PICO
• M5STACK_STAMP_C3
• M5STACK_STAMP_S3
• M5STACK_CAPSULE
• M5STACK_CARDPUTER
• M5STACK_DIAL
• m5stack_dinmeter
全体的に大文字になったり、M5Stack_Core_ESP32がM5STACK_COREに変わったりしています。例えば、ヘッダファイルの読み込み部分で、以下のようなコードを書くと、ボードに応じた場合分けをすることができます(24/08/16 修正)。
#if defined(ARDUINO_M5STACK_CORE) // M5Stackの場合
#include <M5Stack.h>
#elif defined(ARDUINO_M5STACK_FIRE) // Fireの場合
#include <M5Stack.h>
#elif defined(ARDUINO_M5STACK_CORE2) // Core2の場合
#include <M5Core2.h>
#elif defined(ARDUINO_M5STACK_TOUGH) // Toughの場合
#include <M5Tough.h>
#elif defined(ARDUINO_M5STACK_STICKC_PLUS) // M5StickC Plusの場合
#include <M5StickCPlus.h>
#elif defined(ARDUINO_M5STACK_ATOM) // ATOM Matrix/Liteの場合
#include <M5Atom.h>
#elif defined(ARDUINO_M5STACK_ATOMS3) // ATOMS3の場合
#include <M5AtomS3.h>
#endif
4. まとめと今後の課題
これまで参考にしていたサイトを基に、ボード選択で定義されるマクロを使用していましたが、その意味を正しく理解していませんでした。今回、ボードのアップデートに伴いコンパイルエラーになったため、自分自身で調べ、その意味を以前よりも深く理解することができました。
実務上も、このような場合分けを覚えておくと、マイコン変更に伴なうコーディング変更を最小限にできるため、大変に便利です。
参考
・この記事には助けられました。マクロによる場合分けを知らなかったらとしたら、ゾッとします。
・本記事では深堀りしていませんが、M5Unified.hについてはこちらが参考になります。