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
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