Thermal camera (Thermo AI device TiD) Python BME280

BOSCH temperature / humidity / barometric pressure sensor BME280 temperature / humidity / barometric pressure data is acquired by I2C communication.


  1. Introduction
  2. Sensor
  3. Sensor case
  4. Raspberry Pi
  5. Python 5.1 Form 5.2 OMRON Non-contact Temperature Sensor D6T-44L-06 Edition 5.3 Pololu ranging sensor VL53L0X edition 5.4 BOSCH Temperature / Humidity / Barometric Pressure Sensor BME280 5.5 Shutdown / Restart Switch Edition 5.6 OpenCV 5.7 Speedup

bme280.jpg 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

Thermal camera (Thermo AI device TiD) Python BME280
Thermal Camera (Thermo AI Device TiD) Python Acceleration
Thermal Camera (Thermo AI Device TiD) Python OpenCV Edition
Thermal camera (thermo AI device TiD) Python VL53L0X edition
Thermal Camera (Thermo AI Device TiD) Python D6T-44L-06 Edition
Thermal Camera (Thermo AI Device TiD) Introduction
Thermal camera (Thermo AI device TiD) Sensor edition
Thermal Camera (Thermo AI Device TiD) Raspberry Pi Edition
Thermal Camera (Thermo AI Device TiD) Python Acceleration
Thermal camera (Thermo AI device TiD) Python BME280
Thermal Camera (Thermo AI Device TiD) Python OpenCV Edition
Thermal camera (thermo AI device TiD) Python VL53L0X edition
Thermal Camera (Thermo AI Device TiD) Python D6T-44L-06 Edition
Thermal Camera (Thermo AI Device TiD) Introduction
Thermal camera (Thermo AI device TiD) Sensor edition
Thermal Camera (Thermo AI Device TiD) Raspberry Pi Edition