SDカードスロットを使用して、ファイルの読み書きを行っていきます。以前使用したBME280から取得した値をログとして、ファイルに追記していきます。
ファイルの読み書きが行えるとできることの幅が広がりそうで、楽しそうです。
ESP32、BME280、SDカードスロット接続
それぞれ接続していきたいと思います。
準備するものは、以下になります。
- ESP32-DevKitC
- ブレッドボード
- BME280
- SDカードスロットソケット
- ジャンパーワイヤー
- USBケーブル
SDカードスロットソケットは、Amazonの検索でヒットした安いものを使用しています。
中国から郵便で2週間程度かかって送られてきましたが、普通に使用できています。
以下のように接続を行います。
SDカードファイル読み書み プログラム作成
Arduino IDEを使用して、SDカードを使用したファイル読み書きプログラムを作成していきます。
処理概要
処理概要を箇条書きで以下に記載いたします。
- SDカード直下に「data」フォルダが存在することを確認する。
- 「data」フォルダが存在しない場合は、フォルダを作成する。
- 「data」フォルダ配下に、「bme280.csv」が存在することを確認する。
- 「bme280.csv」ファイルが存在しない場合は、ファイルを作成しファイルのヘッダ項目を追加する。
- 「bme280.csv」ファイルが存在する場合は、ファイルの内容を全て読み込み、シリアル通信で出力する。
- 定期的に、BMEから温度、湿度、気圧を取得してファイルに追記する。
プログラム作成
処理概要に従い、プログラムを作成します。
#include <SPI.h>
#include <SD.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
const int BME_CS = 15;
const int BME_SCK = 14;
const int BME_MOSI = 13;
const int BME_MISO = 12;
const unsigned int ADDRESS = 0x27;
const int CHARS_NUM = 16;
const int LINES_NUM = 2;
const int CS_PIN = 4;
const String file_path = "/data/bme280.csv";
Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK);
File f;
void setup() {
Serial.begin(115200);
delay(1000);
if(SD.begin(CS_PIN)){
Serial.println("SD OK");
}else{
Serial.println("SD Failed");
while(1);
}
// フォルダ確認
if(!SD.exists("/data")){
Serial.println("directory none");
SD.mkdir("/data");
}
// ファイル確認
if(SD.exists(file_path)){
Serial.println("file exist");
ReadFile(file_path);
}else{
Serial.println("file none");
f = SD.open(file_path, FILE_WRITE);
f.println("temp,humid,press");
f.close();
}
// BME280測定開始
bme.begin();
}
void loop() {
WriteBme280File();
delay(5000);
}
// BME280測定データ書き込み
void WriteBme280File(){
float temp = bme.readTemperature();
float humid = bme.readHumidity();
float pres = bme.readPressure() / 100.0;
char dat[32];
memset(dat, sizeof(dat), 0x00);
sprintf(dat, "%4.2f,%4.2f,%4.2f", temp, humid, pres);
f = SD.open(file_path, FILE_APPEND);
f.println(dat);
f.close();
}
// ファイル情報読み込み
void ReadFile(String path) {
char ch;
f = SD.open(path, FILE_READ);
if(f){
while(f.available()){
ch = f.read();
Serial.print(ch);
}
f.close();
}
}
プログラムについて簡単に説明いたします。
1~2行目で、SDカードの読み書きをするために「SPI.h」、「SD.h」を設定しています。SDカードとの通信にSPIを使用しているためです。
15行目でCSピン(チップセレクト)を設定してます。これは、SDライブラリの初期化で使用します。
16行目では、今回使用するファイル名を設定しています。ファイルパスは、SDカード直下の「data」フォルダの下の「bme280.csv」ファイルという感じです。
20行目で、Fileクラスの変数を設定しています。
27行目で、SDライブラリの初期化を行っています。先ほど設定したCSピンを引数に設定します。
35行目で、SDカード直下に「data」フォルダが存在するか確認して、存在しない場合は、37行目で「data」フォルダを作成しています。
41行目で、「bme280.csv」ファイルが存在するか確認しています。存在している場合は、「ReadFile()」関数でファイルの全データを読み込んでシリアル通信で出力しています。存在しない場合は、「bme280.csv」ファイルを作成してファイルヘッダ「temp,humi,press」を書き込んでいます。
ファイルをオープンして書き込んでも、48行目のように「close()」処理を行わないとデータが書き込まれないので、かならずファイルクローズを忘れないように注意して下さい。
ファイルオープンで指定できる引数は、以下の3つになります。
- FILE_READ・・・読み込み専用。
- FILE_WRITE・・・書き込みモード。新しくファイルの先頭から書き込み。
- FILE_APPEND・・・追記モード。ファイルの最後に追記していきます。
55~58行目で、5秒ごとにBME280からデータを取得して、ファイルに書き込んでいます。
実際の処理は、60~73行目の「WriteBme280File()」関数で行っています。
62~64行目で、温度、湿度、気圧を取得して、68行目でカンマ区切りのデータに変換しています。
70~72行目で、変換したデータを追記モードでファイルに書き込んでいます。
動作確認
動作確認をしてみます。Arduino IDEのシリアルモニタを起動して、シリアル出力で処理を確認します。
まず、SDカードを挿入して起動すると、SDカード認識OKで、フォルダとファイルがないことが出力されました。
この後しばらく放置して、BME280から取得したデータが書き込まれていくのを待ちます。
一旦電源を落として再投入します。
起動するとシリアルモニタに、SDカードとファイルが存在していることが表示され、ファイルに書き込まれた情報が出力されました。
作成したデータファイルは、EXCELで開くことができる「CSVファイル」にしているため、グラフ等の作成に使用できます。
まとめ
ESP32にSDカードスロットを接続して、ファイルの読み書きを行ってみました。
基本環境で用意されているライブラリを使用するだけで、簡単にファイルの読み書きが行えました。
バッテリーなどの問題もありますが、ESP32を孤立した環境に設置して、ログを取得するなどの用途で使用できそうです。
また、設定データを読み込んで動作するプログラムも作成できるので、いろいろと用途が広がりそうです。
【参考図書】