2014年12月3日水曜日

SDカードを読み書きしよう!(Arduino編)


おはようございます、今日はArduinoでSDカードを読み書きしようと思います。
ケータイ、スマホ、果てはデジカメ、ゲーム機などの外部記憶媒体としてSDカードはメジャーとも言えますね。最近ではmicroSDの16GBですら2000円あれば十分にお釣りがくるほど、メディアの単価も安くなりました。


上の写真のSDカードはかなり昔のSDカードです。今回はこれを読み書きしようと思います。



SDカードとマイコンボードを繋げて対話させるために、microSD→SD変換アダプタを1枚犠牲にして、SDカードをDIP化するアダプタを作ります。

お金があれば、こういうものを買うとレイアウトもすっきりして基板への実装サイズも融通が利くような形になりますが、本ブログではなるべく安価に、そして簡単にするためにmicroSD→SD変換アダプタを1枚使いました。

SDカードのピン配置はこのようになっています。(裏面)
カード裏面左上、斜めの切り欠きの下にあるピンが9番ピン、そこから左向きに数えて1,2,3,4,5,6,7,8番ピンが並びます。

各ピンの役割は以下の通りです。
No.   SDネイティブモード   SPIモード
9:   DAT2           
1:   DAT3            CS
2:   CMD             DI (MOSI)
3:   Vss1            Vss1 (Gnd)
4:   Vcc             Vcc (+V)
5:   CLK            SCLK (SCK)
6:   Vss2            Vss2 (Gnd)
7:   DAT0            DO (MISO)
8:   DAT1

上の表を見る限り、一般の民生用機器で使われているSDカードはSDネイティブモードを使用して通信しています。SDネイティブモードを使用するにはライセンスを購入しなければなりません、しかも年間2000ドルと(1ドル120円としても年間24万円)、ライセンス料も高価です。

本記事のような、趣味での電子工作に関してはライセンスを買ってネイティブモードを使用しても最終的な出来栄えには遜色がないどころか、高速化以外に何の利点もありません。

バカバカしくてやってられないので、馬鹿にならずにバカバカしくやる方法として、簡便なSPIモードを使います。
SPIモードというのは、Philips社が提唱したI2Cと双璧を成す、かの有名なMotorola(現フリースケール・セミコンダクタ)が開発したバス規格です、ただしI2Cと同様に、あくまでもマイコンシステム同士の接続のための規格なので、長距離伝送は出来ません(無理があります)。

まず、SD変換アダプタとピンヘッダをハンダ付けします。
上の写真ではピンヘッダの位置合わせをしています。


7,8番ピンは他のピンよりも気持ち狭めになっていますので、そこを狙ってハンダ付けがきちんと行えるようにピンヘッダを位置決めしてください。
ピンヘッダの支持部(黒いプラスチック部分)とSD変換アダプタの先端のヘリのプラスチック部分が平行になるように、位置合わせをしてみてくださいね。
SDアダプタ裏面のピンの間にある「桟」の上にピンヘッダが来るようにすると、うまく行きます。




今回の工作の最難関部分、ハンダ付けです。
位置が決まったら、ピンヘッダ部分がブレッドボードに挿せるように支持部のプラスチックを上下させて調整します。9番ピンは接触部分とピンヘッダがギリギリ重なるようにして、ハンダの表面張力を利用して半ばブリッジ気味に、右上部に隣接する7,8番ピンはもうしょうがないので、細心の注意を払ってブリッジしないように手早くハンダ付けしてみてください。
今回の動作確認には、超ミニサイズのブレッドボードを使いました。200円くらいです。


こんなに小さくて使えるのか、と疑問に思われる方もいらっしゃるかと思いますが、横が17列ありますので、ちゃんと28ピンのATMegaマイコンに加え、セラミック発振子を取り付けることが出来ちゃいます(*^-^*)



ブレッドボードに挿せたら、いよいよマイコンボードとの接続です。
SPI通信という、モトローラ社が開発したシリアルバスでSDカードと通信しますので、ピンの接続の流儀が若干異なります。

マイクロコントローラーに搭載されているUART(USARTとも。非同期シリアル通信)ではTXを相手側のRXに、RXは相手側のTXに、というようにクロスさせる必要がありますが、SPIバスではSS, MOSI, MISO, SCLKの4本で構成される端子をそれぞれのマイコンの同じ端子につなぐだけです。I2Cなんかもこの方式ですね。

要約すると
マイコン側    SDカード側
SS ------------ SS
MOSI ---------- MOSI
MISO ---------- MISO
SCLK ---------- SCLK

こんな感じで繋いだら取り敢えずOKです。
SDカードの電源電圧は、2.7-3.6Vと、狙ったようにArduinoの3v3端子を利用できるように設計されているので、Arduino Uno等であれば、POWER側の3v3端子をVccに直結してしまってOKだったりします。この状態で3日程度放置しても特にカードが壊れたり、ということが無かったので、これでいいという仮定で話を進めます。

Arduino Duemilanoveなど一部のArduinoボードでは、3v3端子から取れる電流が50mAだったりします。この場合は5V端子を利用して、抵抗分圧なり、レギュレーターを使うなりして、3.3Vを供給します。(読み書き時に100mAほど流れるそうなので)

Arduino IDEを起動して、
ファイル → スケッチの例 → SD → CardInfo を選択し、SDカードが読めるか試してみましょう。

スケッチを開くとコメント欄に配線の概略が載っていますので、まずはその通りにジャンプワイヤで配線してみてください。

配線が無事に済んだらCtrl+Uでコンパイルして、マイコンボードにCardInfoのスケッチを流し込みます。
SDカードを刺した状態でシリアルモニタを起動すると、SDカードの中身が覗けます。面倒なことはArduinoのSD.hライブラリが殆どやってくれます。楽ちん。




// 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
//const int chipSelect = 4;

const int chipSelect = 8;

スケッチ内で宣言されているconst int chipSelect = 4; となっているところを8に変更すると信号線の取り出しがArduinoの8~13番の範囲内で取り出せるようになります。
これと余ったユニバーサル基板を利用して、単機能なSDカードシールドが作れそうですね。

さて、これで何ができるか…考えてみるだけでも利用の幅は案外あります。
データロガーを作るときの記録媒体として使うのもよし、或いはSIPの様に誰が作っても高さがそれなりに一定になることから、基板側にピンソケットを付けてファミコンのカセットの様に交換できるようにしても面白いですね。液晶モジュールがあれば簡単なゲームをSDの差し替えで実現できそうです。
マイコンの中のEEPROM(1kBytes)には納まりきらないようなデータも格納できますので、自作ゲームの面データROM的な用途としても使えそうです。ハンダ付けの際にL字ピンヘッダを使うと高さを削減できます。

おまけ



0 件のコメント:

コメントを投稿