稼働中

マイクロビット(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