マイクロビット(c_17)BMP280 用モジュール
BMP280(I2C) BMP280_c.py
GY-BMP280-3.3大気圧センサーモジュール(以下、BMP280)は温度と気圧が測定できるセンサです。
※詳細はデータシートを参照ください。
BMP280センサーモジュールで使う自作の’BMP280_c.py’を作成しました。使い方だけを記載します。
‘BMP280_c.py’は末尾にあります。(※記事e_043を元にクラスにしました。)
‘BMP280_c.py’は末尾にあります。使い方だけを記載します。
使い方
ファイル転送
micro:bitへ’BMP280_c.py’を送った後でimportして使います。micro:bitに直接ファイルをアップロード出来ない場合(Thonny 3.1.12など)は、microfsなどを使ってアップロードします。
※microfsについては、当サイト内のこちらを参照ください。
※ファイルシステムへ送って使わないとメモリーエラーになると思います。(micro:bit V1)
メソッド
‘BMP280_c’をimportすると「init_BMP280, read_Trimming, read_BMP280」のメソッドが使えるようになります。
BMP280()で初期化します。
(01)init_BMP280
初期設定します。今回は次のように設定されます。
※t_sb、filter・・osrs_tなど記号の内容はデータシートを参照ください。
config(0xF5)には以下の条件0b1010010('0x52')を設定しています。
t_sb 101 standby time 1000msec(1sec)
filter 001 IIR filter Filter無
spi(en) x0 spi not use
ctr_meas(0xF4)には以下の条件0b00100111('0x27')を設定しています。
osrs_t 001 oversampling ×1 16 bit / 0.0050 °C
osrs_p 001 oversampling ×1 16 bit / 2.62 Pa (Ultra low power)
mode 11 power mode ノーマル
(02)read_Trimming()
Trimming parameterを読み出します。
dig_T,dig_Pのリストデータを返します。測定前に一度は実行する必要があります。
(03)read_BMP280
測定した温度、気圧を返します。
使用例
温度、気圧を測定します。
BMP280_ex.py
from microbit import i2c
from BMP280_c import BMP280
# Digital Pressure Sensor BMP280
## example ------------------
#i2c.init(freq=100000, sda=pin20, scl=pin19)
i2c.init()
#
a=BMP280()
##BME280の初期化(測定モード)
a.init_BMP280()
# Trimming parameter read
r_digT,r_digP=a.read_Trimming()
#
##測定データの読込>>表示出力
t,p=a.read_BMP280()
print('temp =',t,'C')
print('press=',p,'hPa')
実行結果
>>> %Run BMP280_ex.py
temp = 30.72 C
press= 1007.23 hPa
>>>
BMP280 用モジュール
BMP280M_c.py
from microbit import i2c
# Digital Pressure Sensor BMP280
class BMP280:
def __init__(self):
# org bmp280_test06_get_compdat.py
self.addr=0x76
#Compensation
self.t_fine = 0.0
#Compensation data
self.digT = [] # 補償用データ配列に保管
self.digP = []
# 開始アドレス設定
def r_reg(self,dat):
buf=bytearray(1)
buf[0]=dat
i2c.write(self.addr,buf)
# 符号付き計算
def sig(self,dat):
if dat >= (2**15):
dat=dat-(2**16)
return dat
## Trimming parameter readout ---------------------------
def read_Trimming(self):
### read trimming parameter
## dig_T1~T3 0x88~0x8d 6byte
self.r_reg(0x88)
com_t=i2c.read(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 signed data
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=i2c.read(self.addr,18) # dig_P1~P9 6byte
# 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 signed data
for i in range(1,9):
self.digP[i]=self.sig(self.digP[i])
# parameter readout
return self.digT,self.digP
## Temp,Press -------------------------
# data write resister/data
def w_reg(self,reg,dat):
buf=bytearray(2)
buf[0]=reg
buf[1]=dat
i2c.write(self.addr,buf)
#BME280の測定モード設定
## mes_init ctr_meas(0xF4)'0x27'config(0xF5)'0x52'
def init_BMP280(self):
self.w_reg(0xF4,0x27)
self.w_reg(0xF5,0x52) #'0xa0 machigai'
# 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,self.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 read_BMP280(self):
## temp press data register
## 測定データ読み込み press_msb 0xF7~temp_xlsb 0xFC 3+3 6byte
self.r_reg(0xF7)
dat=i2c.read(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)
#表示
#print('t = ' + str(tmp))
#print('p = ' + str(prs))
return tmp,prs