Arduinoに外部接続して使えるセンサーやディスプレイなどのデバイスはいろいろとあります。
そしてそれら周辺デバイスとのデータのやり取りを行う通信方式には主にUARTやI2C、SPIが使われます。
シリアル通信となるUARTは、送信ラインTXと受信ラインRXの2本の信号線のみでデータのやり取りを行うことができ比較的簡単に扱えることからArduinoなどマイコンボードではよく使われる通信方式です。
Arduinoではボードへのスケッチの書き込みやシリアルモニタの表示などでも使われています。
Arduinoでよく使われるBluetoothモジュールを使った作例もご紹介しました。
またArduino入門編記事として、RTC(リアルタイムクロック)からの時間の取得やLCDディスプレイに文字を表示させる方法としてI2C通信を使った作例もご紹介しました。
そして今回はSPI通信について見ていきたいと思います。
SPIとは「Serial Peripheral Interface」の略となりますが、上記I2C通信などと同様にArduinoなどのマイコンボードと周辺デバイス間(またはArduino間)での短距離通信で使われる通信の一種となります。
上記記事のLCDモニターを表示させる作例ではI2C通信を使いました。
パラレル方式の接続に対してI2C通信を使えば非常に少ない信号線(SCL/SDAの2本)でArduinoとデータのやり取りが出来ました。
SPI通信はI2C通信の時と同様に接続したデバイスとのデータのやり取りで使う信号線が少なく、またI2C通信と比べ高速でやり取りを行うことが出来ます。
I2C通信では接続したデバイス(センサーやディスプレイなど)を制御する【マスター(Arduinoにあたります)】とそのマスターからの命令によって制御される【スレーブ】に分かれていました。
制御するマスターとなるArduinoに対して複数のスレーブを少ない信号線で接続し制御する事が出来るというものです。
そしてSPI通信でも同様に行うことが出来ます。
I2C通信ではマスター(制御側)に繋がっている複数(または単一)のスレーブは、それぞれ個別のアドレス(I2Cアドレス)によって選択されています。
対してSPI通信ではスレーブはこのようなアドレスを持っていませんが、物理的な接続(SS:Slave Select)によって通信する相手を指定しています。
今回はこのSPI通信の基礎を見ていきたいと思います。
目次
【Arduino】SPI通信の基礎知識
今回の目的
以前このようなArduinoを使ったロボットカーを製作しました。
ご要望を何件か頂いたので3Dプリントパーツを公開しブログ記事としてまとめました。
Arduino Uno・L298Nモータードライバ・DCモーター・超音波センサーHC-SR04というシンプルな構成の小型ロボットカーとなります。
自動運転により勝手に部屋中を動き回る可愛いロボットとなりますが、このロボットカーにラジコンの機能も持たせようと考え追加でnRF24L01という無線モジュールを使いもう1台のArduinoをコントローラーとし無線操作出来るようにしてみました。
送信機となるもう1台のArduinoを用意し、Arduino間の無線通信によるラジコン化ということですね!
Arduino間での無線モジュールを使ったやり取りは面白く、電子工作で作った製作物を操作する場合に便利に使えます。
無線モジュールを使いArduino間でデータの送受信を行っていますが、送信側・受信側それぞれのArduinoに繋がれた無線モジュールとArduino間ではSPI通信によるデータのやり取りを行っています。
Arduino入門編記事としてArduinoなどのマイコンボードでよく使われる通信方式の一つとなるSPI通信についての基礎を理解することを今回の目的としたいと思います。
SPI通信とは?
SPIとは、シリアル・ペリフェラル・インターフェース(Serial Peripheral Interface)の略となり、マイコン内部で使われるデバイス同士を接続するためのバスとなります。
パラレル接続と比べて接続する信号線の数が少なくてすむシリアルバスの一種となり、比較的低速なデータ転送を行うデバイスに利用されます。
I2C通信と同様に少ない信号線でのデータのやり取りを行うことが出来る通信方式となります。
以前ご紹介したI2C通信によるLCDディスプレイ表示の例では、パラレル接続では非常に多くの信号線の接続が必要でしたが、同様なことをI2C通信による接続で行えば2本の信号線のみ(Vcc/GNDを入れると4本)で完結させることが出来ました。
同様にSPI通信でも少ない信号線のみでデータのやり取りを行うことが出来ます。
I2C通信には2本の信号線、SCLとSDAを使って通信しました。
またUART通信ではTX/RXの2本を使います。
SPI通信では4本の信号線(SCK/MOSI/MISO/SS)で構成されています。
そしてI2C通信同様に、Arduinoと単一あるいは複数のデバイスを接続して通信することができます。
Arduinoを使った電子工作で使うセンサーやディスプレイ・その他モジュールなど接続するデバイスがI2C接続に対応したものならI2Cで接続し、SPI接続に対応したものならSPIで接続して使う・・・そんな感じで理解して頂ければArduino入門編記事として読んで頂くには十分だと思います。
例えば同じ形状のディスプレイにもI2C接続に対応したものやSPI接続に対応したものがあります。
SPI接続の方が描画速度(通信速度)が早いなどの違いはあるようですが・・・このあたりは用途により使い分けるといった感じになるかと思います。
あまり話を掘り下げてしまうとクロック信号での同期など話が少し難しくなってしまい、入門編記事としては分かりにくく面白くなくなってしまうので、今回はArduinoを使ったSPI通信の概要を理解する事を目的に話を進めていきます。
SPI通信で使う信号線
SPI通信では先述のように4本の信号線を使ってデータのやり取りを行う通信方式だという事は雰囲気伝わったかと思います。
SPI通信で使う4つの信号線についてまず詳しく見ていきます。
SPI通信は、SCK(Serial Clock)・MISO(Master IN Slave Out)・MOSI(Master Out Slave In)・SS(Slave Select)の4つの信号線を使いArduinoと接続したデバイスとのデータのやり取りを行う通信方式となります。
頭文字を取っていますが、簡単な英語なので分かりやすいと思います。
マスターとなるArduinoにデータが入ってくるのか出ていくのかという信号の向きを表しています。
そして下記接続図がSPI接続の基本となります。
制御する端末[マスター](こちらではArduinoとなります)と、そのマスターとデータのやり取りを行うSPI接続に対応したデバイス[スレーブ]との接続です。
1つのマスター(Arduino)に対して単一または複数のスレーブと接続してやり取りを行うことが出来ます。
このあたりはI2C通信の時と同様ですね。
制御する側となるArduino(マスター)が権限を持っていて、それに接続したセンサーなどのデバイスを制御するといったイメージとなります。
信号線 | 用途 |
SCK(Serial Clock) | データ転送同期用のクロック信号 |
MISO(Master IN Slave Out) | スレーブからマスターへのライン |
MOSI(Master Out Slave In) | マスターからスレーブへのライン |
SS(Slave Select) | スレーブデバイスの選択 |
I2C通信と大きく違うところは、I2C通信ではスレーブとなる各デバイスはそれぞれアドレス(I2Cアドレス)を持っていてこのアドレスを変えることにより複数デバイスを認識し制御していました。
これに対しSPI通信ではスレーブはアドレスを持たず、個別の物理的な信号線SS(Slave Select)を使い制御する形となります。
マスターは通信したい相手をこのSSピンを使って選択し、通信相手として指定されていない他のスレーブはマスタから届いた信号を無視するように振る舞います。
具体的には、SSピンをLOWにするとマスターとのやり取り(通信)が有効となります。
複数のスレーブ端末が存在する場合、SSピンがHIGHになっているデバイスはマスターからのデータを無視するように振る舞います。
これにより複数接続されたSPIデバイスとのデータのやり取りに3本の信号線(SCK/MISO/MOSI)を共有して使うことが出来るようになっています。
I2C通信がアドレスを指定してスレーブとのやり取りを行うのに対して、SPI通信では物理的に接続されたSSピンにより通信する相手を選ぶということですね。
各SPIピンの役割は、MISO(Master IN Slave Out)がスレーブからマスタへのデータ送信・MOSI(Master Out Slave In)がマスタからスレーブへのデータ送信・SCK(Serial Clock)がマスタとスレーブを同期させるためのクロック信号・そしてSS(Slave Select)によりどのデバイスと通信するかを決めています。
上記の接続では1対1でのやり取りでしたが、複数のスレーブ(デバイス)と接続してやり取りする場合、SSピン(Slave Select)で複数のスレーブを制御するのがSPI通信での特徴となります。
MISO・MOSI・SCKの3本の信号線に複数のSPI対応デバイスを接続し、SSピンによりマスターはどのデバイスと通信するかを決めているということです。
複数デバイスを接続する際はそのデバイスごとにSSピンが必要となってきます。(HIGH or LOWで識別しているのため)
Arduinoと接続する場合では、MISO/MOSI/SCKの3本の信号線と接続するスレーブデバイスの数だけSSピンを用意する必要があります。(Arduinoのデジタル端子を使います)
ArduinoはSPI通信で使えるデジタルピンがボードによって決まっている
制御の権限を持ったマスターが接続されたSS(Slave Select)ピンを使いスレーブ端末を選択するというSPI通信の基本が何となく分かってきたところでその接続方法です。
ArduinoでSPI通信を利用する場合、標準で用意されているSPIライブラリ(SPI.h)を使うのが最も簡単です。
Arduino標準ライブラリとなるSPIライブラリを使うことを前提で話を進めていきます。
ArduinoのSPIライブラリを利用する場合、ArduinoのSPI通信に使える端子はボードごとに決まっています。
基本的にSS(Slave Select)以外のピンは変更ができません!
まずArduino Unoの場合SPI通信に使える端子は、デジタルピンD10がSS(Slave Select)、D11番がMOSI(Master Out Slave In)、D12がMISO(Master IN Slave Out)、D13がSCK(Serial Clock)となっています。
SPI通信を行う場合、このデジタルピンD11~D13とSSとして使用する端子D10は通常のデジタル入出力ピンとして使用できなくなります。
またArduino UnoにはICSP端子というものが付いています。
これは主にArduino Unoの頭脳にあたるマイコンチップ(ATmega328P)にブートローダーを書き込む用途で使われる端子です。
このICSP端子もSPI接続で使うことが出来ます。
他のArduinoボードで使えるSPIピンも少し見ておきます。
Arduino Nanoの場合ですが、SPIピンはこのように割り振られています。
ピン番号自体はArduino Unoと同じですね!
またArduino Megaの場合は、D50(MISO)/D51(MOSI)/D52(SCK)/D53(SS)このようになっています。
Arduinoボードは他にも多数あります。
ボードごとにSPIで使える端子が異なっているので、他のボードで利用する場合は公式サイトで仕様を確認して下さい!
使用できる端子はボードごとに異なっているので注意が必要です!
Arduinoとの接続例
ここまででSPIについての基礎部分は理解できたかと思います。
それではSPIに対応したデバイスとの接続方法ですが、もう簡単ですね!
先述のようにArduinoではSPI接続で使えるSPIピンはボードによって決まっています。
SPIデバイスの対応した端子をArduinoに接続するだけです。
Arduino Unoではこのような接続ですね。
実際にはデバイスを駆動するための電源(VCC/GND)の接続も必要となってきます。
3.3V駆動のデバイスならArduinoの[3.3V]端子に接続、5V駆動のデバイスなら[5V]端子に接続するといった感じですね。
そしてArduino入門編記事ではこれまで毎回簡単な作例としてテストスケッチをご紹介し実際に動かして確認できるようにしてきたので、今回もSPI接続での簡単な作例をご紹介したかったのですが・・・
I2CやUARTでの接続では、Arduino同士を繋いだデータのやり取りなど簡単な作例を試すことが出来るのですが、「SPI.hライブラリ」はArduinoをマスターとして使うように設計されているようで、スレーブとして動かす機能がほとんどないようです。
Arduino同士をSPI接続で繋げてデータのやり取りを行う・・・なんてことをご紹介しようかと思ったのですが、入門編記事としては逆に分かりづらくなってしまいます。
ArduinoにSPI接続して使えるデバイスは多数あります。
これまでブログ記事としてご紹介したものでは、nRF24L01という無線モジュールがあります。
非常に便利な無線モジュールなので、私はArduinoとセットでよく使っています。
簡単にこのモジュールとの接続を例に見ていきたいと思います。
nRF24L01モジュールの接続端子はこのようになっています。
SPI接続で使えるモジュールなので、SS(CE/CES)・MISO・MOSI・SCKといった配置となっています。
SPIでの接続なのでArduinoの対応した端子と接続するだけです。
例えばArduino Unoとの接続はこのようになります。
先述のようにArduinoのSPI接続で使える端子はボードによって決まっています。
それぞれ対応した端子に接続するだけなので簡単ですね!
入門編記事としては、ArduinoではSPI接続で使える端子がボードごとに決まっていることや、SPIでの接続には信号線としてSS/MISO/MOSI/SCKを使った接続となるのが分かれば今回の目的は達成です!
実際のスケッチ等はこちらの記事を参考にして下さい!
Arduinoと接続して使えるSPI対応デバイスは他にもいろいろとあります。
Arduinoを使ったSPI通信では基本的にArduinoをマスタとしたスレーブデバイスとの接続で使うことが多いと思います。
SPI通信で使う4つの信号線とその概要が分かっていれば、あとはデータ受け渡しのタイミング等難しくなってくる部分は全てライブラリ側が行ってくれるのであまり難しい事を考える必要がなく扱うことが出来ると思います。
今回のポイント
- SPI通信ではMISO/MOSI/SCKの3本の信号線と接続するデバイス(スレーブ)の数だけSSピンを用意する必要がある!
- SPI通信では接続するデバイス(スレーブ)の選択は、SS(Slave Select)端子を使って行っている!
- Arduinoで使えるSPI端子はボードごとに異なっているので注意が必要!
今回使ったアイテム
Arduino UNO
Arduinoはオープンソースハードウェアなので正規品以外にも互換品が多数販売されています。
互換品でも正規品と比べて特に問題なく使用でき安価なためArduino学習用としていいと思います。
Elegoo製のArduinoボードは、互換ボードの中でも非常にクオリティーが高く本家ボードと遜色なく使えるのでおすすめです!
Arduino スターターキット
これからArduino学習を進めていくにあたりArduino UNO(互換品)やブレッドボード、ジャンパーピンなどがセットになったスターターキットが販売されています。
私はGeekcreit製のスターターキットを使っていますが、ELEGOO製のものは国内Amazonなどでも購入可能で人気があるようです。(セット内容はほぼ同じです!)
そしてELEGOOのサイトからスターターキット用サンプルスケッチのダウンロードも可能です。(Geekcreitのキットでも使えます)
参考 チュートリアルダウンロードELEGOO基本的にこれからこのセットで出来るものから紹介していこうと考えていますが、かなり多くのことが出来ます。
電子工作を始めるにはまずブレッドボードやジャンパーピン、メインとなるArduino UNOやサーボ、LEDなどの基本的なパーツがないと実際に動かすことが出来ませんが、個々にパーツを購入して回路を組んでとなるとかなりの手間がかかります。
スターターキットがあればArduinoの初歩的なことはかなりの数こなすことが出来るのでオススメです!
そこからスキルアップに伴い個別でセンサーやモジュールなど必要なものを増やしていくのがいいと思います。
最近の半導体不足による価格高騰によりArduinoボードも以前と比べ非常に割高感があります。
上記Elegoo製Arduino互換ボードも私が購入していた時より倍近くの価格まで高騰しているようです。
これからArduinoを始めてみようとお考えの方は、価格的にもお得感があるArduinoスターターキットから始めてみるのがいいかと思います。
最後に!
UARTやI2C、そしてSPIはArduinoではよく使われる通信方式になります。
ArduinoとSPIで接続できるデバイスは多数ありますが、基本的にArduinoにはそれらを利用する際に使えるライブラリが用意されています。
SPI接続についての基本的な概要が理解出来ていれば、それら専用ライブラリを使うことにより内部で行われている難しいことをあまり意識することなく扱うことが出来ると思います。
今回はArduinoでSPI接続をするための基礎知識をご紹介しました。
コメントを残す