ArduinoでマイクロSDカード〜書き込み読み込み記録する
こんなこと、やります。
- ArduinoでマイクロSDカードの情報を表示する
- SDカードに新規ファイルを作成する
- SDカードにデータを書き込む
- SDカードにデータを読み込む
この記事では、マイクロSDカードモジュールをArduinoで使う方法を解説します。
つかうもの
はじめに、この記事で使うものをご紹介します。
マイクロSDカード拡張モジュール
マイクロSDカード
マイクロSDカードはSDまたはSDHCをお使いください。SDXCは使えませんのでご注意ください。 私はSDHCを使用しました。
また、SDカードはFAT16またはFAT36でフォーマットしておく必要があります。
Arduino
Arduino Uno Rev3を使用しました。
この記事の内容は、ほかのArduinoでも動作します。
まだArduinoをお持ちでないようでしたら おすすめArduinoどれを選べばいい?Arduinoで電子工作をはじめる方へ をご覧ください。
その他の電子部品
また、ブレッドボードやジャンプワイヤもあると便利です。
ArduinoとSDカードモジュールの配線
ArduinoとSDカードモジュールの配線は、次の通りになります。
SDカードモジュール | Arduinoピン |
---|---|
3V3 | 3V3 |
CS | pin 10 |
MOSI | pin 11 |
CLK | pin 13 |
MISO | pin 12 |
GND | GND |
▼ 書き込みに失敗する場合や、電圧問題が心配な方はレベルシフターとレジュレータが内蔵された下記商品をお勧めします。
CS番号に注意
サンプルプログラムですと、CS(チップセレクト)が4番ピンに指定されていましたが、動作が安定しなかったため10番ピンに変更しました。どうも、SDカードモジュールによって指定が異なるみたいです。
もし、SDカードの情報が表示されず、動作がおかしい場合はこのCSにつなげるピン番号を変えてみてください。その際は、プログラムのchipSelectの書き換えもお忘れなく。
SDカードの内容を表示するプログラム
Arduino IDEにサンプルプログラムが入っているので、ここではそれを利用してみます。Arduino IDEのFileメニューから、Examples→SDでサンプルプログラムを開くことができます。
次は、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()でファイルハンドラを閉じてください。実践的なプログラムではメモリーリークにつながる恐れがあります。