raspberypi3 b+でmcp3208のSPIが使えない 解決方法

raspberypi3 b+でmcp3208のSPIが使えない
mcp3208からSPIでLM35の温度を取り出すコード

raspberyPi3 Bで作成したSPIDEVでLM35から電圧(温度)
を取り出している(ソースA)

同じソースをraspberypi3 b+で実行しようとすると
mcp3208の12ビットモードでSPIが使えない現象が発生
raspberyPi3 Bでは0が帰ってくる

gpiozeroを使うとデータが帰ってくる(ソースB)

ls -la /dev/spidev*でライブラリを見ると
0.0と0.1が存在している

ネットをググって見ると結構混乱しておりOSがハードの
差を吸収していない様子

Raspvian 9.4 stretch 2018/08/19現在

(ソースA)
import spidev
import time
import sys
spi= spidev.SpiDev()
spi.open(0,0)
def  adc_read12(ch):
    r = spi.xfer2([4|2|(ch >> 2), (ch & 3) << 6,0])
    v=((r[1] & 0xF) << 8 ) + r[2]
    return v
def conv_volts(data,places):
    volts = (data *3.3)/float(4096)
    volts=round(volts,places)
    return volts
def conv_temp(volts,places):
    temp =  volts * 100 
    temp  =round(temp,places)
    return temp
while True:
    try:
        d=adc_read12(0)
        #print("adc  : {:8} ".format(d))
        v=conv_volts(d,4)
        #print("volts: {:8.2f}".format(v))
        t=conv_temp(v,4)
        print("temp : {:8.2f}".format(t))
        print("------------------------")
        time.sleep(1)
    except KeyboardInterrupt:
        break
spi.close()  

(ソースB)
from gpiozero import MCP3208
import time
Vref = 3.30
def conv_temp(volts,places):
    temp =  volts * 100 
    temp  =round(temp,places)
    return temp
 
while True:
    try:
        pot = MCP3208(channel=0)
        v=pot.value * Vref
        #print(str(pot.value * Vref) + "V")
        t=conv_temp(v,4)
        print("temp : {:8.2f}".format(t))
        time.sleep(1)
    except KeyboardInterrupt:
        break

解決方法

A案:SPI.openのあとにmax_speed_hzを記述する
 spi.open(0,0) spi.max_speed_hz =5000 #5khz
追記:
 データシートを見ると
 5Vで2Mhz
 2.7vで1Mhzなので

 spi.max_speed_hz =1000000 #1MHZ

 でテストするとこれでも動作OK 試しに2Mhzにすると電圧が低下した
 状態になる

 多チャンネルを使うときはレートを落とす必要があるので
 spi.max_speed_hz =200000 #200KHZあたりが適当かもしれな

 ちなみにRaspberrypi3Bは1.2GHZ 3B+は1.4GHzだがバスクロックも
 アップしたのだろうか?

B案:gpiozeroを使って書き換える
 from gpiozero import MCP3208

 pot = MCP3208(channel=0)   v=pot.value * Vref

カテゴリー iot