「ATOMIC TFカードリーダー」という製品を購入しました。
屋外にセンサとマイコンデバイスを設置して、定期的にデータを測定し、それをSDカードに保存していきたいという機会があったのですが、「M5Stack Basic」などのSDカードスロット内蔵製品は、屋外に設置して雑に扱うには高額です。また、外付けのSDカードスロットも色々なものが販売されていますが、それらを使おうと思うと、それをマイコンデバイスと接続するための手段を考えなければならず、そちらもなかなか面倒です。
「ATOMIC TFカードリーダー」であれば、ATOMのコネクタに差し込むだけで簡単に接続でき、ネジを使えばしっかり固定することもできます。なんといっても安価な「ATOM Lite」などと一緒に使えるのが大きなメリットです。
そんな訳で、喜び勇んで「ATOMIC TFカードリーダー」を購入し、早速試してみたのですが、なぜかArduino IDEのスケッチ例に掲載されているサンプルスケッチがコンパイルエラーになるという問題が発生してしまいました。
「ファイル」>「スケッチ例」>「M5Atom」>「ATOM_BASE」>「ATOM_TFCard」をコンパイルすると、以下のようなエラーが大量に発生します。
E (1359) gpio: gpio_set_level(227): GPIO output gpio_num error
E (1363) gpio: gpio_set_level(227): GPIO output gpio_num error
:
原因がなかなか分からず、「ATOMIC TFカードリーダー」は使い物にならないのか?とガッカリしていたのですが、いろいろ調べていくと、どうも「Arduino core for the ESP32」のバージョンアップに伴いエラーが発生するようになってしまったようです。
具体的には、「Arduino core for the ESP32」の「2.0.3」以降では、「SD.begin(-1, SPI, 10000000);」のように、存在しないGPIO番号として「-1」を指定することができなくなったようです。
「SD.begin();」では、引数としてCSピンを指定します。指定しなかった場合はデフォルトとして「GPIO5」がCSピンになるようです。
これに対して、「ATOMIC TFカードリーダー」はCSピンがグランドにつながっています。このような場合、従来は「SD.begin(-1);」と指定していたのですが、この指定方法がNGとなったようです。
エラーが発生してしまうようになった原因は分かりましたが、どのように対策したらよいのかは分かりません。
Google検索では見つからないのでChatGPTに質問したところ、「実在する未使用のGPIOを指定すればよい」との回答でした。あまりスマートな対策ではありませんが、やむを得ないのでこの方法を採用することにします。
以下のようなスケッチをつくりました。
1分毎に起動し、ふたつの乱数の値を取得します、それらをSDカード内の「log1.csv」ファイルに追記した後、deep sleepに移行します。
なお、deep sleep中も値を保持する変数「cnt」も準備し、起動した回数も「log1.csv」に書き込むようにしています。
「実在する未使用のGPIO(ダミーのCSピン)」としては、ATOM Liteから外部に取り出されており、なおかつTFカードリーダーでは使われていないピンが最も確実だろうと考え、「22」を使うことにしました。
#include <SD.h>
#include <M5Unified.h>
RTC_DATA_ATTR int cnt;
const int interval = 60;
void setup() {
auto cfg = M5.config();
cfg.serial_baudrate = 115200;
M5.begin(cfg);
// LEDを点灯
neopixelWrite(27, 255, 0, 0);
// データ取得
float val0 = random(100, 1000) * 0.1;
float val1 = random(100, 1000) * 0.1;
Serial.printf("cnt = %d, val0 = %.1f, val1 = %.1f\n", cnt, val0, val1);
// SDカードへのデータ保存
SPI.begin(23, 33, 19, 22);
unsigned long startTime = millis();
if(!SD.begin(22, SPI, 25000000)) {
if(millis() - startTime >= 1000) sleepDevice();
}
File file = SD.open("/log1.csv", FILE_APPEND);
if(file) file.printf("%d,%.2f,%.2f\r\n", cnt, val0, val1);
file.close();
cnt++;
sleepDevice();
}
void loop() {}
void sleepDevice() {
neopixelWrite(27, 0, 0, 0);
esp_sleep_enable_timer_wakeup(interval*1000000ULL);
esp_deep_sleep_start();
}
以下のように、問題なくSDカードにデータを書き込むことができました。
0,34.20,21.20
1,29.70,71.80
2,86.10,48.70
3,33.50,58.40
4,16.40,87.40
5,23.30,70.70
:
「ダミーのCSピンを指定する」という、少々ダサい対策ではありますが、今後はこの方法で「ATOMIC TFカードリーダー」を使っていきたいと思います。
なお、私がM5Stack、M5StickCの使い方を習得するのにあたっては、以下の書籍を参考にさせていただきました。
ごく基本的なところから、かなり複雑なスケッチや、ネットワーク接続など、比較的高度なものまで、つまづかずに読み進めていけるような構成になっており、大変わかりやすい本です。