今回はArduinoでSDカードを使ってみました。
SDカードが使えればデータロガー等を作るときにArduinoのメモリー領域を気にせずに保存しまくることができます。
<参考>
ArduinoでマイクロSDカード〜書き込み読み込み記録する
今回購入したのは5個入599円のSDカードモジュール、microサイズではなくフルサイズのSDカードです。(使う用途の無い古い1GBとか余っていたので丁度良かった)
使用ピンは
[ SD ] - [ Arduino ]
3.3V - 3.3V
CS - D10
MOSI - D11
SCK - D13
MISO - D12
GND - GND
としました。
参考サイトにCS(チップセレクト)ピンに動作安定させるためと10番ピンが使われていて、ピンの収まりが良かったのでそのまま10番ピンを採用しました。
SDカードはFAT16でフォーマット済み1GB
今回の使用ボードはメルカリで瀑安購入した中華製Arduino nanoです。
まずはカード情報を読取るサンプルを動かします。
コードはCS番号だけ10番に変更してそのままです。
// include the SD library:
#include <SPI.h>
#include <SD.h>// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile root;// change this to match your SD shield or module;
// Arduino Ethernet shield: pin 4
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8
// MKRZero SD: SDCARD_SS_PIN
const int chipSelect = 10 ; //←CSピン番号void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("\nInitializing SD card...");// we'll use the initialization code from the utility libraries
// since we're just testing if the card is working!
if (!card.init(SPI_HALF_SPEED, chipSelect)) {
Serial.println("initialization failed. Things to check:");
Serial.println("* is a card inserted?");
Serial.println("* is your wiring correct?");
Serial.println("* did you change the chipSelect pin to match your shield or module?");
while (1);
} else {
Serial.println("Wiring is correct and a card is present.");
}// print the type of card
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");
}// Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
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();// print the type and size of the first FAT-type volume
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);// list all files in the card with date and size
root.ls(LS_R | LS_DATE | LS_SIZE);
}void loop(void) {
}
シリアルモニターで動作確認
Initializing SD card...Wiring is correct and a card is
Initializing SD card...Wiring is correct and a card is present.Card type: SD1
Clusters: 60940
Blocks x Cluster: 32
Total Blocks: 1950080Volume type is: FAT16
Volume size (Kb): 975040
Volume size (Mb): 952
Volume size (Gb): 0.93Files found on the card (name, date and size in bytes):
SPOTLI~1/ 2022-05-02 23:09:28
STORE-V2/ 2022-05-02 23:09:28
6EA0AC~1/ 2022-05-02 23:09:28
PSID.DB 2022-05-02 23:09:44 8192
TM~1.LIO 2022-05-02 23:09:28 0・
・
(略)
・
・
TMPSPO~1.LOC 2022-05-02 23:09:40 2081
VOLUME~1.PLI 2022-05-02 23:09:30 4258
FSEVEN~1/ 2022-05-02 23:09:28
FSEVEN~1 2022-05-02 23:09:44 36
000000~1 2022-05-02 23:09:44 139
000000~2 2022-05-02 23:09:44 72
特にエラーも無くSDカード情報取得成功です。
簡単過ぎて驚きました。
続いて、カードの読み書き動作
これもCS番号だけ変更してサンプルのまま動作させてみます。
#include <SPI.h>
#include <SD.h>File myFile;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("Initializing SD card...");if ( !SD.begin( 10 ) ) { //←CS番号 4→10に変更
Serial.println("initialization failed!");
while (1);
}
Serial.println("initialization done.");// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
myFile = SD.open("test.txt", FILE_WRITE);// if the file opened okay, write to it:
if (myFile) {
Serial.print("Writing to test.txt...");
myFile.println("testing 1, 2, 3.");
// close the file:
myFile.close();
Serial.println("done.");
} else {
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}// re-open the file for reading:
myFile = SD.open("test.txt");
if (myFile) {
Serial.println("test.txt:");// read from the file until there's nothing else in it:
while (myFile.available()) {
Serial.write(myFile.read());
}
// close the file:
myFile.close();
} else {
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}
}void loop() {
// nothing happens after setup
}
動作確認
Initializing SD card...initialization done.
Writing to test.txt...done.
test.txt:
testing 1, 2, 3.
Initializing SD card...initialization done.
Writing to test.txt...done.
test.txt:
testing 1, 2, 3.
成功っぽいです。
PCにSDカードを認識させると
おお!きちんと書き込まれています。
3回実行したのできちんと3回追記されているようです。
外部メモリー難しそうと思っていましたがArduinoめちゃ簡単ですね。
これなら以前にRaspberryPiで作った低温調理器も温度変化ログぐらいなら簡単に取れそうだし安いArduinoで制御させてもいいかもしれません。(面倒なのでしないけど)
モジュールは便利です。