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.
![](https://f1atb.fr/wp-content/uploads/2020/10/bmp180.png)
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.
![](https://f1atb.fr/wp-content/uploads/2020/09/Capturei2c0.png)
Installez les utilitaires I2c.
apt install i2c-tools
Testez la réponse du BMP180.
i2cdetect -y 0
![](https://f1atb.fr/wp-content/uploads/2020/10/i2csalon.png)
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)
Commentaires récents