BMP180 et Orange Pi Zéro

Baromètre et température

La mesure de pression barométrique est possible avec le capteur BMP180 ou GY-68 qui fournit également la température ambiante via un bus I2c.

Raccordement

Raccordez comme montré sur le schéma, le module BMP180 au bus I2c0.

Activation du bus I2c

On part d’un Orange PI avec le système Armbian déjà installé. Il faut configurer le système en lançant ‘armbian-config’, l’équivalent du ‘raspiconfig’ sur Raspberry.

$ armbian-config

Allez dans la rubrique « system » et sélectionnez « Hardware » puis activé i2c0.

Installez les utilitaires I2c.

apt install i2c-tools

Testez la réponse du BMP180.

i2cdetect -y 0
Réponse adresse 77

Installation Bibliothèques

Installation de la bibliothèque d’accès au bus i2c avec python3:

apt install python-smbus python3-smbus

Avec nano, créez le fichier python3 testbmp.py et copiez y le source ci après. Chaque capteur à son propre jeu de coefficients de calibration qui ne doivent pas être nuls. Ils sont lus et affichés par le programme.

#!/usr/bin/python3          

import smbus
import time
import math

address = 0x77  #I2c device BMP180
mode = 1 # mode Standard

# BMP180 registers
CONTROL_REG = 0xF4
DATA_REG = 0xF6
# Calibration data registers
CAL_AC1_REG = 0xAA
CAL_AC2_REG = 0xAC
CAL_AC3_REG = 0xAE
CAL_AC4_REG = 0xB0
CAL_AC5_REG = 0xB2
CAL_AC6_REG = 0xB4
CAL_B1_REG = 0xB6
CAL_B2_REG = 0xB8
CAL_MB_REG = 0xBA
CAL_MC_REG = 0xBC
CAL_MD_REG = 0xBE


def read_signed_16_bit( register): #Lit valeur signée 16 bits        
        msb = bus.read_byte_data(address, register)
        lsb = bus.read_byte_data(address, register + 1)
        if msb > 127:
            msb -= 256
        return (msb << 8) + lsb
def read_unsigned_16_bit( register):  #Lit valeur non signée 16 bits
        msb = bus.read_byte_data(address, register)
        lsb = bus.read_byte_data(address, register + 1)
        return (msb << 8) + lsb

# Temperature (see BMP180 datasheet)

def get_raw_temp():    
        # Start the measurement
        bus.write_byte_data(address, CONTROL_REG, 0x2E)
        # Wait 5 ms
        time.sleep(0.005)
        # Read the raw data from the DATA_REG, 0xF6
        raw_data = read_unsigned_16_bit(DATA_REG)
        # Return the raw data
        return raw_data
def get_temp():
        UT = get_raw_temp()
        X1 = ((UT - calAC6) * calAC5) / math.pow(2, 15)
        X2 = calMC*math.pow(2, 11)/(X1+calMD)
        B5 = X1 + X2
        temperature = ((B5 + 8) / math.pow(2, 4)) / 10
        return temperature

# Pressure
def get_raw_pressure():        
        bus.write_byte_data(address, CONTROL_REG, 0x34 + (mode << 6))
        # Sleep for 8 ms.
        time.sleep(0.008)
        # Read the raw data from the DATA_REG, 0xF6
        MSB = bus.read_byte_data(address, DATA_REG)
        LSB = bus.read_byte_data(address, DATA_REG + 1)
        XLSB = bus.read_byte_data(address, DATA_REG + 2)
        raw_data = ((MSB << 16) + (LSB << 8) + XLSB) >> (8 - mode)
        return raw_data
def get_pressure():     
        UP = get_raw_pressure()
        UT = get_raw_temp()
        #calculation idem temperature
        X1 = ((UT - calAC6) * calAC5) / math.pow(2, 15)
        X2 = (calMC * math.pow(2, 11)) / (X1 + calMD)
        B5 = X1 + X2      
        B6 = B5 - 4000
        X1 = (calB2 * (B6 * B6 / math.pow(2, 12))) / math.pow(2, 11)
        X2 = calAC2 * B6 / math.pow(2, 11)
        X3 = X1 + X2
        B3 = (((calAC1 * 4 + int(X3)) << mode) + 2) / 4
        X1 = calAC3 * B6 / math.pow(2, 13)
        X2 = (calB1 * (B6 * B6 / math.pow(2, 12))) / math.pow(2, 16)
        X3 = ((X1 + X2) + 2) / math.pow(2, 2)
        B4 = calAC4 * (X3 + 32768) / math.pow(2,15)
        B7 = (UP - B3) * (50000 >> mode)
        if B7 < 0x80000000:
            pressure = (B7 * 2) / B4
        else:
            pressure = (B7 / B4) * 2
        X1 = (pressure / math.pow(2, 8)) * (pressure / math.pow(2, 8))
        X1 = (X1 * 3038) / math.pow(2, 16)
        X2 = (-7357 * pressure) / math.pow(2, 16)
        pressure = pressure + (X1 + X2 + 3791) / math.pow(2, 4)
        pressure=pressure/100 #hPa
        return pressure 

        
# I2C bus 0

bus = smbus.SMBus(0)

# Calibration data variables
calAC1 = read_signed_16_bit(CAL_AC1_REG)
calAC2 = read_signed_16_bit(CAL_AC2_REG)
calAC3 = read_signed_16_bit(CAL_AC3_REG)
calAC4 = read_unsigned_16_bit(CAL_AC4_REG)
calAC5 = read_unsigned_16_bit(CAL_AC5_REG)
calAC6 = read_unsigned_16_bit(CAL_AC6_REG)
calB1 = read_signed_16_bit(CAL_B1_REG)
calB2 = read_signed_16_bit(CAL_B2_REG)
calMB = read_signed_16_bit(CAL_MB_REG)
calMC = read_signed_16_bit(CAL_MC_REG)
calMD = read_signed_16_bit(CAL_MD_REG)

print("Calibration:",calAC1,calAC2,calAC3,calAC4,calAC5,calAC6,calB1,calB2,calMB,calMC,calMD)
while True:
    print("Temperature: {0:0.1f} C".format(get_temp()))
    print('Pressure = {0:0.1f} hPa'.format(get_pressure()))   
    time.sleep(2)

La pression est fournie en hecto Pascal (hPa) et la température en degré Celsius (°C).

#!/usr/bin/python3          # This is client.py file


import smbus
import time
import math

address = 0x77  #I2c device BMP180
mode = 1 # mode Standard

# BMP180 registers
CONTROL_REG = 0xF4
DATA_REG = 0xF6
# Calibration data registers
CAL_AC1_REG = 0xAA
CAL_AC2_REG = 0xAC
CAL_AC3_REG = 0xAE
CAL_AC4_REG = 0xB0
CAL_AC5_REG = 0xB2
CAL_AC6_REG = 0xB4
CAL_B1_REG = 0xB6
CAL_B2_REG = 0xB8
CAL_MB_REG = 0xBA
CAL_MC_REG = 0xBC
CAL_MD_REG = 0xBE


def read_signed_16_bit( register): #Lit valeur signée 16 bits        
        msb = bus.read_byte_data(address, register)
        lsb = bus.read_byte_data(address, register + 1)
        if msb > 127:
            msb -= 256
        return (msb << 8) + lsb
def read_unsigned_16_bit( register):  #Lit valeur non signée 16 bits
        msb = bus.read_byte_data(address, register)
        lsb = bus.read_byte_data(address, register + 1)
        return (msb << 8) + lsb

# Temperature (see BMP180 datasheet)

def get_raw_temp():    
        # Start the measurement
        bus.write_byte_data(address, CONTROL_REG, 0x2E)
        # Wait 5 ms
        time.sleep(0.005)
        # Read the raw data from the DATA_REG, 0xF6
        raw_data = read_unsigned_16_bit(DATA_REG)
        # Return the raw data
        return raw_data
def get_temp():
        UT = get_raw_temp()
        X1 = ((UT - calAC6) * calAC5) / math.pow(2, 15)
        X2 = calMC*math.pow(2, 11)/(X1+calMD)
        B5 = X1 + X2
        temperature = ((B5 + 8) / math.pow(2, 4)) / 10
        return temperature

# Pressure
def get_raw_pressure():        
        bus.write_byte_data(address, CONTROL_REG, 0x34 + (mode << 6))
        # Sleep for 8 ms.
        time.sleep(0.008)
        # Read the raw data from the DATA_REG, 0xF6
        MSB = bus.read_byte_data(address, DATA_REG)
        LSB = bus.read_byte_data(address, DATA_REG + 1)
        XLSB = bus.read_byte_data(address, DATA_REG + 2)
        raw_data = ((MSB << 16) + (LSB << 8) + XLSB) >> (8 - mode)
        return raw_data
def get_pressure():     
        UP = get_raw_pressure()
        UT = get_raw_temp()
        #calculation idem temperature
        X1 = ((UT - calAC6) * calAC5) / math.pow(2, 15)
        X2 = (calMC * math.pow(2, 11)) / (X1 + calMD)
        B5 = X1 + X2      
        B6 = B5 - 4000
        X1 = (calB2 * (B6 * B6 / math.pow(2, 12))) / math.pow(2, 11)
        X2 = calAC2 * B6 / math.pow(2, 11)
        X3 = X1 + X2
        B3 = (((calAC1 * 4 + int(X3)) << mode) + 2) / 4
        X1 = calAC3 * B6 / math.pow(2, 13)
        X2 = (calB1 * (B6 * B6 / math.pow(2, 12))) / math.pow(2, 16)
        X3 = ((X1 + X2) + 2) / math.pow(2, 2)
        B4 = calAC4 * (X3 + 32768) / math.pow(2,15)
        B7 = (UP - B3) * (50000 >> mode)
        if B7 < 0x80000000:
            pressure = (B7 * 2) / B4
        else:
            pressure = (B7 / B4) * 2
        X1 = (pressure / math.pow(2, 8)) * (pressure / math.pow(2, 8))
        X1 = (X1 * 3038) / math.pow(2, 16)
        X2 = (-7357 * pressure) / math.pow(2, 16)
        pressure = pressure + (X1 + X2 + 3791) / math.pow(2, 4)
        pressure=pressure/100 #hPa
        return pressure 

        
# I2C bus 0

bus = smbus.SMBus(0)

# Calibration data variables
calAC1 = read_signed_16_bit(CAL_AC1_REG)
calAC2 = read_signed_16_bit(CAL_AC2_REG)
calAC3 = read_signed_16_bit(CAL_AC3_REG)
calAC4 = read_unsigned_16_bit(CAL_AC4_REG)
calAC5 = read_unsigned_16_bit(CAL_AC5_REG)
calAC6 = read_unsigned_16_bit(CAL_AC6_REG)
calB1 = read_signed_16_bit(CAL_B1_REG)
calB2 = read_signed_16_bit(CAL_B2_REG)
calMB = read_signed_16_bit(CAL_MB_REG)
calMC = read_signed_16_bit(CAL_MC_REG)
calMD = read_signed_16_bit(CAL_MD_REG)

print("Calibration:",calAC1,calAC2,calAC3,calAC4,calAC5,calAC6,calB1,calB2,calMB,calMC,calMD)
while True:
    print("Temperature: {0:0.1f} C".format(get_temp()))
    print('Pressure = {0:0.1f} hPa'.format(get_pressure()))   
    time.sleep(2)

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *