Raspberry Pi Pico(s_08)BMP280 用モジュール
BMP280 BMP280c.py
BMP280はデジタル温湿度センサーです。
BMP280はDIGITAL PRESSURE SENSORです。I2C通信で制御します。※詳細はBMP280のデータシートを参照ください。
Raspberry Pi PicoでBMP280センサーモジュールを使う自作の’BMP280c.py’を作成しました。記事d_10を元に作成しています。
使い方だけを記載します。’BMP280c.py’は末尾にあります。
使い方
■ファイル転送
Raspberry Pi Picoへ’BMP280c.py’を送った後でimportして使います。
※BMP280c.pyの末尾に、使用例(BMP280_ex.py)の## example以降をコピペ追加しても動作確認できます。
■メソッド
‘BMP280c’をimportすると「init_bmp280、reset_bmp280、para_bmp280、measure_bmp280、
id_bmp280、sleep_bmp280」のメソッドが使えるようになります。
BMP280(num=1,sda=10)で初期化します。
num:I2C0、I2C1の番号、デフォルトは1(I2C1)
sda:SDAのGPIO番号、デフォルトは10(GP10)
(01)init_bmp280()
ctrl_measレジスタ(0xF4)に’0x27’(oversampling ×1、power mode ノーマル)
configレジスタ(0xF5)に’0x52’(standby time 1000msec、IIR filter Filter無し、SPI not use)
を設定します。
(02)reset_bmp280()
レジスタをリセットします。
(03)measure_bmp280()
測定した温度、湿度をリストで返します。
(04)para_bmp280()
符号計算した補償用のデータ(digT,digP)をリストで返します。
(05)id_bmp280()
デバイスのID値を返します。
(06)sleep_bmp280()
スリープモードにします。
※詳細はBMP280のデータシートを参照ください。
使用例
BMP280で温湿度を測定します。
スレーブアドレス、ID値、補償用データ、温度、湿度をThonnyのShellに表示します。
BMP280c_ex.py
#!/usr/bin/env python
# -*- coding: utf-8 -*
from machine import I2C,Pin
import time
# BMP280 DIGITAL PRESSURE SENSOR / BOSCH
from BMP280c import BMP280
## exapmle -----------------------------------------
# instance BMP280(I2C_num,sda)
a=BMP280(1,10)
# address check
adr=a.i2c.scan()
print(adr, hex(adr[0])) # [118] 0x76
## bmp280_ID register IDを表示
id=a.id_bmp280()
print('ID=',hex(id[0]))
## calibration data(Trimming parameter) を表示
T,P=a.para_bmp280()
print('digT',T)
print('digP',P)
## reset BMP280 リセット
a.reset_bmp280() # added line
#BME280の初期化
a.init_bmp280()
## pressure and temperature
t,p= a.measure_bmp280()
print('t=',t)
print('p=',p)
実行結果
実行すると以下のようになりました。※Thonnyのshellに表示されます。
>>> %Run -c $EDITOR_CONTENT
[118] 0x76
ID= 0x58
digT [27981, 26705, -1000]
digP [37717, -10811, 3024, 2557, 124, -7, 15500, -14600, 6000]
t= 23.13 #温度
p= 1017.473 #湿度
一度、実行するとThonnyのShellでも操作できます。
>>> a.measure_bmp280()
(23.11, 1017.528) #温度、湿度
BMP280用モジュール
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from machine import I2C,Pin
import time
# pico_bmp280_class_01pyからからモジュールに
# BMP280 DIGITAL PRESSURE SENSOR / BOSCH
class BMP280:
def __init__(self,num=1,sda=10):
# BMP280 DIGITAL PRESSURE SENSOR / BOSCH
#slave address
self.addr=0x76 # [118] 0x76
self.i2c=I2C(num, scl=Pin(sda+1), sda=Pin(sda), freq=100_000)
#self.i2c=I2C(1, scl=Pin(11), sda=Pin(10), freq=100_000)
#t_fine carries fine temperature as global value
self.t_fine = 0.0
#Compensation data
self.digT = [] # 補償用データ配列に保管
self.digP = []
## read out
# read start register set (yomidasu register address set)
def r_reg(self,dat):
buf=bytearray(1)
buf[0]=dat
self.i2c.writeto(self.addr,buf)
# data write resister/data
def w_reg(self,reg,dat):
buf=bytearray(2)
buf[0]=reg
buf[1]=dat
self.i2c.writeto(self.addr,buf)
# signed data fugo keisan 16bit
def sig(self,dat):
if dat >= (2**15):
dat=dat-(2**16)
return dat
# compensation parameter 補正データ読み込み
def para_bmp280(self):
## dig_T1~T3 0x88~0x8d 6byte
self.r_reg(0x88)
com_t=self.i2c.readfrom(self.addr,6) # dig_T1~T3 6byte
# 16bitデータに変換
for i in range(0,6,2):
self.digT.append((com_t[i+1] <<8) | (com_t[i])) # digT[0] unsigned
# dig_T2,T3(digT1,2) signed data->fugou keisan
for i in range(1,3):
self.digT[i]=self.sig(self.digT[i])
## dig_P1~P9 0x8E~0x9f 18byte
self.r_reg(0x8E)
com_p=self.i2c.readfrom(self.addr,18) # dig_P1~P9 6byte
#print(com_t)
# 16bitデータに変換
for i in range(0,18,2):
self.digP.append((com_p[i+1] <<8) | (com_p[i])) # digP[0] unsigned
# dig_P2~P9(digP1~P8) signed data->fugou keisan
for i in range(1,9):
self.digP[i]=self.sig(self.digP[i])
return self.digT,self.digP
## init 測定設定
def init_bmp280(self):
self.w_reg(0xF4,0x27) #Register 0xF4 “ctrl_meas”
self.w_reg(0xF5,0x52) #Register 0xF5 “config”
time.sleep_ms(10)
# reset
def reset_bmp280(self):
self.w_reg(0xe0,0xb6) #Register 0xE0 “reset”
time.sleep_ms(2)
# sleep
def sleep_bmp280(self):
self.w_reg(0xF4,0x24) #ctr_meas(0xF4) sleep 0b_00100100'0x24'
time.sleep_ms(2)
# BMP280_ID
def id_bmp280(self):
self.r_reg(0xD0) #Register 0xD0 “id”
self.dat=self.i2c.readfrom(self.addr,1) #
#print('ID=',hex(dat[0]))
return self.dat
# compensation formula
def bmp280_compensate_t(self,adc_T):
#global t_fine
var1 = ( ((adc_T>>3)-(self.digT[0]<<1)) * (self.digT[1]) ) >> 11
var2 = (( ( ((adc_T>>4)-(self.digT[0])) * ((adc_T>>4)-(self.digT[0])) ) >> 12) \
* (self.digT[2]))>> 14
self.t_fine = var1 + var2
t = (self.t_fine * 5 + 128) >> 8
t= t/100
#print(var1,var2,t_fine)
return t
def bmp280_compensate_p(self,adc_P):
#global t_fine
var1 = (self.t_fine)-128000
var2 = var1 * var1 * self.digP[5]
var2 = var2 + ((var1*self.digP[4])<<17)
var2 = var2 + ((self.digP[3])<<35)
var1 = ( (var1 * var1 * self.digP[2]) >>8 ) + ( (var1 * self.digP[1]) <<12 )
var1 = ( ( ((1)<<47) +var1 ) )*(self.digP[0])>>33
if var1 == 0:
return 0 # avoid exception caused by division by zero
p = 1048576 - adc_P
p = ( ( (p<<31)-var2 )*3125 )/var1 # p(float)
#print('p',p,type(p)) # p 6.7116e+09
p=int(p) # float >> int
#print('p',p,type(p)) # p 6711599104
var1 = (self.digP[8] * (p>>13) * (p>>13)) >> 25
var2 = (self.digP[7] * p) >>19
p = ( (p + var1 + var2) >>8) + (self.digP[6] <<4)
p = p / 256 / 100
return p
## 温度、気圧データ読込>>補償計算>>温度、気圧の値を返す
def (self):
## temp press data register
## 測定データ読み込み press_msb 0xF7~temp_xlsb 0xFC 3+3 6byte
self.r_reg(0xF7)
dat=self.i2c.readfrom(self.addr,6) # dig_P1~P9 6byte
#print('r_mdata=',dat)
#データ変換
dat_p = (dat[0] << 16 | dat[1] << 8 | dat[2]) >> 4 # 0xF7~0xF9 20bit
dat_t = (dat[3] << 16 | dat[4] << 8 | dat[5]) >> 4 # 0xFA~0xFC 20bit
#補正
tmp=self.bmp280_compensate_t(dat_t)
prs=self.bmp280_compensate_p(dat_p)
return tmp,prs