Сегодня хотелось бы рассмотреть устройство, представляющее собой барометр — измеритель атмосферного давления. Применения такого устройства необходимо для мониторинга текущего атмосферного давления выраженного на индикаторе устройства в 2-х единицах измерения — в международной системе единиц Паскали (Па или Pa) и во внесистемных единицах измерения — миллиметры ртутного столбца. Последнее скорее всего больше привычно для наших стран, потому что применяется в прогнозах погоды. Но функционал данного устройства не ограничивается измерением лишь атмосферного давления, также реализовано измерение температуры и определение высоты над уровнем моря (альтитуды).
Схема устройства на AVR микроконтроллере ATmega8 представлена ниже:
В качестве датчика атмосферного давления в схеме использован BMP180 производства компании Bosch. По правде говоря, эта компания делает хорошие и качественные вещи, но даташит на этот датчик составлен в сравнении с даташитами других компаний не очень развернуто, без опыта чтения подобной документации разобраться будет трудно. Инженеры Bosch посчитали необходимым дать информацию лишь по самым основным параметрам, но все что нам нужно все есть, хоть местами и кратко. Датчик атмосферного давления BMP180 может работать как по I2C интерфейсу, так и по SPI интерфейсу (выбирается подключением необходимых выводов датчика). В данной схеме используется I2C интерфейс. Так как датчик требует питания до 3,3 вольт, а микроконтроллер питается от 5 вольт постоянного напряжения, необходимо применить согласование уровней I2C для корректной работы. Для этой цели выбрана микросхема производства компании NXP PCA9517. Сам датчик берет питания от стабилизатора напряжения на 3,3 вольта, это же питание подается на подтягивающие резисторы R6 и R7. Уровни сигналов преобразовываются микросхемой PCA9517 и сигналы от датчика атмосферного давления передаются микроконтроллеру с уровнями до 5 вольт. 5 вольт подключается к подтягивающим резисторам R4 и R5. Эти подтягивающие резисторы (pull-up) необходимы для работы протокола I2C — с их помощью формируются высокие уровни сигнала, а когда микросхема проваливает это напряжение с подтягивающих резисторов в нулевой потенциал, формируется низкий логический сигнал. В данной конфигурации напряжений логических уровней 3,3 и 5 вольт можно обойтись на крайний случай и без согласования уровней, потому что согласно стандартам при таких питающих напряжения потенциалы низких уровней у них одинаковые, а высокий уровень совпадает как у 5 вольт, так и у 3,3 вольт, разница заключается лишь в максимальных значениях. Но было решено не рисковать и все же применить согласование уровней — сделать все по правилам. Номиналы подтягивающих резисторов можно взять от 4,7 кОм до 10 кОм. Конденсаторы C3 и C4 необходимы для стабильной работы датчика атмосферного давления.
Важной функцией в данном датчике атмосферного давления является калибровка полученных измерений. В памяти датчика есть 11 коэффициентов, предназначенных для улучшения точности измерения параметров. Но не все так просто — домножить на эти коэффициенты так просто нельзя. для получения конечных результатов в даташите приведен целый пример расчета на странице 15, документация на датчик ниже. В соответствии с этой информацией составляем программу для микроконтроллера на языке Си.
// получить значения температуры и атмосферного давления с учетом калибровочных коэффициентов
void BMP180_calculation (int32_t* temperature, int32_t* pressure) {
//int8_t i;
int32_t ut=0;
int32_t up=0;
int32_t x1, x2, b5, b6, x3, b3, p;
uint32_t b4, b7;
BMP180_get_temper();
ut+=temperature_1;
BMP180_get_pressure();
up=pressure_1;
x1 = ((int32_t)ut — (int32_t)ac6) * (int32_t)ac5 >> 15;
x2 = ((int32_t)mc << 11) / (x1 + md);
b5 = x1 + x2;
*temperature = (b5 + 8) >> 4;
b6 = b5 — 4000;
x1 = (b2 * ((b6 * b6) >> 12)) >> 11;
x2 = (ac2 * b6) >> 11;
x3 = x1 + x2;
b3 = (((((int32_t) ac1) * 4 + x3)<> 2;
x1 = (ac3 * b6) >> 13;
x2 = (b1 * ((b6 * b6) >> 12)) >> 16;
x3 = ((x1 + x2) + 2) >> 2;
b4 = (ac4 * (uint32_t) (x3 + 32768)) >> 15;
b7 = ((uint32_t) (up — b3) * (50000 >> OSS));
//p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2;
if (b7 < 0x80000000)
{
p = (b7 << 1) / b4;
}
else
{
p = (b7 / b4) << 1;
}
x1 = (p >> 8) * (p >> 8);
x1 = (x1 * 3038) >> 16;
x2 = (-7357 * p) >> 16;
*pressure = p + ((x1 + x2 + 3791) >> 4);
}
У каждого датчика калибровочные коэффициенты свои (видимо на заводе их полностью задают в соответствии с какими-то контрольными испытаниями). Перед использованием эти коэффициенты нужно прочитать из регистра хранения датчика.
// получить данные для калибровки
void BMP180_Calibration (void) {
ac1 = Read(0xAA);
ac2 = Read(0xAC);
ac3 = Read(0xAE);
ac4 = Read(0xB0);
ac5 = Read(0xB2);
ac6 = Read(0xB4);
b1 = Read(0xB6);
b2 = Read(0xB8);
mb = Read(0xBA);
mc = Read(0xBC);
md = Read(0xBE);
}
// чтение регистра 16 бит
uint16_t Read(uint8_t address) {
uint16_t msb=0;
uint16_t lsb=0;
uint16_t data;
i2c_start_cond(); // запуск i2c
i2c_send_byte(BMP180_W); // передача адреса устройства, режим записи
i2c_send_byte(address); // передача адреса памяти
i2c_stop_cond(); // остановка i2c
i2c_start_cond(); // запуск i2c
i2c_send_byte(BMP180_R); // передача адреса устройства, режим чтения
msb = i2c_get_byte(0);
lsb = i2c_get_byte(1);
i2c_stop_cond(); // остановка i2c
data = (msb << 8) + lsb;
return data;
}
Для получения значения альтитуды или высоты над уровнем моря используем также формулу, приведенную в даташите и получаем такую функцию:
// функция расчета высоты над уровнем моря (альтитуда) (функция берет очень много памяти из-за математических функций !!!)
void bmp180CalcAltitude(int32_t pressure){
float temp;
temp = (float) pressure/101325;
temp = 1-pow(temp, 0.19029);
//altitude = round(44330*temp*10);
altitude = 44330*temp*100;
//get altitude in dm
}
В зависимости от надобности эту функцию можно выбросить из исходника, потому что для расчета нужно использовать библиотеку — реализованные в ней методы расчета необходимых действий отбирают очень много памяти как флэш, так и оперативной, однако ничего лучше пока не придумал.
Также данный датчик может измерять атмосферное давление с разной точностью. Для задания точности необходимо передать это значение датчику по I2C и правильно задать задержку перед чтением регистров с полученными данными (в зависимости от точности, датчику нужно больше или меньше времени на измерение). программный код выглядит так:
// прочитать значение атмосферного давления
void BMP180_get_pressure(void){
i2c_start_cond(); // запуск i2c
i2c_send_byte(BMP180_W); // передача адреса устройства, режим записи
i2c_send_byte(0xF4); // передача адреса памяти
i2c_send_byte(0x34+(OSS<<6)); // передача разрешения (oss) адреса памяти температуры
i2c_stop_cond(); // остановка i2c
_delay_ms(26); // время на замер (от 5 до 26 мс в зависимости от разрешения (oss))
i2c_start_cond(); // запуск i2c
i2c_send_byte(BMP180_W); // передача адреса устройства, режим записи
i2c_send_byte(0xF6); // передача адреса памяти
i2c_stop_cond(); // остановка i2c
i2c_start_cond(); // запуск i2c
i2c_send_byte(BMP180_R); // передача адреса устройства, режим чтения
D1=i2c_get_byte(0); // MSB
D2=i2c_get_byte(0); // LSB
D3=i2c_get_byte(1); // XLSB
i2c_stop_cond(); // остановка i2c
pressure_1 = ((D1 << 16) + (D2 << 8) + D3) >> (8-OSS); // вычислить давление (в Па)
}
При сборке схемы датчик атмосферного давления BMP180 был применен на заводской печатной плате китайской сборки (модуль включает в себя стабилизатор питания на 3,3 вольта с конденсаторами, подтягивающие резисторы для интерфейса I2C и конденсаторы в обвязке самого датчика по питанию, микросхема или просто схема согласования уровней на данной плате отсутствует, поэтому необходимо применять в другом исполнении):
Питается вся схема от простого модуля питания на силовом трансформаторе. Переменное напряжение выпрямляется четырьмя диодами VD1 — VD4 марки 1N4007, пульсации сглаживаются конденсаторами C1 и C2. Номинал конденсатора C2 можно увеличить до 1000 — 4700 мкФ. Четыре выпрямительных диода можно заменить одним диодным мостом. Трансформатор применен марки BV EI 382 1189 — преобразует 220 вольт переменного тока в 9 вольт переменного тока. Мощность трансформатора составляет 4,5 Вт, этого вполне достаточно и ещё с запасом. Такой трансформатор можно заменить любым другим силовым трансформатором, подходящим для Вас. Либо данный питающий модуль схемы заменить на импульсный источник напряжения, можно собрать схему обратноходового преобразователя либо применить иже готовый блок питания от телефона, например — все это дело вкусов и потребностей. Выпрямленное напряжение с трансформатора стабилизируется на микросхеме линейного стабилизатора L7805, ее можно заменить на отечественный аналог пяти вольтового линейного стабилизатора КР142ЕН5А, либо применить другу микросхему стабилизатора напряжения в соответствии с подключением ее в схеме (например LM317 или импульсные стабилизаторы LM2576, LM2596, MC34063 и так далее). Далее 5 вольт стабилизируются другой микросхемой — AMS1117 в исполнении, дающей на выходе 3,3 вольта. Это напряжение используется для питания датчика атмосферного давления BMP180 в соответствии с документацией. Номиналы конденсаторов в обвязках микросхем стабилизаторов напряжения можно варьировать в широких пределах в области взятого порядка.
Ну и сердцем схемы является микроконтроллер Atmega8. данный микроконтроллер можно использовать как в корпусе DIP-28, так и в СМД исполнении в корпусе TQFP-32. Резистор R3 необходим для предотвращения самопроизвольного перезапускания микроконтроллера в случае появления случайных помех на выводе PC6. Резистор R3 подтягивает плюс питания к этому выводу, надежно создавая потенциал на нем. Для индикации измеряемых параметров используется жидко кристаллический (ЖК или LCD) дисплей SC1602. Он имеет 2 строки символов по шестнадцать штук в каждой из них. ЖК дисплей подключается к микроконтроллеру по 4-х битной системе. Переменный резистор R2 необходим для регулировки контраста символов на дисплее. Вращением движка этого резистора добиваемся наиболее четких для нас показаний на экране. Подсветка ЖК дисплея организована через вывод «А» и «К» на плате дисплея. Подсветка включается через резистор, ограничивающий ток — R1. Чем больше номинал, тем более тускло будет подсвечиваться дисплей. Но пренебрегать этим резистором не стоит во избежание порчи подсветки. Мощность всех резисторов постоянного сопротивления составляет 0,25 Вт.
Схема была собрана и отлажена на макетной плате для микроконтроллеров Atmega8:
В итоге данная схема имеет следующий функционал:
- измерение и отображение атмосферного давления в 2-х единицах измерения (Паскали и миллиметры ртутного столбца)
- измерение и отображение температуры окружающей среды
- подсчет и отображение положения датчика относительно уровня моря (подсчет альтитуды)
- данные на дисплее обновляются раз в две секунды
В данном устройстве показание положения относительно уровня моря именно высчитывается, а не измеряется. Расчет происходит по рекомендованной формуле из даташита упрощенного расчета положения относительно уровня моря в зависимости от атмосферного давления. Как известно, чем выше мы находимся, тем давление атмосферы меньше. Именно эта зависимость и используется при расчете. Но, в связи с тем что для любой отдельной территории погода может меняться, а вместе с ней и атмосферное давление будет колебаться. Исходя из этих размышлений, а также опытных наблюдений, положение над уровнем моря будет постоянно плавать в зависимости от колебаний атмосферного давления (по идеи то высота не должна изменяться с такой скоростью). Эта функция рассматривается как дополнительная и не совсем достоверная (уровень над морем в течении дня может плавать плюс минус процентов 5 — а это много, я считаю). Но именно атмосферное давление измеряется данным датчиком вполне точно — совпадение с текущим прогнозом погоды от полного до расхождения не более одного процента. Температура в данном датчике измеряется также весьма точно.
Как вывод могу сказать, что данный датчик атмосферного давления выполняет свои основные функции очень даже не плохо и может сгодиться для домашней метеостанции, которой мы и займемся в скором будущем.
Для программирования микроконтроллера Atmega8 необходимо знать конфигурацию фьюз битов (скриншот сделан в программе AVR Studio):
К статье прилагается прошивка для микроконтроллера, полный исходный код для данного устройства для работы с датчиком BMP180 в AVR Studio документация на датчик, а также небольшое видео, демонстрирующее работоспособность схемы (наблюдаем как изменяются параметры, если зажать датчик атмосферного давления пальцем руки).
Список радиоэлементовОбозначение
Тип
Номинал
Количество
ПримечаниеМагазинМой блокнот
IC1
МК AVR 8-битATmega81
IC2
ИС I2C интерфейсаPCA95171
IC3
Датчик атмосферного давленияBMP1801
VR1
Линейный регуляторL7805AB1
VR2
Линейный регуляторAMS1117-3.31
VD1-VD4
Выпрямительный диод1N40074
HG1
LCD-дисплейSC16021
На базе HD44780S1
Тактовая кнопкаTC-A1091
Tr1
ТрансформаторBV EI 382 11891
220В — 9В ACR1
Резистор22 Ом1
R2
Подстроечный резистор10 кОм1
R3-R7
Резистор10 кОм5
C1, C3-C5, C7, C8
Конденсатор100 нФ6
C2, C6, C9
Электролитический конденсатор220 мкФ3
Добавить все
Скачать список элементов (PDF)
Прикрепленные файлы:
- 31.hex (21 Кб)
- 31.rar (75 Кб)
- BMP180.pdf (656 Кб)