MCP3208の10と12ビット+I2CのADT7410同時使用 (I2Cの読込ビット説明)

ADT7410はI2Cで接続してsmbusを利用して通信する
前章でSPIを説明したので、I2Cを説明

・i2c = smbus.SMBus(1)
 バス番号を選択
 i2cツールで引数を0,1で検索してエラーにならない方で
sudo i2cdetect -y 1  (0か1 ラズパイのバージョンによる)

・adt7410_addr = 0x48
 センサーのアドレス I2Cツールで検索

・register7410 = 0x00
 読み出しレジスター

#I2Cの読込み
def read():
     datas = i2c.read_i2c_block_data(adt7410_addr,register7410,2)
     data = datas[0] << 8
     data = data | datas[1]
     data = data >> 3     
   if (data>= 4096):
        data = data – 8192 
     data = data /16.0
     return data

・I2c.read_i2c_block_data(adt7410_addr,register7410,2)
 アドレス0x48のレジスタ0から2バイト読みだし(13ビットだから)
 13ビットだからはじめの1バイト[0]に8ビット 次の[1]に8ビット
 セットされる(頭から13ビット分セット!)

 [b12b11b10b9b8b7b6b5] [b4b3b2b1b0???]

・data = datas[0] << 8
 datasにdatas[0]を8ビット左シフトしてセット
   b12b11b10b9b8b7b6b500000000

・data = data | datas[1] OR演算だから
 b12b11b10b9b8b7b6b5b4b3b2b1b0???

・ data = data >> 3   
 000b12b11b10b9b8b7b6b5b4b3b2b1b0

なおb12はマイナスフラグ
 データシートを見ると
 1/16=0.0625刻みだから
 -0.0625で 00011111 11111111  0x1FFF =8191
    +0.0625で 0000000 0000001   0X0001 =  1
   -55 で0x1290 = 7312
 +150で0x960 =  2400
 つまり0~2400はプラスで
 7312~8191はマイナス

この計算式では+の値だけになるので修正が必要
 if (data>= 4096):
      data = data – 8192
   data = data /16 

SPIとI2Cを同時に使用して
 アナログLM35温度センサーの値を10ビットと12ビット
 デジタル温度センサーADT7410のI2Cの測定値の比較をしてみた

 I2Cの有効化とsumbusの取り込み先に実施して

以下のソースで比較

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#sudo apt-get install python-spidev
import time
import sys
import spidev
import smbus

#I2Cの定義
i2c = smbus.SMBus(1)
adt7410_addr = 0x48
register7410 = 0x00

#SPIの定義
spi = spidev.SpiDev()
spi.open(0,0)

#SPIの10ビット読込
def readadc(adcnum):
    r = spi.xfer2([1, 8 + adcnum << 4, 0])
    adcout = ((r[1] & 3) << 8) + r[2]
    return adcout

#SPIの12ビット読込
def readadc12(adcnum):
    if adcnum > 7 or adcnum < 0:    
        return -1
    r = spi.xfer2([4 | 2 | (adcnum >> 2), (adcnum & 3) << 6, 0])
    adcout = ((r[1] & 15) << 8) + r[2]
    return adcout

#SPI10ビットのLM35のボルト
def convertVolts(data):
    volts = (data * 3.3) / 1023
    #volts = round(volts,4)
    return volts

#SPI12ビットのボルト
def convertVolts12(data):
    volts = (data * 3.3) / 4095
    #volts = round(volts,4)
    return volts

#温度補正
def convertTemp(volts):
    #temp = (100 * volts) - 50.0
    temp = volts * 100
    temp = round(temp,4)
    return temp

#I2Cの読込み
def read():
     datas = i2c.read_i2c_block_data(adt7410_addr,register7410,2)
     data = datas[0] << 8
     data = data | datas[1]
     data = data >> 3
     if (data>= 4096):
        data = data - 8192      
     data = data /16.0
     return data

if __name__ == '__main__':
    try:
        while True:
   #10ビット
            data = readadc(1)
            volts = convertVolts(data)
            temp = convertTemp(volts)
            print("temp10bit : {:8.2f}".format(temp))

   #12ビット
            data = readadc12(1)
            volts = convertVolts12(data)
            temp = convertTemp(volts)
            print("temp 12bit: {:8.2f}".format(temp))

   #I2C
            temp = read()
            print("temp I2C: {:8.2f}".format(temp))
            time.sleep(3)
    except KeyboardInterrupt:
        spi.close()
        sys.exit(0)
-----------------------------------------------------------------

結果は

temp10bit :    24.84
temp12bit:   24.90
temp I2C:     25.12

でした
カテゴリー iot