ESP32でセンサの測定データを保存したい、ログを記録したいと思ったことはありませんか?
ESP32には内蔵フラッシュメモリがありますが、大量のデータを継続的に保存したい場合にはSDカードが便利です。
SDカードを使用すれば、ESP32で取得した温度や湿度などのセンサデータをファイルに保存し、後からパソコンで確認できます。
今回は、ESP32-C3を搭載した開発ボード「KUMITATE-C3」を使って、SDカードをSPI通信で接続し、テキストファイルの書き込みと読み出しを行う方法を解説します。
Arduino IDEで動かせるサンプルプログラムも紹介するので、ぜひ試してみてください。
1. ESP32でSDカードを使うと何ができる?
ESP32にSDカードを接続すると、次のような用途に活用できます。
- 温度・湿度・照度などのセンサデータの保存
- IoTデータロガーの作成
- CSVファイルへの測定結果の記録
- 設定ファイルの読み込み
- 長期間の動作ログの保存
例えば、ESP32で温度センサの値を1分ごとに取得してSDカードに記録すれば、パソコンで測定結果をグラフ化できます。
Wi-Fiを利用してクラウドへデータを送る方法もありますが、SDカードならインターネット接続がない環境でもデータを保存できるのがメリットです。
2. ESP32とSDカードの接続にはSPI通信を使用する
SDカードには複数の通信方式がありますが、今回はSPI通信を使います。
SPI(Serial Peripheral Interface)は、マイコンと周辺機器の間でデータを送受信するための通信方式です。
主に次の4つの信号を使用します。
| 信号 | 役割 |
|---|---|
| SCK | クロック信号 |
| MOSI | ESP32からSDカードへデータを送信 |
| MISO | SDカードからESP32へデータを送信 |
| CS | 通信するデバイスを選択 |
これらの信号に加えて、電源(VCC)とGNDを接続します。
ESP32ではSPI通信に使用するGPIOをプログラムから指定できるため、基板の構成に合わせて配線できます。
3. 使用する部品
今回使用する部品は次のとおりです。
- KUMITATE-C3(ESP32-C3搭載開発ボード)
- SPI対応microSDカードモジュール
- microSDカード(FAT32形式を推奨)
- ジャンパーワイヤー
- USBケーブル
KUMITATE-C3以外のESP32でも、利用可能なGPIOを適切に設定すれば同様のプログラムを応用できます。
注意:ESP32のGPIOは3.3V系です。SDカードモジュールは3.3Vロジックに対応したものを使用してください。5V入力に対応したモジュールでも、電源電圧や信号電圧の仕様を確認する必要があります。
4. ESP32とSDカードの配線方法
今回はKUMITATE-C3のGPIO4~GPIO7を使用します。
| microSDモジュール | KUMITATE-C3 |
|---|---|
| CS | GPIO4 |
| MOSI(DI) | GPIO5 |
| SCK(CLK) | GPIO6 |
| MISO(DO) | GPIO7 |
| VCC | 3.3V |
| GND | GND |
モジュールによっては、MOSIが「DI」、MISOが「DO」と表記されている場合があります。
配線を間違えるとSDカードが認識されないため、特にMOSIとMISOの接続に注意してください。
なお、ESP32-C3のGPIO4~GPIO7にはJTAGデバッグ用の機能も割り当てられています。これらをSPI通信に使用する場合、外部JTAGデバッグとの併用には注意が必要です。
5. Arduino IDEでSDカードを読み書きするプログラム
それでは実際にプログラムを作成してみましょう。
今回は、次の3つの処理を行います。
- SDカードを初期化する
- SDカードにtest.txtを作成して文字列を追記する
- ファイルを読み出し、シリアルモニタに表示する
Arduino-ESP32環境にはSPI通信を制御する「SPI.h」と、SDカードを操作する「SD.h」が用意されています。
サンプルプログラム
#include <SPI.h>
#include <SD.h>
// SDカードのSPI接続ピン
const int SD_CS = 4;
const int SD_MOSI = 5;
const int SD_SCK = 6;
const int SD_MISO = 7;
void setup() {
Serial.begin(115200);
delay(2000);
Serial.println("SDカードの初期化を開始");
// SPI通信を初期化
SPI.begin(SD_SCK, SD_MISO, SD_MOSI, SD_CS);
// SDカードを初期化(4MHz)
if (!SD.begin(SD_CS, SPI, 4000000)) {
Serial.println("SDカードの初期化に失敗");
return;
}
if (SD.cardType() == CARD_NONE) {
Serial.println("SDカードが見つかりません");
return;
}
Serial.println("SDカードを認識しました");
// SDカードの容量を表示
Serial.print("容量: ");
Serial.print(SD.cardSize() / (1024ULL * 1024ULL));
Serial.println(" MB");
// ファイルへ文字列を追記
File file = SD.open("/test.txt", FILE_APPEND);
if (!file) {
Serial.println("ファイルを開けません");
return;
}
if (file.println("Hello from ESP32-C3!")) {
Serial.println("書き込み成功");
} else {
Serial.println("書き込み失敗");
}
file.close();
// ファイルを読み出す
file = SD.open("/test.txt", FILE_READ);
if (!file) {
Serial.println("読み出しに失敗");
return;
}
Serial.println("--- SDカードの内容 ---");
while (file.available()) {
Serial.write(file.read());
}
file.close();
}
void loop() {
}
このプログラムはArduino-ESP32の標準SDライブラリを使用しています。使用するSDカードモジュールの仕様に合わせて動作を確認してください。
6. プログラムの実行結果
プログラムを書き込んだら、Arduino IDEのシリアルモニタを開き、通信速度を115200bpsに設定します。
正常に動作すると、次のようなメッセージが表示されます。
SDカードの初期化を開始
SDカードを認識しました
容量: 7560 MB
書き込み成功
--- SDカードの内容 ---
Hello from ESP32-C3!
※上記は初回実行時の出力例です。容量は使用するSDカードによって異なります。
SDカード内には「test.txt」というファイルが作成され、次の文字列が保存されます。
Hello from ESP32-C3!
今回は追記モードでファイルを開いているため、プログラムを再実行すると同じ文字列が追加されます。
7. プログラムのポイントを解説
SPI.begin()で通信ピンを設定する
SPI.begin(SD_SCK, SD_MISO, SD_MOSI, SD_CS);
ESP32で使用するSPI通信のピンを設定しています。
引数の順番は次のとおりです。
SPI.begin(SCK, MISO, MOSI, CS);
MISOとMOSIの順番を間違えないように注意してください。
SD.begin()でSDカードを初期化する
SD.begin(SD_CS, SPI, 4000000);
SDカードとの通信を開始する処理です。
今回は通信速度として4MHzを指定しています。
初期化に失敗する場合は、配線や電源を確認したうえで、通信速度を1MHz程度まで下げてみるのも一つの方法です。
SD.open()でファイルを開く
File file = SD.open("/test.txt", FILE_APPEND);
SDカード内の「test.txt」を追記モードで開きます。
ファイルが存在しない場合は新しく作成され、存在する場合は末尾にデータを追加します。
Arduino-ESP32では、FILE_APPENDが追記、FILE_WRITEが新規書き込み・上書き用のモードです。FILE_WRITEで既存ファイルを開くと、それまでの内容は消去されるため注意してください。
println()でデータを書き込む
file.println("Hello from ESP32-C3!");
ファイルに文字列と改行を書き込んでいます。
センサデータを保存したい場合は、測定値に置き換えることで応用できます。
available()とread()で読み出す
while (file.available()) {
Serial.write(file.read());
}
ファイルに読み出せるデータがある間、1バイトずつ読み取り、シリアルモニタへ出力しています。
close()でファイルを閉じる
file.close();
書き込み後はファイルを閉じることが重要です。
特に、書き込み途中に電源を切るとデータが失われたり、ファイルが破損したりする可能性があります。
8. ESP32でSDカードが認識されない場合の対処法
SDカードが認識されないときは、次の項目を確認してください。
① 配線が正しいか
MOSI、MISO、SCK、CSの接続を再確認してください。
ESP32の種類によってデフォルトのSPIピンは異なります。ほかのESP32ボードを使用する場合は、プログラムのGPIO番号も変更してください。
② SDカードのフォーマットを確認する
SDカードが対応していないファイルシステムでフォーマットされていると、初期化できないことがあります。
今回はFAT32形式のmicroSDカードを推奨します。exFAT形式の場合は、FAT32対応カードで試してみてください。
なお、フォーマットすると保存済みデータが消去されるため、必要なファイルは事前にバックアップしてください。
③ 電源電圧を確認する
ESP32は3.3V系のマイコンです。
SDカードモジュールの仕様を確認し、適切な電源を供給してください。
また、電源が不安定な場合も、初期化や書き込みに失敗することがあります。
④ SPI通信速度を下げる
通信が不安定な場合は、次のように速度を下げて試します。
SD.begin(SD_CS, SPI, 1000000);
配線が長い場合や信号品質が悪い場合は、通信速度を下げることで改善することがあります。
⑤ シリアルモニタに何も表示されない
ESP32-C3では、使用するボードやUSB接続方法によってシリアル出力の設定が異なります。
ネイティブUSBを利用する構成では、Arduino IDEの「USB CDC On Boot」の設定も確認してください。
9. 応用編:ESP32でセンサデータをSDカードにCSV保存する
今回のプログラムを応用すると、ESP32で取得したセンサの測定結果をSDカードに保存できます。
例えば、温度と湿度を次のようなCSV形式で保存できます。
time_s,temperature,humidity
0,25.1,52.3
60,25.3,52.1
120,25.4,51.8
CSVファイルはExcelなどの表計算ソフトで開けるため、測定結果の集計やグラフ化に便利です。
実際に温湿度センサと組み合わせれば、簡単なデータロガーを作成できます。
時間情報も記録したい場合は、ESP32のWi-Fi機能を利用してNTPから現在時刻を取得したり、RTCモジュールを追加したりする方法があります。
次の記事では、ESP32と温湿度センサを組み合わせて、一定間隔で取得した測定データをSDカードにCSV形式で保存するデータロガーの作り方を紹介します。
関連記事:ESP32とSDカードでCSV保存!センサデータロガーの作り方
10. まとめ
今回はESP32とSDカードをSPI通信で接続し、ファイルの書き込みと読み出しを行う方法を紹介しました。
今回のポイントは次のとおりです。
- ESP32とSDカードはSPI通信で接続できる
- SPI通信にはSCK、MOSI、MISO、CSの4信号を使用する
- SPI.hとSD.hを使うことでArduino環境から制御できる
- SD.open()でファイルを開き、文字列の保存や読み出しができる
- センサと組み合わせることでデータロガーにも応用できる
SDカードは、ESP32を使った電子工作やIoT開発で幅広く活用できる周辺機器です。
まずは今回のサンプルコードでファイルの書き込みと読み出しを試してみてください。
さらに実践的な使い方を学びたい方は、ESP32でセンサデータをSDカードにCSV保存する方法もご覧ください。
KUMITATE-C3を使った組み込みプログラミングの学習
クミタテでは、ESP32-C3を搭載したKUMITATE-C3を使って、GPIO、I2C、SPIなどの組み込みプログラミングを学べる教材を公開しています。
ESP32や電子工作に興味のある方は、ぜひこちらもご覧ください。

