BOSCH temperature / humidity / barometric pressure sensor BME280 temperature / humidity / barometric pressure data is acquired by I2C communication.
Use the smbus module to control I2C in Python on the Raspberry Pi. If the smbus module is not installed, install it with the following command.
pip install smbus
Although bme280.py is imported and used as a package, temperature / humidity / barometric pressure data can be obtained by itself for testing. bme280.py (compressed with ZIP)
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
BM280 script.
=============
Temperature: -40 to +85 [degC]
Dumidity: 0 ot 100[%]
barometer: 300 to 1100[hPa]
"""
i2c_enable = False
try:
import smbus
i2c_enable = True
except:
i2c_enable = False
import random
import time
class BME280():
def __init__(self):
self.bus_number = 1
self.i2c_address = 0x76
self.i2c_enable = i2c_enable
if self.i2c_enable:
self.bus = smbus.SMBus(self.bus_number)
else:
self.bus = self.SMBus(self.bus_number)
return
self.digT = []
self.digP = []
self.digH = []
self.t_fine = 0.0
self.setup()
self.get_calib_param()
@property
def barometer(self):
result = float(f'{random.uniform(1020.0, 1040.0):.2f}')
if self.i2c_enable == False:
return result
# For I2C error at pushed power switch.
try:
pres_raw = self._read_bus_data('barometer')
except:
return result
pressure = 0.0
v1 = (self.t_fine / 2.0) - 64000.0
v2 = (((v1 / 4.0) * (v1 / 4.0)) / 2048) * self.digP[5]
v2 = v2 + ((v1 * self.digP[4]) * 2.0)
v2 = (v2 / 4.0) + (self.digP[3] * 65536.0)
v1 = (((self.digP[2] * (((v1 / 4.0) * (v1 / 4.0)) / 8192)) / 8) + ((self.digP[1] * v1) / 2.0)) / 262144
v1 = ((32768 + v1) * self.digP[0]) / 32768
if v1 == 0:
return 0
pressure = ((1048576 - pres_raw) - (v2 / 4096)) * 3125
if pressure < 0x80000000:
pressure = (pressure * 2.0) / v1
else:
pressure = (pressure / v1) * 2
v1 = (self.digP[8] * (((pressure / 8.0) * (pressure / 8.0)) / 8192.0)) / 4096
v2 = ((pressure / 4.0) * self.digP[7]) / 8192.0
pressure = pressure + ((v1 + v2 + self.digP[6]) / 16.0)
#print('pressure : %7.2f hPa' % (pressure/100))
result = float(f'{pressure/100:7.2f}')
return result
def get_calib_param(self):
if self.i2c_enable == False:
return
calib = []
for i in range (0x88,0x88+24):
calib.append(self.bus.read_byte_data(self.i2c_address,i))
calib.append(self.bus.read_byte_data(self.i2c_address,0xA1))
for i in range (0xE1,0xE1+7):
calib.append(self.bus.read_byte_data(self.i2c_address,i))
self.digT.append((calib[1] << 8) | calib[0])
self.digT.append((calib[3] << 8) | calib[2])
self.digT.append((calib[5] << 8) | calib[4])
self.digP.append((calib[7] << 8) | calib[6])
self.digP.append((calib[9] << 8) | calib[8])
self.digP.append((calib[11]<< 8) | calib[10])
self.digP.append((calib[13]<< 8) | calib[12])
self.digP.append((calib[15]<< 8) | calib[14])
self.digP.append((calib[17]<< 8) | calib[16])
self.digP.append((calib[19]<< 8) | calib[18])
self.digP.append((calib[21]<< 8) | calib[20])
self.digP.append((calib[23]<< 8) | calib[22])
self.digH.append( calib[24] )
self.digH.append((calib[26]<< 8) | calib[25])
self.digH.append( calib[27] )
self.digH.append((calib[28]<< 4) | (0x0F & calib[29]))
self.digH.append((calib[30]<< 4) | ((calib[29] >> 4) & 0x0F))
self.digH.append( calib[31] )
for i in range(1,2):
if self.digT[i] & 0x8000:
self.digT[i] = (-self.digT[i] ^ 0xFFFF) + 1
for i in range(1,8):
if self.digP[i] & 0x8000:
self.digP[i] = (-self.digP[i] ^ 0xFFFF) + 1
for i in range(0,6):
if self.digH[i] & 0x8000:
self.digH[i] = (-self.digH[i] ^ 0xFFFF) + 1
@property
def humidity(self):
result = float(f'{random.uniform(10.0, 60.0):.2f}')
if self.i2c_enable == False:
return result
# For I2C error at pushed power switch.
try:
hum_raw = self._read_bus_data('humidity')
except:
return result
var_h = self.t_fine - 76800.0
if var_h != 0:
var_h = (hum_raw - (self.digH[3] * 64.0 + self.digH[4]/16384.0 * var_h))\
* (self.digH[1] / 65536.0\
* (1.0 + self.digH[5] / 67108864.0 * var_h \
* (1.0 + self.digH[2] / 67108864.0 * var_h)))
else:
return 0
var_h = var_h * (1.0 - self.digH[0] * var_h / 524288.0)
if var_h > 100.0:
var_h = 100.0
elif var_h < 0.0:
var_h = 0.0
#print('hum : %6.2f %' % (var_h))
result = float(f'{var_h:.2f}')
return result
def _read_bus_data(self, data_type):
"""
data_tpye: 'temperature' or 'hidumity' or 'barometer'
"""
data = []
for i in range (0xF7, 0xF7+8):
data.append(self.bus.read_byte_data(self.i2c_address,i))
if data_type == 'barometer':
return (data[0] << 12) | (data[1] << 4) | (data[2] >> 4)
elif data_type == 'humidity':
return (data[6] << 8) | data[7]
elif data_type == 'temperature':
return (data[3] << 12) | (data[4] << 4) | (data[5] >> 4)
else:
return [0]
def read_data(self):
t = self.temperature
h = self.humidity
p = self.barometer
return [t, h, p]
def setup(self, ):
osrs_t = 1 #Temperature oversampling x 1
osrs_p = 1 #Pressure oversampling x 1
osrs_h = 1 #Humidity oversampling x 1
mode = 3 #Normal mode
t_sb = 5 #Tstandby 1000ms
filter = 0 #Filter off
spi3w_en = 0 #3-wire SPI Disable
ctrl_meas_reg = (osrs_t << 5) | (osrs_p << 2) | mode
config_reg = (t_sb << 5) | (filter << 2) | spi3w_en
ctrl_hum_reg = osrs_h
self.write_reg(0xF2,ctrl_hum_reg)
self.write_reg(0xF4,ctrl_meas_reg)
self.write_reg(0xF5,config_reg)
# Dummy SMBus.
class SMBus():
def __init__(self, *args, **kwargs):
pass
@property
def temperature(self):
result = float(f'{random.uniform(20.0, 40.0):.2f}')
if self.i2c_enable == False:
return result
# For I2C error at pushed power switch.
try:
temp_raw = self._read_bus_data('temperature')
except:
return result
v1 = (temp_raw / 16384.0 - self.digT[0] / 1024.0) * self.digT[1]
v2 = (temp_raw / 131072.0 - self.digT[0] / 8192.0) * (temp_raw / 131072.0 - self.digT[0] / 8192.0) * self.digT[2]
self.t_fine = v1 + v2
temperature = self.t_fine / 5120.0
result = float(f'{temperature:.2f}')
return result
def write_reg(self, reg_address, data):
if self.i2c_enable == False:
return
try:
self.bus.write_byte_data(self.i2c_address, reg_address, data)
except:
self.i2c_enable = False
self.bus = self.SMBus(self.bus_number)
if __name__ == '__main__':
em = BME280()
while True:
print(em.read_data())
#print(em.barometer)
#print(em.humidity)
#print(em.temperature)
time.sleep(0.5)
YouTube: Thermal Camera (Thermo AI Device TiD) Python Edition web: Thermo AI device TiD Python BME280 (URL is subject to change)
Recommended Posts