概要
M5Stackから画面付きのATOMが販売されましたので、確かめてみました。LED RGBを16個搭載したATOM Matrixと同じ価格ながら画面があるのはやっぱり便利です。(ドルベースでは同じ価格ですが、日本ではATOMS3のほうが安いです!)
製品
- ATOMS3(スイッチサイエンス)
- ATOMS3 Dev Kit w/ 0.85-inch Screen(公式ストア)
上記から購入できます。おそらく日本向けは戦略価格なのでいまは日本から購入したほうが早いし、安いと思います。販売直後は品薄ですが、レギュラー商品なのでもう少ししたら在庫も潤沢になると思います。
こんな感じで届きました。パッケージは簡略化されていますが、かなりがんばって価格を下げるためだと思われます。
こんな感じで前面がLEDになっています。
裏側は従来どおりですね。
ライブラリについて
公式ライブラリは準備されていますが、現状でいまいちでした。。。
公式ライブラリ
発売当初のライブラリは未完成な状態でした。ライブラリマネージャにも登録されておりませんし、Arduino IDEでもエラーがでて使うことができません。
今後調整されることを期待します。ただグラフィックライブラリがIn_eSPIをつかっていて、M5GFX(LovyanGFX)ではありません。積極的に使う必要は無い気がします。
M5Unified
M5Stack製品共通で使えるM5UnifiedでもATOMS3に対応しています。ATOMS3では画面とボタン、IMUに対応しています。IRには対応していませんが、公式ライブラリも同じなのでM5Unifiedの利用をおすすめします。
こちらのライブラリはライブラリマネージャから追加可能です。
開発環境
Arduino IDE
Arduino IDEは2系をおすすめします。この記事を書いているときの最新は2.0.3でした。アイコンが四角い方が2系になります。
ESP32ボードマネージャー
M5StackのボードマネージャーではATOMS3がまだ追加されていませんでした。M5Stack版ではなくESP32の公式ボードマネージャーを使ったほうがいいと思います。今後M5Stack版にも追加されると思いますのでATOMS3がボードの選択肢になかったESP32公式を使っていください。
また、最近でたESP32 2.0.6を使うことでデバッグが可能となります。
Arduino IDEの設定
ボード設定は「ESP32S3 Dev Module」を選択します。
細かい設定がいろいろありますが、気をつけないといけないのはUSB系の設定です。
項目 | 設定値 | 備考 |
---|---|---|
USB CDC On Boot | Enable | USB SerialをSerialクラスとして使う |
CPU Frequency | 240MHz | |
Core Debug Level | なし | |
USB DFU On Boot | Disabled | |
Erase All Flash Before Sketch Upload | Disabled | |
Events Run On | Core 1 | |
Flash Mode | QIO 80MHz | |
Flash Size | 4MB | |
JTAG Adapter | Integrated USB JTAG | |
Arduino Runs On | Core 1 | |
USB Fireware MSC On Boot | Disabled | |
Partition Scheme | Default 4MB with spiffs | |
PSRAM | Disabled | |
Update Mode | USB-OTG CDC | |
Update Speed | 921600 | |
USB Mode | Hardware CDC and JTAG | Hardware CDC and JTAGを選択 |
※USBまわりの設定によりシリアル出力の方法が変わります。別の記事にてまとめる予定です。
また、ボードの設定を変更するとUSB接続でシリアルが利用できないモードになる可能性があります。その場合にはATOMS3の左側にあるリセットボタンを2秒以上押すことで緑のLEDが光って強制書き込みモードにすることが可能です。
サンプルスケッチ
M5Unifiedの「HowToUse」をまずは動かすのがよいと思います。画面とボタン、IMUの使い方がわかります。
#include <M5Unified.h>
void setup(void) {
auto cfg = M5.config();
M5.begin(cfg);
M5.Display.setTextSize(1);
const char* name;
switch (M5.getBoard()) {
case m5::board_t::board_M5AtomS3:
name = "ATOM S3";
break;
default:
name = "Who am I ?";
break;
}
M5.Display.startWrite();
M5.Display.print("Core:");
M5.Display.println(name);
Serial.printf("core:%s\n", name);
switch (M5.Imu.getType()) {
case m5::imu_t::imu_mpu6886:
name = "MPU6886";
break;
default:
name = "none";
break;
}
M5.Display.print("IMU:");
M5.Display.println(name);
M5.Display.endWrite();
Serial.printf("imu:%s\n", name);
}
void loop(void) {
delay(1);
int h = M5.Display.height() / 8;
M5.update();
static constexpr const int colors[] = { TFT_WHITE, TFT_CYAN, TFT_RED, TFT_YELLOW, TFT_BLUE, TFT_GREEN };
static constexpr const char* const names[] = { "none", "wasHold", "wasClicked", "wasPressed", "wasReleased", "wasDeciedCount" };
M5.Display.startWrite();
auto state = M5.BtnA.wasHold() ? 1
: M5.BtnA.wasClicked() ? 2
: M5.BtnA.wasPressed() ? 3
: M5.BtnA.wasReleased() ? 4
: M5.BtnA.wasDeciedClickCount() ? 5
: 0;
if (state) {
Serial.printf("BtnA:%s count:%d\n", names[state], M5.BtnA.getClickCount());
if (!M5.Display.displayBusy()) {
M5.Display.fillRect(0, h * 3, h, h - 1, colors[state]);
M5.Display.setCursor(0, h * 3);
M5.Display.printf("%d", M5.BtnA.getClickCount());
}
}
M5.Display.endWrite();
if (M5.Imu.isEnabled()) {
int ox = (M5.Display.width() + h) >> 1;
static int prev_xpos[6];
int xpos[6];
float val[6];
M5.Imu.getAccel(&val[0], &val[1], &val[2]);
M5.Imu.getGyro(&val[3], &val[4], &val[5]);
int color[6] = { TFT_RED, TFT_GREEN, TFT_BLUE, TFT_RED, TFT_GREEN, TFT_BLUE };
for (int i = 0; i < 3; ++i) {
xpos[i] = val[i] * 50;
xpos[i + 3] = val[i + 3] / 2;
}
M5.Display.startWrite();
M5.Display.setClipRect(h, h, M5.Display.width(), M5.Display.height());
M5.Display.waitDisplay();
for (int i = 0; i < 6; ++i) {
if (xpos[i] == prev_xpos[i]) continue;
int px = prev_xpos[i];
if ((xpos[i] < 0) != (px < 0)) {
if (px) {
M5.Display.fillRect(ox, h * (i + 2), px, h, M5.Display.getBaseColor());
}
px = 0;
}
if (xpos[i] != px) {
if ((xpos[i] > px) != (xpos[i] < 0)) {
M5.Display.setColor(color[i]);
} else {
M5.Display.setColor(M5.Display.getBaseColor());
}
M5.Display.fillRect(xpos[i] + ox, h * (i + 2), px - xpos[i], h);
}
prev_xpos[i] = xpos[i];
}
M5.Display.clearClipRect();
M5.Display.endWrite();
}
M5.Display.display();
}
上記が「HowToUse」でATOMS3に関連する場所のみ抜き出したもの+ちょっとした修正になります。IMUのグラフを描いている部分がちょっと複雑ですが、シンプルに利用することができます。
Serialだけはちょっと注意が必要で、Serialクラスは「USB CDC On Boot」をEnableにしないとUSBではなくてESP32標準のUARTになります。そしてATOMS3にはUARTのポートがありません。つまりUSB側シリアルを使いたい場合には「USB CDC On Boot」をEnableにしてSerialクラスをUSB側にするか、デフォルトのままの設定の場合にはSerialクラスのかわりに、USBSerialクラスを利用する必要があります。
※USBまわりの設定によりシリアル出力の方法が変わります。別の記事にてまとめる予定です。
JTAGでのデバッグ
ESP32-S3の特徴として、USBシリアルとJTAGを内蔵していることです。チップ自体も無印ESP32よりも一つ新しいシリーズが搭載されています。
そのためArduino IDEの2系とEPS32ボードマネージャーの2.0.6以降を組み合わせることで、ブレイクボイントを利用したデバッグがすぐに使えるようになります。これは便利ですね。いままでは別にJTAGボードを用意して、PlatformIOを使ったりと気軽に使うことができませんでした。
デバッグできない場合
上記の記事を参考にしてください。
まとめ
もう少し確認が必要ですが、ファーストインプレッションとしてここまでにしたいと思います。とりあえず最新のArduino IDEとESP32ボードマネージャーを使って、M5Unifiedライブラリで触るのがおすすめです!
コメント
ありがとうございます。いつも参考にさせていただいています!
私もM5Stack ATOMS3を購入したのを機に「公式ライブラリ:M5AtomS3.h→M5Unified」へ移行しようと考えいますが、M5Canvasと組合せると上手く動作しないので、質問させて下さい。
◆質問
「M5Unified+M5Canvas」で、ATOMS3でボタンを押した時にスプライトを利用して画面に図形を表示することは可能でしょうか?
◆詳細
参考例を「M5Unified+M5Canvas」で画面表示できたのですが、これに”M5.begin(cfg)を指定”すると、ATOMS3に何も表示されなくなりました。M5.begin(cfg)をコメントにすると表示されます。これは、「M5Unified+M5Canvas」ではプログラムを記載できないということでしょうか?
◆テスト例:M5Canvas – 1.簡単な利用サンプル
https://docs.m5stack.com/ja/api/m5gfx/m5gfx_canvas
==ここから==
//#include // M5Unifiedに変更のためコメント
//#include // M5Unifiedに変更のためコメント
#include // M5Unifiedを追加
M5GFX display;
M5Canvas canvas(&display);
int32_t x;
int32_t y;
void setup()
{
auto cfg = M5.config(); // M5.begin設定を追加すると画面が表示されない
M5.begin(cfg) // M5.begin設定
display.begin();
-以下参考例と同じため省略-
==ここまで==
M5Unifiedを使う場合にはM5.Lcdがdisplayになります。
またM5.begin(cfg);で初期化されているのでM5.Lcd.begin()は呼び出す必要がありません。
#include
M5Canvas sprite(&M5.Lcd);
void setup() {
auto cfg = M5.config();
M5.begin(cfg);
M5.Lcd.println(“Test”);
sprite.createSprite(32, 32);
みたいな感じになると思います。
ちなみにM5.LcdでもM5.Displayでも中身は同じなので好きな方を使ってください。
回答ありがとうございます、動作しました!
M5.Lcdを使うことで、LGFXを使っていた時よりシンプルになりました。
教えていただいた「M5Unified」「M5Canvas 」を使ってAtomS3サーマルカメラを作成しましたので、シェアいたします。ありがとうございました!
・【IoT】”AtomS3”でM5StickC Thermal Camera Hat(MLX90640)を動かす
https://zenn.dev/aoya_uta/articles/1682c3677eafca