概要
M5Stack(BASIC, GRAY, FIRE)、M5Stack Core2、M5StickC、M5StickC Plus、ATOM(LITE, MATRIX)で共通コードのSDカードの使い方を調べてみました。
SDカードの対応状況
| 機種 | SDカードスロット |
| M5Stack BASIC | 内蔵 |
| M5Stack GRAY | 内蔵 |
| M5Stack FIRE | 内蔵 |
| M5Stack Core2 | 内蔵 |
| M5StickC | 外付け可能 |
| M5StickC Plus | 外付け可能 |
| ATOM LITE | 外付け可能、ATOMIC TFカードキット |
| ATOM MATRIX | 外付け可能 |
| ATOM ECHO | 利用不可 |
上記の状況になっています。M5Stack系は内蔵しているのでそのまま利用可能です。M5StickC系はHAT側端子を利用して外付け可能です。ATOMはちょっと複雑でECHOは、SDで使うピンをスピーカーとマイクで利用しているので拡張できません。
外付け方法
上記のようなSDカードモジュールを利用します。たまにカードスロットのみで、必要な抵抗などが一切ないものがあるので、抵抗などの部品が実装されているものを選ぶ必要があります。

上記がM5StickCに接続した場合です。がんばればプロトHATに内蔵できる気もします。

ATOM LITEに接続した場合です。
- ATOMIC TFカードキット(スイッチサイエンス)
ATOMに関しては、上記のATOMICを利用することによって、かんたんにSDを使うことが可能です。ただ、ATOM LITEが同梱されている関係でちょっとお高い、、、
接続方法
| SD | M5StickC | M5StickC Plus | ATOM LITE | ATOM MATRIX |
| 3V3 | 3V3 | 3V3 | 3V3 | 3V3 |
| GND | GND | GND | GND | GND |
| CLK | GPIO0 | GPIO0 | GPIO23 | GPIO23 |
| MISO | GPIO36 | GPIO36 | GPIO33 | GPIO33 |
| MOSI | GPIO26 | GPIO26 | GPIO19 | GPIO19 |
| CS | GND | GND | GND | GND |
上記の接続になります。ATOM ECHOにはけして繋げないでください。スピーカーとマイクに上記のGPIOを利用しているため、他の用途に利用すると本体が壊れる可能性があります。
また、CSがGNDになっているので、常にSDが有効な状態になります。複数のSPI接続をする場合には別GPIOに接続する必要がありますが、空きGPIO的に複数接続することは少ないと思います。
外付けSDの利用方法
ESP32は内蔵フラッシュなどでSPIを利用していますが、ユーザーが利用できるSPIは2系統までの制限があります。通常1系統目はLCDで利用されています。M5Stackなどは1系統目のSPIにLCDとSDの両方が接続されています。M5StickCの場合には1系統目のSPIにLCDが接続されており、外部からは利用できないので、SDは2系統目に接続する必要があります。ATOMはLCDがないので2系統どちらでも利用できますが、M5StickCと同じ2系統目を使うことにします。
スケッチ例
#include "M5Lite.h"
SPIClass SPI_EXT;
void setup() {
M5Lite.begin();
if (M5.Ex.board == lgfx::board_M5Stack) {
// AutoStart
} else if (M5.Ex.board == lgfx::board_M5StackCore2) {
// AutoStart
} else if (M5.Ex.board == lgfx::board_M5StickC) {
// SD M5StickC
// 3V3 3V3
// GND GND
// CLK GPIO0
// MISO GPIO36
// MOSI GPIO26
// CS GND
SPI_EXT.begin(0, 36, 26, -1);
SD.begin(-1, SPI_EXT);
} else if (M5.Ex.board == lgfx::board_M5StickCPlus) {
// SD M5StickC
// 3V3 3V3
// GND GND
// CLK GPIO0
// MISO GPIO36
// MOSI GPIO26
// CS GND
SPI_EXT.begin(0, 36, 26, -1);
SD.begin(-1, SPI_EXT);
} else if (M5.Ex.board == lgfx::board_unknown) {
// SD ATOM(Lite, Matrix) Doesn't work with Echo!
// 3V3 3V3
// GND GND
// CLK GPIO23
// MISO GPIO33
// MOSI GPIO19
// CS GND
SPI_EXT.begin(23, 33, 19, -1);
SD.begin(-1, SPI_EXT);
}
}
void loop() {
M5Lite.Lcd.setCursor(0, 0, 1);
M5Lite.Lcd.println("M5LiteSD");
M5Lite.Lcd.println(millis());
// delay & M5Lile.update()
M5Lite.Ex.delay(100);
}
SDを内蔵しているボードに関しては、明示的に利用開始を宣言しなくてもM5Liteにて初期化されているので、そのまま利用できます。M5StickCやATOMの場合には外付けをする必要がありますので、接続しているGPIOを指定して初期化が必要になります。
初期化後は共通のSDクラス経由でアクセスが可能になります。
SPIClass SPI_EXT;
上記で2系統目のSPIを定義しています。1系統目はSPIで定義されており、他の名前で宣言をすると2系統目になります。SPI2という名前で定義している事例が多いですが、spi_struct.hですでにSPI2は定義されていますので、他の名前にしたほうが好ましいと思います。
extern spi_dev_t SPI0; /* SPI0 IS FOR INTERNAL USE*/ extern spi_dev_t SPI1; extern spi_dev_t SPI2; extern spi_dev_t SPI3;
動作確認

上記はM5StickCの例ですが、シリアルモニタから「SD」を送信するとSDカードの情報が表示されます。

「SD DIR /D」などDIRコマンドでファイル一覧が表示されます。現状はDIRコマンドしかありませんが、そのうちWi-Fi経由でファイルダウンロードする機能などを追加したいと思っています。
利用可能なSDカード
16GBまでのマイクロSDカードが推奨されています。

上記がM5Stackに32GBのマイクロSDを入れてみた出力です。カードの容量が1.5GBぐらいに見えていますね。内部的にはファイル容量をuint32_tで表現しているので、そもそも上限が4GBまでしか正しく扱えません!
一応32GBでも認識をして、ファイル一覧を表示することができました。でも空き容量とかを考えると4GBを使ったほうが安心なのかな?
まとめ
初期化まで終わればあとはSDクラスで共通化できるので、便利ですね。とはいえ、個人的にはSDカードはほとんど使ったことないです。。。Wi-Fi経由の方が楽なんですよね。
4GBのマイクロSDは最近あまり売っていないので、少し入手しておこうかな。

















コメント
こんにちはご無沙汰しております
素敵なライブラリをいつもありがとうございます
お仕事の案件で 32GByte SDHCを扱う事があり
こちらの記事が気になりましたのでご報告です
仰るように uint32_t では足りないらしく uint64_t に変更すればOKなようです
また SDカードは マイクロSDカード(≦2G)、マイクロSDHCカード(≦32G)までは対応されているようです
次回のバージョンアップにでも組み込んで下さると幸いです
よろしくお願い致します
* 1163行は (uint32t) でキャストしないと吐きそうになります
変更前
===============================================================
SD
===============================================================
Card Type : SDHC
Card Size : 872.00 MB
Total Bytes : 860.00 MB
Used Bytes : 13.53 MB
変更後
===============================================================
SD
===============================================================
Card Type : SDHC
Card Size : 28.85 GB
Total Bytes : 28.84 GB
Used Bytes : 13.53 MB
M5LiteDebug.h ===
1151:String fileSizeString(uint32_t val) { => String fileSizeString(uint64_t val)
1163:return String(val) + String(” B”); => return String((uint32_t)val) + String(” B”);
1233:uint32_t cardSize = SD.cardSize(); => uint64_t cardSize = SD.cardSize();
1234:uint32_t totalBytes = SD.totalBytes(); => uint64_t totalBytes = SD.totalBytes();
1235:uint32_t usedBytes = SD.usedBytes(); => uint64_t usedBytes = SD.usedBytes();
M5Lite.h ===
369:uint32_t totalBytes = SPIFFS.totalBytes(); => uint64_t totalBytes = SPIFFS.totalBytes();
370:uint32_t usedBytes = SPIFFS.usedBytes(); => uint64_t usedBytes = SPIFFS.usedBytes();
SPIFFS.totalBytes()の戻り値をみたらsize_tで取り扱うのが正しそうですね!
そんな大きいんですかぁ(///)
こんばんわ
“M5シリーズ全機種でWifiをSTAかAP接続しWebDAVを実装してSDカードをPCのネットワークドライブに割り付ける話”
書きました- ご査収くださいませ
よろしくお願い申し上げます
ありがとうございます!
WebDAV便利そうですね
M5Unifiedというライブラリが公式から公開されましたので、M5Liteより今後はM5Unifiedを使ったほうがいいかもしれません
ただし、現在あまり情報がありません
お疲れさまです
M5Unified ですかぁ
全然しりませんでした
情報ありがとうございます
さらにこれ更新しましたぁ
https://qiita.com/chrmlinux/items/d2e49cb9ac339664a3b1
是非 ご賞味くださいませ