RaspberryPi и барометр Bosch BMP085

Третьего дня пришел заказанный на dx.com модуль, содержащий трехосный гироскоп L3G4200D, трехосный акселерометр ADXL345, цифровой компас HMC5883L, и барометр BMP085. Ссылка на модуль GY-80 BMP085 9-Axis Magnetic Acceleration Gyroscope Module for Arduino. Работа со всеми датчиками производится через I2C, адреса устройств берутся из даташитов. Поскольку с гироскопами, аксами и компасом я уже имел дело, то решил начать с барометра, поскольку изучение даташита показало, что получение значения окружающего давления не такая простая процедура, как например получение значений ускорения по осям акселерометра. Для начала необходимо считать несколько коэффициентов, зашиваемых в датчик на заводе при калибровке, потом считать сырые значения температуры и давления, а потом уже из них путем хитрых математических операций можно получить давление в паскалях. В процессе возни с барометром для упрощения была написана простенькая библиотека на питоне для работы с I2C.

Файл I2C_RPi.py содержит класс I2C_RPi, который имеет следующие функции:
__init__(self, address, bus=smbus.SMBus(0))

Инициализация шины I2C, в качестве параметров передается адрес устройства и канал(по умолчанию всегда нулевой), на котором висит шина, для моей RaspberryPi это нулевой канал, в каких-то более новых моделях — первый, но можно принудительно задать любой, поэтому эту библиотеку можно использовать на любой другой плате, только необходим установленный питоновский модуль smbus.
read_u8(self, reg_addr)

Функция чтения unsigned byte, параметр — адрес регистра для чтения
read_u16(self, reg_addr)

Функция чтения unsigned 16-bit, параметр — адрес регистра для чтения
read_s16(self, reg_addr)

Функция чтения signed 16-bit, параметр — адрес регистра для чтения
write_8(self, reg_addr, value)

Функция записи byte, параметр — адрес регистра для чтения

Подключение библиотеки осущетвляется добавлением в начало программы на питоне:
from I2C_RPi import I2C_RPi

Файл I2C_RPi.py должен лежать в той же папке, что и файл программы.

Далее был написан отдельный класс для барометра, чтобы удобно было работать и не перегружать основную программу расчетами и функциями. Опишу основные моменты, целиком файл класса смотрите в прикрепленном архиве, файл BMP085_device.py.
Подключаем нашу библиотеку:
from I2C_RPi import I2C_RPi

Согласно даташиту задаем константы режимов работы барометра, из названий думаю понятно какие это режимы:
__BMP085_ULTRALOWPOWER     = 0
__BMP085_STANDARD          = 1
__BMP085_HIGHRES           = 2
__BMP085_ULTRAHIGHRES      = 3


Определяем глобальные переменные, в которые будем записывать калибровочные коэффициенты, имена взяты из даташита:
_AC1 = 0
_AC2 = 0
_AC3 = 0
_AC4 = 0
_AC5 = 0
_AC6 = 0
_B1 = 0
_B2 = 0
_MB = 0
_MC = 0
_MD = 0


Инициализация барометра, адрес по умолчанию 0х77, режим — 1 (стандартный):
__init__(self, address=0x77, mode=1)


Функция чтения калибровочных коэффициентов, параметров не принимает, все адреса регистров зашиты в функцию согласно даташиту:
readCoef(self)


Функция чтения «сырой» температуры:
readRawTemp(self)


Функция получения температуры в градусах Цельсия:
readTemp(self)

Как термометр этот датчик в принципе можно использовать, но реакция на изменение температуры у него очень медленная, поэтому использовать можно если температура меняется очень медленно.

Читаем «сырое» давление:
readRawPressure(self)


Считаем давление в Паскалях:
readPressure(self)


Считаем высоту над уровнем моря:
readAltitude(self)


Пример использования — файл BMP085_test.py
#!/usr/bin/python
#\
#импортируем необходимые модули
import time
import os
from BMP085_device import BMP085

#инициализируем наш барометр, адрес 0х77, режим - стандартный
barometer = BMP085(0x77, 1)
#создаем и открываем на запись лог-файл для записи показаний
f1 = open("data_log.txt", 'w')

for a in range(10000):
        #читаем температуру в градусах Цельсия
	temp = barometer.readTemp()
        #читаем давление в Паскалях
	pressure = barometer.readPressure()
        #если необходима высота, то следующую строку надо раскомментировать	
	#altitude = barometer.readAltitude()
	
        #записываем давление и температуру в лог-файл
	f1.write("%.2f" % temp)
	f1.write(" ")
	f1.write("%.2f\n" % (pressure / 100.0))

        #выводим показания в консоль
	print "Temperature: %.2f" % temp
	print "Pressure:    %.2f" % (pressure / 100.0)
	#print "Altitude:    %.2f" % altitude

	time.sleep(0.1)
	os.system('clear')


Программа в цикле будет считывать и выводить в консоль и лог-файл значения температуры и давления, выход из программы по Ctrl-C, в папке с программой будет лежать файл data_log.txt, кусок которого приведен ниже:
26.70 1022.42
26.70 1022.48
26.70 1022.50
26.70 1022.47
26.70 1022.42
26.70 1022.38


График полученного массива значений давления у меня дома:)


Архив со всеми необходимыми файлами в приложении к посту, в принципе работать должно на любом устройстве, а не только на RaspberryPi.
Файлы в топике: bmp085.zip

Комментарии (8)

RSS свернуть / развернуть
вы музыку слушали?
0
  • avatar
  • xar
  • 19 декабря 2012, 14:46
Нет, на графике есть небольшая ошибка, чтобы получить килоПаскали, надо результат поделить на 10, соответственно среднее давление будет 766,8 мм. рт. ст., ну а дребезг на графике скорее всего обусловлен погрешностью датчика.
0
ну я к тому, что надо бы фильтровать данные наверно.
0
Это просто эксперименты, при реальном применении для начала хорошо бы откалибровать датчик и сделать компенсацию погрешностей, ну и фильтр какой можно прикрутить.
0
«Аппаратным» фильтром типа куска ваты/поролона для защиты от ветра/сквозняка/шума
0
и это тоже. не зря же я про музыку написал. вполне серьезно может влиять на показания.
0
Если вместе с датчиком есть термометр (SHT21), можно ли использовать в расчетах давления температуру с него?
В BMP085 датчик температуры, как я понял, не калиброван.
0
  • avatar
  • Bonio
  • 20 декабря 2012, 12:48
По идее можно, насчет калибровки не знаю.
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.