RaspberryPi PicoとBMP280(温湿気圧センサ)

VS Codeの使い勝手とMicroPythonどうなのよ。
ってことでPicoに足付けます。※ピンヘッダの向きは意図的です。

はんだ付け、もっとリハビリしないとダメですね。
撮影の都合上、Picoはブレッドボード上に載せてるだけです。

SDA:GP8 / SCL:GP9 / 3V3 / GND

MicroPythonでのI2C読み込みはBYTES型式で戻るので、前回の投稿からアクセス周り修正。
VS Codeだとソースに全角文字入ってた場合、実行時場所の分からないエラー出るので注意です。

Traceback (most recent call last):
File "<stdin>", line 1
SyntaxError: invalid syntax

タイミングがシビアになるのかな?BME280の初期化後、読込エラーが発生。
初期データ書き込み後にウェイト入れました。
コード内「ProtSensorData」使ってません。

from machine import I2C,Pin
import time

i2c_numb = 0
i2c_addr = 0x76
sda = Pin(8)
scl = Pin(9)
freq = 100000   # 100kHz
i2c = I2C(i2c_numb,sda=sda,scl=scl,freq=freq)

dev = i2c.scan()
if dev:
    for i in dev:
        print(hex(i))

digT = []
digP = []
digH = []

t_fine = 0.0
#--------------------------------------------------------------------------------
def readRegB(addr):
    dt = i2c.readfrom_mem(i2c_addr,addr,1)
    return  dt[0]
#--------------------------------------------------------------------------------
def readRegC(addr):
    ch = readRegB(addr)
    if(ch & 0x80):
        wd = (-ch ^ 0xFF)+1
    return  ch
#--------------------------------------------------------------------------------
def readRegW(addr):
    dt = i2c.readfrom_mem(i2c_addr,addr,2)
    return  dt[0] + (dt[1] << 8)
#--------------------------------------------------------------------------------
def readRegS(addr):
    wd = readRegW(addr)
    if(wd & 0x8000):
        wd = (-wd ^ 0xFFFF)+1
    return wd
#--------------------------------------------------------------------------------
def writeReg(addr,data):
    i2c.writeto_mem(i2c_addr,addr,data)
#--------------------------------------------------------------------------------
#   setup
#       ctrl_hum    : osrs_h[2-0]
#       ctrl_meas   : osrs_t[7-5] osrs_p[4-2] mode[1-0]
#       config      :   t_sb[7-5] filter[4-2] spi3w_en[0]
#--------------------------------------------------------------------------------
def setup():
    writeReg(0xF2,b'\x02')  # ---- |- 010
    writeReg(0xF4,b'\x4B')  # 010 0|10 11
    writeReg(0xF5,b'\xA0')  # 101 0|00 - 0
    time.sleep(0.1)
#--------------------------------------------------------------------------------
#   get_calib_param
#--------------------------------------------------------------------------------
def get_calib_param():
    #   T1 ~ T3
    digT.append(readRegW(0x88))
    digT.append(readRegS(0x8A))
    digT.append(readRegS(0x8C))
    #   P1 ~ P9
    digP.append(readRegW(0x8E))
    for i in range(0x90,0xA0,2):
        digP.append(readRegS(i))
    #   H1 ~ H6
    digH.append(readRegB(0xA1))
    digH.append(readRegS(0xE1))
    digH.append(readRegB(0xE3))
    e4 = readRegB(0xE4)
    e5 = readRegB(0xE5)
    e6 = readRegB(0xE6)
    digH.append((e4 << 4) | (e5 & 0x0F)) digH.append((e5 >> 4) | (e6 << 4))
    digH.append(readRegC(0xE7))
#--------------------------------------------------------------------------------
def ProtSensorData():
    print('Sensor data')
    offset = 0
    buf = i2c.readfrom_mem(i2c_addr,0x88,0xe8-0x88)
    for i in buf:
        if offset % 8 == 0:
            print('\n' + hex(0x88 + offset), end=': ')
        print('{0:02X} '.format(i), end='')
        offset = offset + 1
#--------------------------------------------------------------------------------
def compensate_T(adc_T):
    global t_fine
    v1 = (adc_T /  16384.0 - digT[0] / 1024.0) * digT[1]
    v2 = (adc_T / 131072.0 - digT[0] / 8192.0) * (adc_T / 131072.0 - digT[0] / 8192.0) * digT[2]
    t_fine = v1 + v2
    t = t_fine / 5120.0
    return t
#--------------------------------------------------------------------------------
def compensate_P(adc_P):
    global  t_fine
    p = 0.0

    v1 = (t_fine / 2.0) - 64000.0
    v2 = (((v1 / 4.0) * (v1 / 4.0)) / 2048) * digP[5]
    v2 = v2 + ((v1 * digP[4]) * 2.0)
    v2 = (v2 / 4.0) + (digP[3] * 65536.0)
    v1 = (((digP[2] * (((v1 / 4.0) * (v1 / 4.0)) / 8192)) / 8)  + ((digP[1] * v1) / 2.0)) / 262144
    v1 = ((32768 + v1) * digP[0]) / 32768

    if v1 == 0:
        return 0
    p = ((1048576 - adc_P) - (v2 / 4096)) * 3125
    if p < 0x80000000: p = (p * 2.0) / v1 else: p = (p / v1) * 2 v1 = (digP[8] * (((p / 8.0) * (p / 8.0)) / 8192.0)) / 4096 v2 = ((p / 4.0) * digP[7]) / 8192.0 p = p + ((v1 + v2 + digP[6]) / 16.0) return p / 100 #-------------------------------------------------------------------------------- def compensate_H(adc_H): global t_fine var_h = t_fine - 76800.0 if var_h != 0: var_h = (adc_H - (digH[3] * 64.0 + digH[4]/16384.0 * var_h)) var_h *= (digH[1] / 65536.0 * (1.0 + digH[5] / 67108864.0 * var_h * (1.0 + digH[2] / 67108864.0 * var_h))) else: return 0 var_h = var_h * (1.0 - digH[0] * var_h / 524288.0) if var_h > 100.0:   var_h = 100.0
    elif var_h <   0.0:   var_h =   0.0
    return var_h
#--------------------------------------------------------------------------------
def readData():
    dat = i2c.readfrom_mem(i2c_addr,0xF7,8)
    p_raw = (dat[0] << 12) | (dat[1] << 4) | (dat[2] >> 4)
    t_raw = (dat[3] << 12) | (dat[4] << 4) | (dat[5] >> 4)
    h_raw = (dat[6] <<  8) |  dat[7]

    t = compensate_T(t_raw)
    p = compensate_P(p_raw)
    h = compensate_H(h_raw)
    d = 0.81 * t + 0.01 * h * (0.99 * t - 14.3) + 46.3
    return [t,p,h,d]
#--------------------------------------------------------------------------------
setup()
get_calib_param()

if __name__ == '__main__':
    if readRegB(0xD0) == 0x60:  print("BME280")
    else:                       print("BMP280")

    dat = readData()
    print("T:%3.2f C"   % dat[0])
    print("P:%5.1f hPa" % dat[1])
    print("H:%3.2f %%"  % dat[2])
    print("D:%3.2f"     % dat[3])
#--------------------------------------------------------------------------------
#EOF

実行結果はこんな感じです。
(I2C addr,CHIP型番,温度,気圧,湿度,不快指数)

Runしてもレスポンス悪いタイミングが多々ありました。なんだろう。。
Picoに対応した各モジュールのライブラリ量、またはC/C++に走るか。
悩ましいところですね。

コメント

タイトルとURLをコピーしました