ESP32

ESP32でSDカードスロットを使って、ファイルの読み書きを行います

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を孤立した環境に設置して、ログを取得するなどの用途で使用できそうです。

また、設定データを読み込んで動作するプログラムも作成できるので、いろいろと用途が広がりそうです。

【参考図書】