SD microSD(TF)カードを使ってみる(Arduino)
センサー類から送られてくる情報を記録して、
後で解析するということも多いと思います。
そんなときの記憶媒体として、価格も手頃で利用しやすい
SDカードやmicroSD(TF)カードを使用してみます。
TF(Trance Flash)カードとは、サンディスクが開発したもので、
microSDカードはこのTFカードの仕様を引き継いだものです。
Arduinoの本体には、SDカードを挿入するスロットなどはありません。
利用するためには、SDカードリーダーモジュールが必要になります。
ネットで検索すると、いろいろな製品が紹介されています。
検索:”Arduino SD microSD TF カードリーダー”
私が利用しているモジュールを紹介します。
AliExpress
・ SDカードスロットソケットリーダーモジュールSPI
¥61-(送料:¥133-)
・マイクロSD(TF)カードメモリシールドモジュールSPI
¥51-(送料:¥133-)
https://www.aliexpress.com/item/32523546123.html?spm=a2g0s.9042311.0.0.5d074c4dCMqN22
・・・送料の方が高いですね。
今回使用した、SDカードとmicroSD(TF)カードです。
SDカードは、相性なのか、モジュール不良なのか
上手くアクセスできず、5枚試してみましたが、
・2GBのものは、使えませんでした。
PCでは問題なく利用可能です。
・512MBのものは、途中から使えなくなりました。
PCでも、アクセス不良になり、廃棄ですね。
・128MBのものは、1枚は使用できず、もう1枚は途中から使えなくなりました。
2枚ともPCでは問題なく利用可能です。
microSD(TF)カード
・1GBのも1枚のみ使用しましたが、問題なく利用できました。
もちろん、PCでも問題なく利用可能です。
各カードフォーマット処理は、
・SDメモリカードフォーマッターを使用
https://www.sdcard.org/jp/downloads/formatter/
ダウンロードして展開(解凍)しインスートールします。
デスクトップの”SD Card Formatter”アイコンを選択し起動します。
・WindowsOS付属のフォーマットソフトを使用
エクスプローラーの左ペインからSDカードの対象ドライブを選択し右クリック、
表示されたメニューから、”フィーマット(A)…”を選択します。
※対象ドライブを間違えないようくれぐれも注意して下さい。
と、いろいろ試してみました。
ということで、私が紹介するモジュールでは、
”マイクロSD(TF)カードメモリシールドモジュールSPI” を使用する方が、
良いかと思います。
このモジュールは、SPI通信対応製品なので、本体との接続も単純です。
回路は図の通りです。
この回路図の作図には fritzing を利用させて頂いております。
https://fritzing.org/home/
・配線は、モジュールによって違います。
必ず、利用モジュールのデータシートを確認して下さい。
SDカードモジュールの場合
モジュール側 | Arduino側 |
GND | GND |
3V3 | 未接続(3.3V?) |
5V | 5V |
CS | 10番PIN |
MOSI | 11番PIN |
SCK | 13番PIN |
MISO | 12番PIN |
GND | 未接続(GND?) |
※私のが使用したモジュールでは正常な動作はしませんでした。
書き込めたり、書き込めなかったり、読めたり、読めなかったり、
文字化けしたファイルが作成されたりです。
電源供給の問題もあるかと、3.3Vを供給したり、
別電源で供給したりもしましたがまともな動作はできませんでした。
モジュールの問題なのか、SDカードとの相性なのか、
残念ながら私の技量では解決できませんでした。
microSD(TF)カードモジュールの場合
モジュール側 | Arduino側 |
CS | 10番PIN |
SCK | 13番PIN |
MOSI | 11番PIN |
MISO | 12番PIN |
VCC | 5V(3.3V?) |
GND | GND |
※私のが使用したモジュールですが、
データシートでは、VCCは5Vor3.3Vとなっていましたが、
3.3Vの供給では動作しませんでしたので、
5V供給で使用しましたが、動作は良好でした。
SPI(Serial Peripheral Interface)
マイクロコントローラに複数のデバイスを接続する目的で使用される、
短距離用の簡便な同期通信プロトコルです。
Arduino Uno:10(SS)、11(MOSI)、12(MISO)、13(SCK)ピンが使用されます
・Master In Slave Out (MISO) - (機器)スレーブから(本体)マスタへデータ送信用
・Master Out Slave In (MOSI) - (本体)マスタから(機器)スレーブへデータ送信用
・シルアルクロック (SCK) - データ転送用同期クロック信号用
・SS(Slave Select)は - マスタが通信相手(機器)スレーブを選択するための信号線用
スレーブでは、CS(Chip Select)と表記されています。
※Arduino UNOの互換機では、SSの指定が10番ピンでないものもあります。
その場合は、スケッチで指定することができます
※Arduino UNO 以外では、SPI通信で使用するピンが変わります。
データシートやインターネットで調べて配線して下さい。
SS(Slave Select)のピン番号を4番ピンに変更する場合は、
// ChipSelect番号設定
const int chipSelect = 4;
// SDカードへのアクセス確認
if ( SD.begin(chipSelect) ) {
}
などと、記述することで変更可能です。
ここからは、スケッチです。
今回は、
・SPI通信用に、SPIライブラリ
・SD操作用に、SDライブラリ
を利用します。
インストール済みでインストール操作の必要はないと思います。
ファイルへの操作は大きく分けて、
・ファイルへの書き込み
・ファイルからの読み込み
・ファイルの削除
の3種類で、手順はそれぞれ以下の通りです。
1.ファイルへの書き込み手順
1.SDカードへのアクセス確認
2.ファイルの有無確認
3.ファイルが存在しない場合は作成
4.ファイルのオープン
5.書き込み処理
6.ファイルのクローズ
・ファイルの書き込みは追記処理が基本となります。
ファイルが存在すれば追記されます。
・ファイルが存在しない場合は、空のファイルの作成処理が行われます。
その後、このファイルをオープンし書き込み処理を行うことになります。
・新規ファイルへの書き込みを行いたい場合には、
既存ファイルの削除処理を行い、ファイルを新規作成することで可能です。
2.ファイル内容の読み込み手順
1.SDカードへのアクセス確認
2.ファイルのオープン
3.読み込み処理
4.ファイルのクローズ
3.ファイルへの削除手順
1.SDカードへのアクセス確認
2.ファイルの有無確認
3.ファイルの削除
・ファイルの有無を確認せず削除処理をしても問題ないと思います。
ファイルが存在しなければ削除できないだけだからです。
ただし、SD.remove( ) 関数で、削除の成功、失敗を判定する場合は、
ファイルの有無を確認する必要があります。
最初は、
SDカードへ書き込み処理をするスケッチです。
// ライブラリのインクルード
#include SD.h // SD関連
#include SPI.h // SPI関連
boolean flg = false; // SDカードモジュールの確認フラグ
char fName[] = "DATA1.TXT"; // SDカードの指定ファイル名
void setup() {
// put your setup code here, to run once:
// シリアルモニタ設定
Serial.begin( 9600 );
// シリアルモニタの準備用時間稼ぎ
delay(5000);
// SDカードモジュールの確認
Serial.println( "SD card module check start" );
flg = SD.begin();
if ( flg ) {
// SDカードモジュールの確認完了
Serial.println( "SD card module check OK" );
// 指定ファイルへのアクセス(有無)確認
Serial.println( "check for the existence of files" );
if( !SD.exists( fName ) ){
// ファイルが存在しないので空ファイルを作成
Serial.println( "no specified file" );
File file = SD.open( fName, FILE_WRITE );
if ( file ) {
file.close();
Serial.println( "create specified file" );
}
}
// 指定ファイルへ書き込み処理
Serial.println( "start writing to file" );
// ファイルのオープン処理(書き込みモード)
File file = SD.open( fName, FILE_WRITE );
if ( file ) {
// ファイルのオープンに成功
Serial.println( "file open OK" );
// ファイルへの書き込み処理
file.print( "data, " );
file.print( 123, DEC );
file.print( ", " );
file.println( 456, DEC );
Serial.println( "file write OK" );
// ファイルのクローズ処理
file.close();
Serial.println( "file close OK" );
} else {
// ファイルのオープンに失敗
Serial.println( "file open NG" );
}
} else {
// SDカードモジュールの確認失敗
Serial.println( "SD card module check NG" );
}
}
void loop() {
// put your main code here, to run repeatedly:
}
このスケッチは、
ファイル名:DATA1.TXT
書き込み内容:
・文字:data
・数値:123
・数値:456
をカンマ区切りの1行(1レコード)として書き込みます。
”data, 123, 456” こんな感じです。
また、動作状況をシリアルモニタに表示します。
・このスケッチでは、setup() 関数の最初で、delay(5000); を実行しています。
これは、マイコンボードへの書き込みが完了すると同時にスケッチ内容が
実行されてしまい、シリアルモニタの起動が間に合いません。
そのため、シリアルモニタの準備時間として、5秒待機させています。
・SDカードの抜き差しは、電源がOFFの時に行うのが理想です。
特に書き込みタイミングなどに抜き差しすると破損する場合があります。
シリアルモニタに実行状況を表示するようスケッチしてみましたので、
確認しながら行って下さい。
※私も抜き差しミスやスケッチミスで何枚か駄目にしています。
Arduinoへ書き込み処理をして実行してみます。
SDカードは、PCで確認できます。
ファイルは、メモ帳などで開くことができますので確認してみて下さい。
続いて、
SDカードの”ファイル名:DATA1.TXT” から
読み込み処理をするスケッチです。
// ライブラリのインクルード
#include SD.h // SD関連
#include SPI.h // SPI関連
boolean flg = false; // SDカードモジュールの確認フラグ
char fName[] = "DATA1.TXT"; // SDカードの指定ファイル名
void setup() {
// put your setup code here, to run once:
// シリアルモニタ設定
Serial.begin( 9600 );
// SDカードモジュールの確認
Serial.println( "SD card module check start" );
flg = SD.begin();
if ( flg ) {
// SDカードモジュールの確認完了
Serial.println( "SD card module check OK" );
// 指定ファイルからの読み込み処理
Serial.println( "start reading from file" );
// ファイルのオープン処理(読み込みモード)
File file = SD.open( fName, FILE_READ);
if ( file ) {
// ファイルのオープンに成功
Serial.println( "file open OK" );
// ファイルからの読み込み処理(行単位)
Serial.println( "----- reed data start -----" );
while ( file.available() ) {
Serial.write( file.read() );
}
Serial.println( "----- reed data end -----" );
// ファイルのクローズ処理
file.close();
Serial.println( "file close OK" );
} else {
// ファイルのオープンに失敗
Serial.println( "file open NG" );
}
} else {
// SDカードモジュールの確認失敗
Serial.println( "SD card module check NG" );
}
}
void loop() {
// put your main code here, to run repeatedly:
}
このスケッチは、ファイルの内容を1行(1レコード)単位で読み込み、
シリアルモニタのその内容と動作状況を表示します。
・行単位での読み込みを行っていますが、
次のレコード(読み込み可能なレコード)が続く間(ファイルの最後まで)、
読み込みを繰り返すため、
while ( file.available() ) { // 継続レーコードの有無確認
Serial.write( file.read() );
}
を使用しています。
Arduinoへ書き込み処理をして実行してみます。
このスケッチの実行確認では、
ファイルの内容を3行(3レコード)に増やして実行確認しています。
最後に、
SDカードから ”ファイル名:DATA1.TXT” を
削除するスケッチです。
// ライブラリのインクルード
#include SD.h // SD関連
#include SPI.h // SPI関連
boolean flg = false; // SDカードモジュールの確認フラグ
char fName[] = "DATA1.TXT"; // SDカードの指定ファイル名
void setup() {
// put your setup code here, to run once:
// シリアルモニタ設定
Serial.begin( 9600 );
// シリアルモニタの準備用時間稼ぎ
delay(5000);
// SDカードモジュールの確認
Serial.println( "SD card module check start" );
flg = SD.begin();
if ( flg ) {
// SDカードモジュールの確認完了
Serial.println( "SD card module check OK" );
// ファイルの有無確認
if( SD.exists( fName ) ){
// ファイルが存在するので削除
SD.remove( fName );
Serial.println( "file erasure completed" );
} else {
Serial.println( "target file does not exist" );
}
} else {
// SDカードモジュールの確認失敗
Serial.println( "SD card module check NG" );
}
}
void loop() {
// put your main code here, to run repeatedly:
}
このスケッチは、指定ファイル(”DATA1.TXT”)を削除し、
その動作状況をシリアルモニタに表示します。
Arduinoへ書き込み処理をして実行してみます。
ファイル処理は、
・アクセスでは、順次アクセスや直接アクセスなど、
・扱うデータでは、テキストデータやバイナリデータなど、
とさまざまです。
近年では、デーベースで一括管理される時代ですが、
基本的な知識として知っておきたい内容です。