サイトロゴ

ArduinoでマイクロSDカード〜書き込み読み込み記録する

著者画像
Toshihiko Arai

はじめに

こんなこと、やります。

  • ArduinoでマイクロSDカードの情報を表示する
  • SDカードに新規ファイルを作成する
  • SDカードにデータを書き込む
  • SDカードにデータを読み込む

この記事では、マイクロSDカードモジュールをArduinoで使う方法を解説します。

ArduinoとSDカードモジュールの配線

ArduinoとSDカードモジュールの配線は、次の通りになります。

SDカードモジュール Arduinoピン
3V3 3V3
CS pin 10
MOSI pin 11
CLK pin 13
MISO pin 12
GND GND

SDカードの電源電圧は3.3Vです。モジュール内に レベルシフター がない場合、5V電源を繋いでしまうと最悪の場合SDカードが壊れてしまいます。ご注意下さい。

CS番号に注意

サンプルプログラムですと、CS(チップセレクト)が4番ピンに指定されていましたが、動作が安定しなかったため10番ピンに変更しました。どうも、SDカードモジュールによって指定が異なるみたいです。

もし、SDカードの情報が表示されず、動作がおかしい場合はこのCSにつなげるピン番号を変えてみてください。その際は、プログラムのchipSelectの書き換えもお忘れなく。

SDカードの内容を表示するプログラム

Arduino IDEにサンプルプログラムが入っているので、ここではそれを利用してみます。Arduino IDEのFileメニューから、ExamplesSDでサンプルプログラムを開くことができます。

次は、SDカードの内容を表示するプログラムです。

#include <SPI.h>
#include <SD.h>

Sd2Card card;
SdVolume volume;
SdFile root;

const int chipSelect = 10;

void setup() {

  Serial.begin(9600);
  while (!Serial) {
    ;
  }

  Serial.print("\nInitializing SD card...");

  if (!card.init(SPI_HALF_SPEED, chipSelect)) {
    Serial.println("initialization failed.");
    while (1);
  } else {
    Serial.println("Wiring is correct and a card is present.");
  }

  Serial.println();
  Serial.print("Card type:         ");
  switch (card.type()) {
    case SD_CARD_TYPE_SD1:
      Serial.println("SD1");
      break;
    case SD_CARD_TYPE_SD2:
      Serial.println("SD2");
      break;
    case SD_CARD_TYPE_SDHC:
      Serial.println("SDHC");
      break;
    default:
      Serial.println("Unknown");
  }

  if (!volume.init(card)) {
    Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
    while (1);
  }

  Serial.print("Clusters:          ");
  Serial.println(volume.clusterCount());
  Serial.print("Blocks x Cluster:  ");
  Serial.println(volume.blocksPerCluster());

  Serial.print("Total Blocks:      ");
  Serial.println(volume.blocksPerCluster() * volume.clusterCount());
  Serial.println();


  uint32_t volumesize;
  Serial.print("Volume type is:    FAT");
  Serial.println(volume.fatType(), DEC);

  volumesize = volume.blocksPerCluster();    // clusters are collections of blocks
  volumesize *= volume.clusterCount();       // we'll have a lot of clusters
  volumesize /= 2;                           // SD card blocks are always 512 bytes (2 blocks are 1KB)
  Serial.print("Volume size (Kb):  ");
  Serial.println(volumesize);
  Serial.print("Volume size (Mb):  ");
  volumesize /= 1024;
  Serial.println(volumesize);
  Serial.print("Volume size (Gb):  ");
  Serial.println((float)volumesize / 1024.0);

  Serial.println("\nFiles found on the card (name, date and size in bytes): ");
  root.openRoot(volume);

  root.ls(LS_R | LS_DATE | LS_SIZE);
}

void loop(void) {
}

次のように、SDカード情報が表示されれば成功です。

ファイルを読み書きする

次にSDカードにファイルの読み書きを行ってみましょう。

#include <SPI.h>
#include <SD.h>

File myFile;

void setup() {
  Serial.begin(9600);
  while (!Serial) {
    ;
  }

  if (!SD.begin()) {
    Serial.println("initialization failed!");
    while (1);
  }
  
  myFile = SD.open("hoge.txt", FILE_WRITE); // creat new file

  

  if (myFile) {
    myFile.println("Hello, SD card?"); // write contents
    myFile.close();
  } else {
    Serial.println("file open failed!");
  }

  myFile = SD.open("hoge.txt");
  if (myFile) {
    Serial.println("-----------------------");
    while (myFile.available()) {
      Serial.write(myFile.read()); // read contents
    }
    myFile.close();
  } else {
    Serial.println("file open failed!");
  }

}

void loop() {
}
  • SD.open("ファイル名", FILE_WRITE)で、「ファイル名」がなければ新規作成されます。
  • myFile.println(内容);で「内容」を書き込みます。
  • myFile.read()で「内容」を読み込みます。

注意

内容をシリアルモニターに表示する際、Serial.printを使うとASCIIコードで表示されてしまいます。数字の羅列しか表示されない場合は、Serial.writeを使って出力してください。

また、ファイルハンドラ(myFile)を作ったときは、必ずmyFile.close()でファイルハンドラを閉じてください。実践的なプログラムではメモリーリークにつながる恐れがあります。

関連記事