Let's use the SD card slot on the Arduino Ethernet Shield

◆Arduinoイーサーネットシールドに付属のSDカードスロット

 2007年秋、ついに登場したArduinoイーサーネットシールドを買いました。イーサーネットは問題なく使えるのですが、基板にはサポートされていないSDカードスロットが付いているんです。

 

 大胆にもこんな風にアピールされてしまうと気になって仕方ありません。そこで今回はイーサーネットではなく、Arduinoイーサーネットシールド上のSDカードスロットの話を書きます。

◆結線はどうなっているの?

 とりあえず何がどこにつながっているのかテスターで調べると、SPIで必要な端子はPIOに直結されていました。

CS - 6
DI - 8
CLK - 9
DO - 3

 この結線だとAVRのSPI機能を利用できません。PIOでSPIのプログラムを書けば動きそうですが、一つ大きな問題があります。SDカードは3.3Vで動作しますが、ArduinoのPIOは5Vです。うーん、これって基板を作ってからそのことに気がついてNOT SUPPORTEDシール扱いになったと思われます。

◆使えそうなソースコードを探してみる

 まぁ、回路の方は何とかするとして、SPI、それよりもSDカードのプロトコルを一から書くのは嫌なので使えそうなコードを探すことにします。ちょっとググるっとArduinoのフォーラムが引っ掛かりました。

 関連してこちらのブログも参考にさせて頂きました。

 このソースコードは使えそうです。早速ダウンロードしてソースを見ると、AVRのSPIを利用しているので、そこをPIOに書き換えれば何とかなりそうです。親切にも、5VのArduinoとSDカードを接続する分圧回路も掲載されていますのでそのまま使わせて頂く事にします。

◆イーサーネットシールドの分圧改造

 CS,DI,CLKの3端子をチプ抵抗で分圧します。以下のように各端子を3.3kで基板上のアースに半田付け。

 そして、6,8,9番のパターンをコネクターの根元からカットして1.8kを挿入します。

◆ソースの修正

 主な修正箇所は1バイトの送受信関数です。AVRにお任せしていた部分をPIOに変更しタイミングを調整しました。

/**
 * \ingroup sd_raw
 * Sends a raw byte to the memory card.
 *
 * \param[in] b The byte to sent.
 * \see sd_raw_rec_byte
 */
void sd_raw_send_byte(uint8_t b)
{
#ifndef PIO_SPI
    SPDR = b;
    /* wait for byte to be shifted out */
    while(!(SPSR & (1 << SPIF)));
    SPSR &= ~(1 << SPIF);
#else
    int i;

    for(i=8; 0!=i; i--){
        clk_low();
        delayMicroseconds(3);
        if(b & 0x80)
            di_hi();
        else
            di_low();
        clk_hi();
        delayMicroseconds(3);
        b <<= 1;
    }
    clk_low();
    di_low();
#endif
}


/**
 * \ingroup sd_raw
 * Receives a raw byte from the memory card.
 *
 * \returns The byte which should be read.
 * \see sd_raw_send_byte
 */
uint8_t sd_raw_rec_byte()
{
#ifndef PIO_SPI
    /* send dummy data for receiving some */
    SPDR = 0xff;
    while(!(SPSR & (1 << SPIF)));
    SPSR &= ~(1 << SPIF);
    return SPDR;
#else
    uint8_t r = 0;
    int i;
    
    /* send dummy data for receiving some */
    di_hi();
    for(i=8; 0!=i; i--){
        clk_low();
        delayMicroseconds(3);
        clk_hi();
        r <<= 1;
        r |= do_read();
        delayMicroseconds(3);
    }
    clk_low();
    di_low();

    return r;
#endif
}

 

 PIO用の修正コードとサンプルスケッチはここからダウンロードできます。
 The modified code download here.

if you have a trouble downloading, please type this url => http://www.geocities.jp/jun930/etc/SDcard.zip

 実行結果ですが、32MBのSDカードのサイズがそれっぽいので、SPIはうまく動いているみたいです。SDカードとイーサーネットを組み合わせると、すごく小さなWEBサーバができそうですよ。


Latest update at 2009/1/4