Raspberry PiでSPI通信できるようにする設定【ADコンバータMAX1118】
この記事では、Raspberry PiでSPI通信できるようにするまでの設定を紹介します。今回SPI通信でやりとりするデバイスとして、ADコンバータのMAX1118を使いました。また、Raspberry Pi zeroを使用しましたが、他のRaspberry Piでも構いません。SPIの設定は簡単ですのでぜひ挑戦なさってみてください。
▼ I2Cの設定方法はこちら
使うもの
Raspberry Pi
お好きなRaspberry Piをお使いください。
MAX1118
SPI通信のできるデバイスならなんでも構いませんが、ここではADコンバータのMAX1118を使いました。
▼ 秋月電子通商さんで購入可能です。 2chシリアル8ビットADコンバータMAX1118 - 秋月電子通商
MAX1118は、2チャネル、シリアル8ビットのADコンバータです。ADコンバータを使えばラズパイからアナログ電圧を自由に読み取ることが可能です。
▼ 写真の通りかなり小型です。
▼ I2C通信のADコンバータADS1115もおすすめ!
Raspberry PiとADコンバータMAX1118の配線
ADコンバータMAX1118の仕様
MAX1118ピン端子の役割は下図の通りです。
配線
次の表の通りRaspberry PiとMAX1118の配線を行いました。
MAX1118 | 名称 | 役割 | Pi接続先 |
---|---|---|---|
1 | Vdd | 正電源電圧 | +5V |
2 | Ch0 | アナログ電圧入力 | -- |
3 | Ch1 | アナログ電圧入力 | -- |
4 | GND | グランド | GND |
5 | (REF)I.C | リファレンス入力 | 3.3V |
6 | CNVST | 変換/スタート入力 | SPIO CS0 (GPIO 8) |
7 | DOUT | シリアルデータ出力 | SPIO MISO (GPIO 9) |
8 | SCLK | シリアルクロック | SPIO SCLK (GPIO 11) |
Raspberry Piでは、SPIで使われるCS・MOSI・MISO、SCLKがあらかじめGPIO8・GPIO10・GPIO9・GPIO11ピンに割り当てられているので注意しましょう。
リファレンス電圧とは?
ADコンバータでよく出てくるリファレンス電圧(Vref)について触れておきます。リファレンス電圧とはADコンバータにとっての基準電圧のことです。たとえば、8ビットの分解能を持っているMAX1118では、このリファレンス電圧を基準に256等分してアナログ電圧を読み取る仕様になってます。リファレンス電圧が3.3Vだとしたら、3.3÷256で約0.013Vの精度で電圧が読み取れる理屈になります。外部端子にリファレンス入力がない場合は、ADコンバータ内部で設けられているはずです。データシートで確認しておくと良いでしょう。
Raspberry PiでSPIを使えるようにするための設定
ここからはRaspberry PiでSPIを使えるようにする設定方法を紹介します。
Raspberry PiへSSHでログイン後、$ sudo raspi-config を実行します。下の画面で5番のInterfacing Optionsを選択。
▼ SSHでRaspberry Piを操作する方法
次にP4のSPIを選択します。
「Would you like the SPI interface to be enabled?」をYESにします。
以上です。たったこれだけの設定ですが、SPI通信が使えるようになりました。
PythonでSPI通信の設定
次に、PythonからもSPI通信ができるようにライブラリをインストールしておきます。Python 2.x系なら $ sudo pip install spidev で、Python 3.x系なら $ sudo pip3 install spidev でインストールします。その後 $ sudo reboot でRaspberry Piを再起動したら完了です。
MAX1118のデータ送受信のフォーマット
さて、Pythonプログラムを書く前にADコンバータMAX1118の仕様を確認しておきます。MAX1118のデータシートを確認すると、CNVST に送る信号を変えることよって CH0 と CH1 のどちらからデータを読むかを選択できるようになってます。また、Dout からはアナログ電圧(8bit)のデータを読み取ることが可能です。
CHO のフロー: CH1 のフロー:MAX1118データシートより MAX1118データシート - 秋月電子通商
ざっくりとこんな感じで通信してるんだなぁ、と頭に留めておく程度で構いません。難しい話は抜きで、ここからは実際にPythonでアナログ電圧を読み取ってみます。手を動かしていくうちに、SPI通信のイメージがつかめるはず。
Pythonでアナログ電圧を読み取ってみる
Pythonを使ってRaspberry Piでアナログ電圧を読み取ってみます。作業を簡単にするため、乾電池一本と抵抗で分圧した回路を用意しました。
抵抗で分圧された地点をADコンバータのCH0 と CH1 に接続して、それぞれの電圧をRaspberry Piで読み取ってみます。(GNDはRaspberry Piと共通に。)
次はADコンバータで電圧値を読み取るPythonのプログラムです。
# -*- coding: utf-8 -*-
import spidev
import time
import RPi.GPIO as GPIO
# MAX1118データシート
# http://akizukidenshi.com/download/ds/maxim/max111x.pdf
Vref = 3.335 # Raspberry Piの3.3V電源をテスターで実測
GPIO.setmode(GPIO.BCM)
GPIO.setup(8, GPIO.OUT) # CNVST
spi = spidev.SpiDev()
spi.open(0, 0) # bus0,cs0
spi.no_cs = True # CSを使わない
spi.max_speed_hz = 1000000 # 1MHz
spi.bits_per_word = 8
def sendCNVST(CH):
if CH == 0:
GPIO.output(8, GPIO.LOW)
GPIO.output(8, GPIO.HIGH)
GPIO.output(8, GPIO.LOW)
elif CH == 1:
GPIO.output(8, GPIO.LOW)
GPIO.output(8, GPIO.HIGH)
GPIO.output(8, GPIO.LOW)
GPIO.output(8, GPIO.HIGH)
GPIO.output(8, GPIO.LOW)
def getVolts():
adc = spi.xfer2([0x00])
return adc[0] / 255.0 * Vref
try:
while True:
sendCNVST(0)
v0 = getVolts()
time.sleep(0.1)
sendCNVST(1)
v1 = getVolts()
print("CH0: {:.3f}V".format(v0))
print("CH1: {:.3f}V".format(v1))
time.sleep(1.0)
except KeyboardInterrupt:
spi.close()
GPIO.cleanup()
行数は少なく、簡単そうに見えます。spi.xfer2 を疑問に思った方、 【Raspberry Pi】spi.xfer2関数の使い方を徹底解説 で詳しく解説してますので合わせてご覧ください。
注意点を述べておきます。 MAX1118 ではCS端子を直接操作したいので、上のプログラムでは spi.no_cs = True のようにCSを使わない設定をしてます。こうしないと GPIO.output(8, GPIO.LOW) のように出来なくなるので注意が必要です。
下図は実際にプログラムを実行した結果です。テスターで測った電圧と1/100以上の精度で一致してましたから、なかなかすごい精度です。
▼ MAX1118を使って音に反応するセンサを作ってみた
▼ 8ch、10bitADコンバータMCP3008(SPI通信)