全然BLOGに手をつけてなく電子工作グダグダやってました。
流れ的にI2Cなので定番のBME280での温度・湿度・気圧測定です。
必要なもの一式組み込みます。(Python3ベース)
$ sudo apt-get -y install python3-dev $ sudo apt-get -y install python3-pip # pip3 入れる $ sudo apt-get -y install python3-gpiozero # pinout 使えるようにしてみる $ sudo apt-get -y install i2c-tools # pi OS(lite) には入ってないっぽい
モジュール[smbus2]入れます
$ pip3 install smbus2
BME280はデータシート見ながら&Python勉強。と
ソースぐちゃぐちゃですが貼り付けます。
#--------------------------------------------------------------------------------
# 0x80 ~ 0xA1 R 調整データ dig.T1 ~ T3,dig.P1 ~ P9,dig_H1 19?
# 0xD0 R チップID chip_id [7-0]
# 0xE0 W リセット reset [7-0]
# 0xE1 ~ 0xF0 R 調整データ dig.H2 ~ H6
# 0xF2 R/W 制御レジスタ osrs_h[2-0]
# 0xF3 R ステータス measuring,im_up_date
# 0xF4 R/W 制御レジスタ osrc_t[2-0],osrs_p[2-0],mode[1-0]
# 0xF5 R/W 設定レジスタ t_sb[2-0],filter[2-0],pi3w_en
# 0xF7 R 圧力測定データ(HIGH) press.msb [7-0]
# 0xF8 R 圧力測定データ(LOW) press.lsb [7-0]
# 0xF9 R 圧力測定データ(exLOW) press.xlsb [7-4]
# 0xFA R 温度測定データ (HIGH) temp.msb [7-0]
# 0xFB R 温度測定データ (LOW) temp.lsb [7-0]
# 0xFC R 温度測定データ (exLOW) temp.xlsb [7-4]
# 0xFD R 湿度測定データ(HIGH) press.lsb [7-0]
# 0xFE R 湿度測定データ(LOW) press.lsb [7-0]
#--------------------------------------------------------------------------------
from smbus2 import SMBus
bus_number = 1
i2c_address = 0x76
bus = SMBus(bus_number)
digT = []
digP = []
digH = []
t_fine = 0.0
#--------------------------------------------------------------------------------
# Register Write
#--------------------------------------------------------------------------------
def writeReg(reg_address, data):
bus.write_byte_data(i2c_address,reg_address,data)
#--------------------------------------------------------------------------------
# flg:0 DWORD,1:WORD,2:BYTE
#--------------------------------------------------------------------------------
_DWORD = 0
_WORD = 1
_BYTE = 3
def unsigned2long(dt,flg=1):
cf = 0x80000000
mk = 0xffffffff
if flg & 1:
cf >>= 16
mk >>= 16
if flg & 2:
cf >>= 8
mk >>= 8
if dt & cf: dt = (-dt ^ mk)+1
return dt;
#--------------------------------------------------------------------------------
# キャリブレーション
# 0x88 - 0x8D T1(WORD),T2,T3(short) 6Byte
# 0x8E - 0x9F P1(WORD),P2-P9(short) 18Byte
# 0xA1 H1(BYTE)
# 0xE1 H1(BYTE)
#--------------------------------------------------------------------------------
def get_calib_param():
#----------------------------------------------------------------------------
# T1 ~ T3
for i in list(range(0x88,0x8E,2)):
digT.append(bus.read_word_data(i2c_address,i))
#----------------------------------------------------------------------------
# P1 - P9
for i in list(range(0x8E,0xA0,2)):
digP.append(bus.read_word_data(i2c_address,i))
#----------------------------------------------------------------------------
# H1 - H6
digH.append(bus.read_byte_data(i2c_address,0xA1)) #H1
digH.append(bus.read_word_data(i2c_address,0xE1)) #H2
digH.append(bus.read_byte_data(i2c_address,0xE3)) #H3
t = bus.read_word_data(i2c_address,0xE4)
digH.append(((t & 0xFF) << 4) | ((t >> 8) & 0x0F)) #H4 0xE4 / 0xE5[3-0] => [11-4]/[3-0]
t = (t >> 12) & 0x0F
t = t | (bus.read_byte_data(i2c_address,0xE6) << 4) digH.append(t) #H5 0xE5[7-4] / 0xE6 => [3-0]/[11-4]
digH.append(bus.read_byte_data(i2c_address,0xE7)) #H6
#----------------------------------------------------------------------------
# sign Flip
# T2,T3 : (short)
for i in range(1,2): digT[i] = unsigned2long(digT[i],_WORD)
# P2 ~ P9 : (short)
for i in range(1,9): digP[i] = unsigned2long(digP[i],_WORD)
# H2,H4,H5 : (short)
for i in [1,3,4]: digH[i] = unsigned2long(digH[i],_WORD)
# H6 : (char)
digH[5] = unsigned2long(digH[5],_BYTE)
#--------------------------------------------------------------------------------
# データ読み込み
# 0xF7 ~ 0xFE
#--------------------------------------------------------------------------------
def readData():
data = []
for i in range (0xF7, 0xF7+8):
data.append(bus.read_byte_data(i2c_address,i))
p_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4)
t_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4)
h_raw = (data[6] << 8) | data[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]
#--------------------------------------------------------------------------------
# 圧力
#--------------------------------------------------------------------------------
def compensate_P(adc_P):
global t_fine
pressure = 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
pressure = ((1048576 - adc_P) - (v2 / 4096)) * 3125
if pressure < 0x80000000: pressure = (pressure * 2.0) / v1 else: pressure = (pressure / v1) * 2 v1 = (digP[8] * (((pressure / 8.0) * (pressure / 8.0)) / 8192.0)) / 4096 v2 = ((pressure / 4.0) * digP[7]) / 8192.0 pressure = pressure + ((v1 + v2 + digP[6]) / 16.0) # print ("pressure:%7.2f hPa" % (pressure/100)) return pressure/100 #-------------------------------------------------------------------------------- # 温度 #-------------------------------------------------------------------------------- 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 return t_fine / 5120.0 #-------------------------------------------------------------------------------- # 湿度 #-------------------------------------------------------------------------------- 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
#--------------------------------------------------------------------------------
# Setup
# 0xF2 [00000hhh] osrs_h 湿度 over sampling 0:skip 1:x1 2:x2 3:x4 4:x8 5~:x16
# 0xF4 [tttpppmm] osrs_t 温度 over sampling 0:skip 1:x1 2:x2 3:x4 4:x8 5~:x16
# osrs_p 圧力 over sampling 0:skip 1:x1 2:x2 3:x4 4:x8 5~:x16
# mode デバイスのセンサーモード
# 0 : スリープ
# 1-2: 強制
# 3 : 通常
# 0xF5 [tttfff0i] t_sb 通常モードでの休止状態の継続時間
# 0: 0.5ms
# 1: 62.5ms
# 2: 125.0ms
# 3: 250.0ms
# 4: 500.0ms
# 5:1000.0ms
# 6: 10.0ms
# 7: 20.0ms
# filter 0:OFF 1:2 2:4 3:8 5~:16
# spi3w 0:4WireSPI 1:3WireSPI
#--------------------------------------------------------------------------------
def setup():
osrs_h = (1 ) # 湿度 oversampling x 1
osrs_t = (1 << 5) # 温度 oversampling x 1
osrs_p = (1 << 2) # 圧力 oversampling x 1
mode = (3 ) # Normal mode
t_sb = (5 << 5) # Tstandby 1000ms
filter = (0 << 2) # Filter off
spi3w = (0 ) # 3-wire SPI Disable
writeReg(0xF2,osrs_h ) # 制御レジスター osrs_h[2-0]
writeReg(0xF4,osrs_t | osrs_p | mode ) # 制御レジスター osrs_t[2-0] osrs_p[2-0] mode[1-0]
writeReg(0xF5,t_sb | filter | spi3w) # 設定レジスター t_sb [2-0] , filter [2-0] , pi3w_en
#--------------------------------------------------------------------------------
# Start!
# Addr:0xD0 chip_id [0x56,0x57,0x58:BMP280] / [0x60:BME280]
#--------------------------------------------------------------------------------
setup() # 初期化
get_calib_param() # チップ固有の個体差パラメータ読込
if __name__ == '__main__':
chip_id = bus.read_byte_data(i2c_address,0xD0);
if chip_id == 0x60: print("BME280")
else: print("BMP280")
try:
dat = readData()
print("温度:%-3.2f℃" % dat[0])
print("気圧:%7.2fhPa" % dat[1])
print("湿度:%6.2f%" % dat[2])
print("不快指数:%3.2f"% dat[3])
except KeyboardInterrupt:
pass
#--------------------------------------------------------------------------------
#EOF
チップの型番チェックとモジュールとして呼び出しができるように設定しています。
不快指数も計算してみました。
>>> %Run bme280.py BME280 温度:27.78℃ 気圧:1007.67hPa 湿度: 35.88% 不快指数:73.53


コメント