SPI通信は、マイコンと周辺部品の通信でよく使われるシリアル通信です。
ここでは、ArduinoとSDカードのSPI通信波形を実際に確認しながら、SPIの仕様についてまとめていきたいと思います。
この記事で使うシステムについては以下の記事でご紹介しています。
実際に作ってみたいという方は、是非一読していただけるとうれしいです!
準備するもの
この記事では、以下の物を使います。
●Arduino Uno
amazonのスイッチサイエンスから購入する純正のArduinoは、永久保証を受けることができます。
ブレッドボードや電子部品が付いてくるので、すぐに工作を始めることができます。
●LCDディスプレイ
16文字×2行を表示することができるLCDディスプレイです。
本来LCDディスプレイはパラレル信号を入力しないといけませんが、この商品はパラレル通信⇔I2C通信を変換してくれる回路が元から付いているので、I2C通信によるやりとりが可能です。
●CO2センサー
I2C通信で接続することができるCO2センサーです。
精度はそれほど信用できるものではありませんが、手軽にArduinoでCO2を計測することができます。
詳細な使い方は以下の公式HPで紹介されています。
https://wiki.keyestudio.com/KS0457_keyestudio_CCS811_Carbon_Dioxide_Air_Quality_Sensor
●マイクロSDカード シールド
SPI通信で接続することができるマイクロSDカードシールドです。
手軽にArduinoでSDカードとの連携をすることができます。
SDカードは3.3Vで動作しますがArduinoの電源は5Vなので、本来はそのまま接続するとSDカードが壊れてしまいます。
ですがこのシールドは5Vを3.3Vに変換するチップが付いているので、そのままArduinoと接続しても問題ありません。
●マイクロSDカード
一般的なマイクロSDカードです。
●ジャンパーワイヤー
LCDディスプレイやセンサーは端子がオスになっているので、各種ワイヤーを揃えておくと便利です。
●ロジックアナライザ
このロジックアナライザを使用すれば、UART、IIC、SPIなどのシリアル通信のデータを見ることができます。
●解析ソフト pluseview
上記のロジックアナライザのデータを見るために、pluseviewというフリーソフトを使用します。
https://sigrok.org/wiki/Downloads
以下のサイト様でインストール方法から使用方法まで詳細に説明されているので、参考にしてください。
SPI通信とは
Serial Peripheral Interfaceの略でシリアル通信の一つです。
SCLK(クロック)、CS(チップセレクト)、MOSI(マスターアウト・スレーブイン)、MISO(マスターイン・スレーブアウト)の4つの通信線で通信する仕様で、I2Cと比べて高速で通信することができますが、通信線が多くなってしまう特徴があります。
I2Cと同様に、上記の通信線を共有して複数の周辺部品と通信することができます。
ただし、CSで通信したいマイコンを指定してからそのマイコンと通信を開始する仕様上、CSだけは周辺機器の数だけ通信線が必要になってしまいます。
使用するスケッチ
ArduinoでCO2センサーから取得したデータを、SDカードに保存するスケッチを使用します。
ArduinoとSDカードの通信にSPI通信を使っているので、ここの通信を解析してみたいと思います。
スケッチの中で重要なところを抜粋してご紹介します。
const int chipSelect = 4;
ArduinoからSDカードへCS信号を出力するピンを4ピンに設定しています。
void loop() {
delay(1000);
// append to the string
dataString += String(sensor.getCO2PPM());
dataString += ",";
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
File dataFile = SD.open("datalog.txt", FILE_WRITE);
// if the file is available, write to it:
if (dataFile) {
dataFile.println(dataString);
dataFile.close();
メインループの中で、CO2センサーからI2Cでデータを受け取ってSDカードに書きこんでいます。
メインループの先頭で1秒のディレイを入れているので、1秒ごとにこの処理が繰り返されます。
SPI通信の仕様
上記のスケッチを実際に動かして取得したSPIの通信データを見てみましょう。
以下がその通信データです。
スケッチ通りに1秒間隔でなにやら通信をしているのが分かります。
一つの通信を拡大してみます。
SDカードにCS信号を入力している間、SCLKのタイミングに合わせてMOSIとMISOでデータをやり取りしているのが分かります。
通信シーケンス
通信するときのシーケンスは以下の通りです。
順番にSPIの仕様を見ていきたいと思います。
電圧
マイコンの電源電圧によって異なりますが、5Vや3.3Vがよく使われます。
CS(チップセレクト)
CSはプルアップされているので、何も通信をしていないときは常にHighの状態になっています。
マスターは通信したいスレーブに対してCS信号を出力(Low)します。
スレーブはCSにLowが入力されると通信動作を開始します。
CSはI2CやUARTでいうスタートビットの役割も果たしていますね。
通信データの確認
マスターからスレーブに対してCS信号が出力されているのが分かります。
CSがLowになるとSCLKやMOSI、MISOが動作を始めています。
このように電圧がHighのときを「0」「偽」の意味で使い、Lowのときを「1」「真」の意味で使うことを負論理(アクティブロー)といいます。
SCLK(クロック)
マスターはスレーブに対してCS信号を出力したあとに、クロック信号SCLKを出力します。
お互いにこのSCLK信号でタイミングを合わせて8bitデータを送受信します。
このようにクロックのタイミングに合わせて通信を行う方式を同期式通信といいます。
通信データの確認
マスターからスレーブに対してSCLK信号が出力されているのが分かります。
ここではクロックが立ち上がりのときに、MOSI、MISOの電圧がHighかLowかを読み取っていますね。
MOSI
マスターからスレーブに対してデータを送るときに使われます。
通信時に送られるデータは8ビットです。
通信データの確認
マスターから8bitのMOSI信号が出力されているのが分かります。
MOSIも何も通信していないときはHighになっていますね。
まずArduinoがSDカードに対してCSとSCLKを出力し、次に「0xFF」を出力しています。
これは、SDにCSを出力してからSDカードの準備が整うまでの時間を稼いでいるようです。
次に「0x51」を出力しています。
SDカードと通信するには、決められたルールを守る必要があります。
「0x51」はSDカードのメモリを1ブロック分読みだすコマンドを意味します。
MSBで1bit目は必ずスタートビットで「0」、2bit目はマスターからスレーブへのコマンドであることを意味する「1」、そして1ブロック分読み込むことを意味するコマンド「010001」をつなげて「0x51」というデータになっているわけです。
SPIは定められているルールがシンプルな分、それを利用する部品側でルールをしっかり定めておく必要があります。
MISO
スレーブからマスターに対してデータを送るときに使われます。
通信時に送られるデータは8ビットです。
SPIはマスターからスレーブにデータを送るMOSIと、スレーブからマスターにデータを送るMISOが用意されています。
よって、お互いの好きな時にデータを送っても通信が衝突することはありません。
このような通信方式を全二重方式といいます。
通信データの確認
スレーブからマスターに対して8bitのデータ「0x00」を出力しているのが分かります。
これはSDカードと通信するときのルールで、マスターから送られたコマンドに対するレスポンスになります。スレーブからマスターに「0x00」を送ることでコマンドを問題なく受け取れたことを伝えています。
マスターから1ブロックを読みだすコマンド「0x51」が送られているので、ここから512Byteのデータがスレーブから送られてきます。
まとめ
ArduinoとSDカードで無事にSPI通信ができていることが確認できました。
複雑な通信シーケンスのI2Cと比べて、SPI通信はとてもシンプルですね。
SDカードへデータをやり取りするときは、CO2センサの1回分の値(数Byte)でも毎回1ブロック(512Byte)単位でやり取りをしていました。
書き込む対象のブロック512Byteを一度読みだして、対象の数Byteだけを書き換えてもう一度SDに戻すということをしているので、少し贅沢な通信の使い方ですね。
通信の効率を上げるためには、一度Arduinoの中で512Byte分のデータが溜まるのを待ってから通信を行うなど工夫が必要そうです。
この辺りの話は今回の趣旨とは異なりますので、また機会があればご紹介してみたいと思います。
コメント