SDカード(フラッシュメモリー)

SDカードは SPI 方式で接続可能なフラッシュメモリーです。容量は2GBまで可能で、大規模なメモリーが装備されていない組み込みコンピュータの記憶装置として利用できます。ここでは、小型のマイクロSDカードをソケットに差し込んで利用します。

  1. SDカード

     SDカードは フラッシュメモリーを実装し、ファイルシステム(FAT16:16ビット)を搭載した記憶モジュールです。最近の大型のSDカードは FAT32 を搭載した SDHC になっていますが、組み込み用のSDカードは2GBが最大容量です。FATシステムは、ファイルやディレクトリの作成や削除が可能で、USB メモリーと同様 USB カードを介して PC で読み書き可能です。
     
       マイクロSDカード

  2. SPI方式

     SPI(Serial Peripheral Interface)方式は、クロック信号と2本のデータ線を用いて高速にデータを送受信する方式です。SPI はマスター:スレーブで構成され、マスターからCLKでクロック信号を送り、このクロックに同期してマスターからスレーブに データ(MOSI:MasterOutSlaveIn)を送り、同時にスレーブからマスタに送られるMISO(MasterInSlaveOut)でデータを受け取ります。前節のシフトレジスタによるシリアル通信が双方向になったものと考えられます。

        SPI 接続

     Arduinoには SPI 接続を行うハードウエアが用意されており、端子は D13(CLK)、D12(MISO)、D11(MOSI)、に割り当てられています。他に、マスターからCS(ChipSelect)を送りスレーブを有効にします。このCS端子はディジタル出力であればどの端子でもかまいません。

  3. マイクロSDカードモジュールと接続(MINI)

     SDカードには、標準、ミニ、マイクロ、の3サイズがありますが、ここでは下図の マイクロSDカードモジュールを利用します。SPI による接続機能はSDカードに内蔵されていますから、モジュールはブレッドボードに挿入できるよう、端子の間隔を調整しているだけです。
     ピン 9,10 はカードが挿入されるとONになります。このスロットにマイクロSDカードを挿入して利用します。VDDが電源の+(3.3V)、VSS が電源の GND 側になります。
    3.3Vの MINI の場合 SDカードの端子と直結できます。SDカードの CLK は MINI のCLK 端子(D13)に、DATO がSDカードの出力なので MINIの MISO(D12) に、CMD が SDカードの入力なので、MINI の MOSI(D11) に接続します。CD/DAT3 がこのモジュールの選択信号で、ここでは MINI の D10 に接続します(この端子は変更可能です)。

    8番 DAT1 //使用しない
    7番 DAT0 (MISO)
    6番 VSS
    5番 CLK>
    4番 VDD
    3番 CMD(MOSI)
    2番 CD/DAT(CS)
    1番 //使用しない

        マイクロSDカードモジュール

  4. SPI接続の電圧問題(UNO)

     UNO の端子の電圧はHのとき 5V ですが、SD カードは3.3V が最大です。したがって、UNO の信号を直接接続すると、電圧が過大になります。そこで、バッファー素子(HC4050)を利用し、電圧を調整します。これは、電圧変換用のバッファー素子を4個収納した IC で、電源を3.3V(1ピン:3.3V、8ピン:GND)とすることで、出力端子の HIGH の電圧を最大3.3Vにできます。
     またこの素子は入力 5V にも耐えることができます。この素子は上から見て切り欠きを左にしたとき、左端が1ピンになりあます。ここでは、CLK、MOSI、CS を14,11,9 ピンに入力し、15,12,10 から変換出力を取り出し、SDカードに接続します。MISO 端子はSDカード出力なので、そのまま、Arduino に接続できます。

      バッファー素子

  5. SDカードの回路(UNO)

     74HC4050 を切り欠きを左向きに挿入します。74HC405 の電源は Arduino の3.3V端子を利用します。GND 端子は 5V 電源の GND と共通です。SD カードのソケットは端子のみを表示しています。1番ピンを左に配置します。こちらの電源も3.3Vです。
     UNO の出力端子 D13,D11,D8 を 74HC4050 のバッファを通してSDカードに接続します。

     UNO と SDカードモジュールの接続

  6. SDカードライブラリ

     SDカードには Arduino のライブラリが用意されています。以下のようにライブラリを読み込みます。SD.begin(CSPIN) で SD カードの利用を準備します。CSPIN は SDカードの選択信号で、SD カードの2番端子への出力信号になります。ここでは、MINI(UNO)の10番端子に接続していますが、変更可能です。SD カードモジュールに不具合がある場合(SDカードが挿入されていない、接続が不良など)、SD.begin (CSPIN) は false を返します。
     #include <SD.h> 
      SD.begin(CSPIN)
      SD.open(fname, FILE_WRITE); でファイルを書き込み用に開きます。fnameはファイル名です。この戻り値がファイル情報になります。これを myFile に受け取ります。同じ名前のファイルがない場合はファイルを作成します。myFile.println("testing 1, 2, 3."); でファイルに書き込みをします。同じ名前のファイルが存在する場合、そのファイル最後に追加をします。書き込みが終了したら close(); で閉じます。
      char fname[20]="tet00.txt";
      File myFile;
      myFile = SD.open(fname, FILE_WRITE); 
      myFile.println("testing 1, 2, 3.");
      myFile.close();
     ファイルを読むには まず、SD.open(fname); でファイルを開きます。available(); でファイルが読み取り可能か確認できます。読み取りは read() を利用します。読み取りが完了したら close() します。
      myFile = SD.open(fname); 
      myFile.available();
      myFile.read();
      myFile.close();
     ファイルの存在は、exists(ファイル名)、削除はremove(ファイル名;) を利用します。同じ名前のファイルが存在する場合、あらかじめ削除しておかないと、古いファイルの最後に追加記録されます。
     SD.exists(fname);
     SD.remove(fname);

  7. SDカードプログラム

     setup() で シリアル通信の初期設定、myFile = SD.begin(CSPIN) で、SDカードの初期設定を行います。接続が間違っていたり、SDカードが挿入されていないと、myFile は false を返します。 ! は論理否定で、!SD.begin(CSPIN) がtrue のとき、" device error " のメッセージを表示します。
     同じ名前のファイルが存在する場合、ファイルの削除を行った後、ファイルを作成します。myFile.println("testing 1, 2, 3."); で書き込み、 File.close();でファイルを閉じます。
     書き込み後ファイルを読み出し、その内容をシリアルに出力します。myFile = SD.open("test.txt"); はファイルを読み取りモードで開きます。myFile.available() はデータが残っていることを確認しながら myFile.read() でデータ(文字単位)を読み取り、Serial.println() でシリアルに出力します。
     SDカードのファイルの内容は、SDカードのアダプタを利用してPCで確認することもできます。
    //SD card
    //clk 14>>15, 
    //MOSI 11>>12 
    //CS 9>>10
    //HC7450 電源 1:3.3V 8:GND
    
    #include <SD.h>
    
    File myFile;
    int i;
    int CSPIN=10;
    char fname[20]="tet00.txt";
    
    void setup()
    {
    // Open serial communications and wait for port to open:
      Serial.begin(9600);
    
      Serial.println("init SD card");
       pinMode(CSPIN, OUTPUT);
       //CSPINはSDカードのcsを接続した端子番号
      if (!SD.begin(CSPIN)) {
        Serial.println("device error");
        return;
      }
      
      Serial.println("create new file");
      
      if(SD.exists(fname)) {
        Serial.print("delete:");
        Serial.println(fname);
        boolean ans=SD.remove(fname);
      }
      
      myFile = SD.open(fname, FILE_WRITE);
      // if the file opened okay, write to it:
      if (myFile) {
        Serial.println("Writing to");
        myFile.println("testing 1, 2, 3.");
        myFile.println("success!");
        for(i=0;i<50;i++){
          myFile.print(i);  myFile.print(',');
          myFile.println(i+1);
        }
    // close the file:
        myFile.close();
        Serial.println("write done.");
      } else {
        // if the file didn't open, print an error:
        Serial.println("error creating test.txt");
      }
     
      // re-open the file for reading:
      myFile = SD.open(fname);
      if (myFile) {
        Serial.println("open file");  
        //ファイルを表示する
        while (myFile.available()) {
        Serial.write(myFile.read());
        }
        //ファイルを閉じる
        myFile.close();
      } else {
      //open 失敗
        Serial.println("error open");
      }
      //
      
    }
    
    void loop()
    {
    
    }
     ファイルから読み取ったデータをシリアル出力しています。Arduino のモニタで確認してください。PCに接続できる SDードアダプタがあれば、PCでファイルの内容を確認できます。
    init SD card
    create new file
    delete:tet00.txt
    Writing to
    write done.
    open file
    testing 1, 2, 3.
    success!
    0,1
    1,2
    2,3
    3,4
    4,5
    略

  8. 発展

     
    1. ファイルの書き込み回数に制限はありますか?

      一般にフラッシュメモリーの書き込み回数には制限があり、1万回ともいわれます。書き込むときはできるだけまとめて書き込む必要があります。
    2. 4GB以上のSDカードは利用できますか?

      4GB以上はSDHCカードになり、利用できません。

    3. USBメモリーは利用できますか?

      原理的には利用できますが、組み込みコンピュータ側に USBホスト 機能が必要になります。

    4. 先のプログラムで、新しいファイル名をしても delete が行われます

       Arduino では、プログラムの書き込みが終わるとすぐに実行が始まります。シリアルモニターを開くと リセットがかかり最初から実行を再開しますが、その前にファイルが書き込まれている可能性があります。