ラズパイ研究室

GPIO SPIのテスト

今回は、部品ケースに眠っていた、ADコンバータ(MCP3204)とサーミスタでSPI経由の温度測定を実験します。

Raspberrpi SPIのドキュメントはこちら

回路図です

基準電圧(Vref)にはTL431を使い精度を上げています。

サーミスタの温度変換式

T = 1 / ( log(Rth/R0 ) * 1/B +1/T0 ) - 273.15

MCP3204 ADコンバータ

MCP3204はSPIインターフェースの4chのADコンバータです。

主な仕様

電源電圧:2.7V~5.5V

分解能:12ビット

入力 :シングルエンド、疑似差動

変換方式:SAR(逐次比較)方式

サンプリング・レート:100ksps

データシートによると、[ 0x06 0x00 0x00 ]の3バイトを送るとCH0の3バイトのデータが返ってきます

  

pythonでテスト

新しく作ったユーザーでログインします。

raspi-config でspiを有効にします。

 

spiが有効になっているか確認

$ls /dev/spi*

/dev/spidev0.0 /dev/spidev0.1

$lsmod | grep spi

spidev 20480 2
spi_bcm2835 20480 0

SPI関連はルート権限が必要なので、spiグループに追加してsudoしなくても動作するようにします。

グループの追加

$sudo gpasswd -a piadmin spi

ターミナルを閉じて再ログインして確認

$groups

piadmin audio spi

ライブラリは、デフォルトでインストール済みのspi-devを使います

MCP3204は 0x06 0x00 0x00 の3バイトを送ると3バイトのデータが返ってきます。そのうち12ビットが有効データとなります。

簡単なテストコード

 
import spidev

spi = spidev.SpiDev()
spi.open(0,0)
while 1:
  ad = spi.xfer([ 0x06, 0x0, 0x0])
  data = ((ad[1] & 0x0F) << 8) | ad[2]         
  print(data)
                

トラブル発生

10Kと10Kなので約半分の値が返ってくるはずですが、値がゼロ。

結線を何度も確認しましたが、間違っていないようです。

gpiozeroにMCP3204のクラスがあるので、変更すると正常動作しました。

gpiozeroもデフォルトで入っています。

from gpiozero import MCP3204
import time

while 1:
  adc = MCP3204(channel=0)
  print(adc)
  time.sleep(1)
     

mcp3204シリーズを使うにはgpiozeroは非常に便利ですが、SPI-devが動作しないのは腑に落ちないので色々調べたところ

以下のことが判明しました。

1.Jessie (Raspberian 8)では動作する。

2.Strech(raspberian 9.0)以降では、spi.max_speed_hz を記述しないと動作しない。

 

正常動作が確認できた、spi-devを使ったサーミスタ温度計測のコードはこちらです。

#!/usr/bin/env python
# coding: utf-8
# 3.3V --10K -- Thermista --GND
import spidev
import math
import time
  
spi = spidev.SpiDev()
spi.open(0,0)
spi.max_speed_hz = 40 * 1000
  
Vdd = 3.3
Vref=2.495
R0 = 10000
B  = 3235
T0 = 298.15
    
def adc():
  
  sd  = spi.xfer2([ 0x06, 0x0, 0])
  adc = ((sd[1] &0x0F ) << 8) | sd[2]
  return adc
  
while 1:
  Vo = ( adc() / 4096.0 ) * Vref
  Rth = Vo /(Vdd-Vo) * R0
  t= 1 / ( math.log(Rth/R0 ) * 1/B +1/T0  ) -  273.15
  print ('{:.2f}'.format( t ) )
  time.sleep(1)