●ArduinoでSDカードを操作する

アマゾンで150円ぐらいで購入したSDカードソケットを使いSDカードの読み書きをしたいと思います。
KKHMF SDカードスロットソケットリーダーモジュールArduino用 [並行輸入品]
電圧変換や面倒な回路はすべて組み込まれているようです。


■デジタルピンを使ったArduinoとの接続

SPIにより通信を行います。
UNOでの通信にはデジタルピンの11,12,13が割り当てられています。
CSは接続機器毎の識別のためにあるので、今回は初期値のデジタルピン10番を使用します。



SDカードソケットのGNDをArduinoのGNDへ接続
SDカードソケットの3V3は使わない
SDカードソケットの 5VをArduinoの5Vへ接続
SDカードソケットの CS をArduinoのデジタルピン10へ接続
SDカードソケットのMOSIをArduinoのデジタルピン11へ接続
SDカードソケットの SCKをArduinoのデジタルピン13へ接続
SDカードソケットのMISOをArduinoのデジタルピン12へ接続

以上の電源と4本の線を接続します。
12番と13番が入れ替わっていますので注意してください。

Arduino側の配線の様子


SDカードソケット側の様子



▼もしデジタルピンの通信でうまく動かなかった場合

通常はデジタルピンのSPI通信でうまくいくと思いますが、どうしてもうまく動かない場合にはISCP端子にも同時にSPIの信号が出ていますので、
それに接続してみるのも手だと思います。
ISCP端子のSPI通信とデジタルピンのSPI通信はプログラムはそのままで動作しますが、動きに何か違いがあります。
ボードが本物か他メーカーの互換かなどの違いで、どちらの端子を使うかによって接続機器の動きが変わってきます。
互換UNOでは動きませんでしたが、互換NANOでは動作しました。
本物のボードだと正しく動くみたいですが、互換品だと色々問題が発生するみたいです。
まあ、この辺はタイミングの問題らしくてよくわかりません。

ISCP端子の位置

この互換UNOではデジタルピンでは動作しましたが、ISCP端子では動作しませんでした。

SDカードソケットの CS をArduinoのデジタルピン10へ接続し、残りの端子は次の位置に接続します。


NANOの場合には端子はこの方向から見ます。

SDカードソケットの CS をArduinoのデジタルピン10へ接続し残りの端子をISCP端子に接続しました。
この互換NANOではデジタルピン、ISCP端子の両方とも動作しました。


■使用できるSDカード

SD カード (FAT16 128MB - 2GB)
SDHCカード(FAT32 4GB - 32GB)

SDカードかSDHCカードでFAT16もしくはFAT32でフォーマットされている必要があります。
128MB以下のサイズのSDカードはFAT12でフォーマットされてしまうため、(普通の方法では)使えないと思ったほうがいいです。
32GB以上のSDXCカードも(普通の方法では)使えないと思ったほうがいいです。
相性があるため、複数枚のSDカードを準備しておく必要があります。


■実行時の注意点

ファイル名はすべて大文字になります。
小文字のファイル名でファイルを作成しても大文字のファイルができます。

ファイルの作成具合や削除具合の動作がおかしいときはSDカードを取り出してパソコンでフォーマットする必要があります。
クイックフォーマットで解決できればいいのですが、ダメな時はガチのフォーマットしないといけない場合があります。

SD.removeでファイルの削除を行うと削除されない、もしくはファイルが壊れる
または、文字化けしたたくさんのファイルが出現する
などの挙動不信の動作が現れた時にはSDカードを他の種類の物に交換してみてください。
瞬時に解決することがあります。
相性があり、SDカードにより動作するものと動作しないものがかなりあります。

SDカードとして一般に安価で売られている物はTLC(トリプル・レベル・セル)タイプの物です。
一つのセルにたいして約1000回の書き換えで寿命に到達するため、書き換え回数をなるべく少なくする工夫が必要になってきます。


■ファイルの作成と書き込み

ファイルに書き込む場合には、ファイルが存在する必要があります。
ファイルは一番うしろに追記される。ため、ファイルなしの場合にはファイルだけ作成されて何も書き込まれない。
そのため、最初にファイルの存在確認を行ってから、無い場合には空のファイルを作成します。
ファイルが存在しないのに書き込むと空のファイルのみが作成されて書き込みは失敗します。

ファイル書き込みはすべて追記です。
上書きしたい場合には、一度ファイルを削除してから新たに書き込む必要があります。

#include <SD.h>

char*filename="TEST.TXT";

void setup(){
  //デフォルトの10番をCS(チップセレクトとする)
  //SPIで使うピンは11、12、13
  if(SD.begin()){
      //ファイルが存在しない場合には空のファイルを作成する
      if(!SD.exists(filename)){
        File file = SD.open(filename, FILE_WRITE);
        if (file) file.close();
        digitalWrite(2,HIGH);
      }
    File file = SD.open(filename, FILE_WRITE);
    if (file) {
      //ファイル書き込み
      file.print(10,DEC);
      file.println(":test");
      file.close();
    }else{
      //ファイルが開けない場合のエラー処理
    }
  }else{
    //SDカードが開けない場合のエラー処理
  }
}

void loop(){

}


■ファイル読み込み

開発環境のツール→シリアルモニタを開くと、TEST.TXTの内容が表示されます。

#include <SD.h>

void setup(){
  Serial.begin(9600);
  //デフォルトの10番をCS(チップセレクトとする)
  //SPIで使うピンは11、12、13
  if(SD.begin()){
    File file = SD.open("TEST.TXT", FILE_READ);
  
    if (file) {
      while (file.available()) {
        Serial.write(file.read());
      }
      file.close();
    }else{
      //ファイルが開けない場合のエラー処理
    }
  }else{
    //SDカードが開けない場合のエラー処理
  }
}

void loop(){

}


■ファイルの削除

#include <SD.h>

void setup(){
  if(SD.begin()){
     SD.remove("TEST.TXT");
  }
}

void loop(){

}


■ファイルが存在するか

#include <SD.h>

void setup(){
  //デフォルトの10番をCS(チップセレクトとする)
  //SPIで使うピンは11、12、13
  if(SD.begin()){
        if(SD.exists("TEST.TXT")){
          //ファイルが存在した場合の処理
        }
  }
}

void loop(){

}


▲トップページ > マイコンなど