Главная » Микроконтроллеры
Призовой фонд
на октябрь 2017 г.
1. Термометр Relsib WT51
Рэлсиб
2. 1000 руб
PCBWay
3. Регулируемый паяльник 60 Вт
Паяльник
4. 100 руб.
От пользователей

Барометр на AVR

Сегодня хотелось бы рассмотреть устройство, представляющее собой барометр - измеритель атмосферного давления. Применения такого устройства необходимо для мониторинга текущего атмосферного давления выраженного на индикаторе устройства в двух единицах измерения - в международной системе единиц Паскали (Па или Pa) и во внесистемных единицах измерения - миллиметры ртутного столбца. Последнее скорее всего больше привычно для наших стран, так как применяется в прогнозах погоды. Однако функционал данного устройства не ограничивается измерением только атмосферного давления, также реализовано измерение температуры и определение высоты над уровнем моря (альтитуды).

Схема устройства на AVR микроконтроллере ATmega8 представлена ниже:

Схема устройства на 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 строки символов по шестнадцать штук в каждой из них. ЖК дисплей подключается к микроконтроллеру по четырех битной системе. Переменный резистор R2 необходим для регулировки контраста символов на дисплее. Вращением движка этого резистора добиваемся наиболее четких для нас показаний на экране. Подсветка ЖК дисплея организована через вывод "А" и "К" на плате дисплея. Подсветка включается через резистор, ограничивающий ток - R1. Чем больше номинал, тем более тускло будет подсвечиваться дисплей. Однако пренебрегать этим резистором не стоит во избежание порчи подсветки. Мощность всех резисторов постоянного сопротивления составляет 0,25 Вт.

Схема была собрана и отлажена на макетной плате для микроконтроллеров Atmega8:

В итоге данная схема имеет следующий функционал:

  • измерение и отображение атмосферного давления в двух единицах измерения (Паскали и миллиметры ртутного столбца)
  • измерение и отображение температуры окружающей среды
  • подсчет и отображение положения датчика относительно уровня моря (подсчет альтитуды)
  • данные на дисплее обновляются раз в две секунды

В данном устройстве показание положения относительно уровня моря именно высчитывается, а не измеряется. Расчет происходит по рекомендованной формуле из даташита упрощенного расчета положения относительно уровня моря в зависимости от атмосферного давления. Как известно, чем выше мы находимся, тем давление атмосферы меньше. Именно эта зависимость и используется при расчете. Однако, в связи с тем что для любой отдельной территории погода может меняться, а вместе с ней и атмосферное давление будет колебаться. Исходя из этих размышлений, а также опытных наблюдений, положение над уровнем моря будет постоянно плавать в зависимости от колебаний атмосферного давления (по идеи то высота не должна изменяться с такой скоростью). Эта функция рассматривается как дополнительная и не совсем достоверная (уровень над морем в течении дня может плавать плюс минус процентов 5 - а это много, я считаю). Но именно атмосферное давление измеряется данным датчиком вполне точно - совпадение с текущим прогнозом погоды от полного до расхождения не более одного процента. Температура в данном датчике измеряется также весьма точно.

Как вывод могу сказать, что данный датчик атмосферного давления выполняет свои основные функции очень даже не плохо и может сгодиться для домашней метеостанции, которой мы и займемся в скором будущем.

Для программирования микроконтроллера Atmega8 необходимо знать конфигурацию фьюз битов (скриншот сделан в программе AVR Studio):

К статье прилагается прошивка для микроконтроллера, полный исходный код для данного устройства для работы с датчиком BMP180 в AVR Studio документация на датчик, а также небольшое видео, демонстрирующее работоспособность схемы (наблюдаем как изменяются параметры, если зажать датчик атмосферного давления пальцем руки).

Список радиоэлементов

Обозначение Тип Номинал Количество ПримечаниеМагазинМой блокнот
IC1 МК AVR 8-бит
ATmega8
1 Поиск в LCSCВ блокнот
IC2 ИС I2C интерфейса
PCA9517
1 Поиск в LCSCВ блокнот
IC3 Датчик атмосферного давленияBMP1801 Поиск в LCSCВ блокнот
VR1 Линейный регулятор
L7805AB
1 Поиск в LCSCВ блокнот
VR2 Линейный регулятор
AMS1117-3.3
1 Поиск в LCSCВ блокнот
VD1-VD4 Выпрямительный диод
1N4007
4 Поиск в LCSCВ блокнот
HG1 LCD-дисплейSC16021 На базе HD44780Поиск в LCSCВ блокнот
S1 Тактовая кнопкаTC-A1091 Поиск в LCSCВ блокнот
Tr1 ТрансформаторBV EI 382 11891 220В - 9В ACПоиск в LCSCВ блокнот
R1 Резистор
22 Ом
1 Поиск в LCSCВ блокнот
R2 Подстроечный резистор10 кОм1 Поиск в LCSCВ блокнот
R3-R7 Резистор
10 кОм
5 Поиск в LCSCВ блокнот
C1, C3-C5, C7, C8 Конденсатор100 нФ6 Поиск в LCSCВ блокнот
C2, C6, C9 Электролитический конденсатор220 мкФ3 Поиск в LCSCВ блокнот
Добавить все

Скачать список элементов (PDF)

Прикрепленные файлы:

Теги:

Опубликована: Изменена: 11.08.2014 0 2
Я собрал 0 0
x

Оценить статью

  • Техническая грамотность
  • Актуальность материала
  • Изложение материала
  • Полезность устройства
  • Повторяемость устройства
  • Орфография
0

Средний балл статьи: 0 Проголосовало: 0 чел.

Комментарии (42) | Я собрал (0) | Подписаться

+1
Zlodey #
Можно было обойтись без PCA9517. Просто подключив подтягивающие резисторы шины к цепи +3.3в и запитав PCA9517 от 3.3в
Ответить
0

[Автор]
Gauss #
Можно и обойтись совсем без нее тогда. В статье указывал, что уровни согласовывать не обязательно, но желательно
Ответить
0
Александр #
Отличная прошивка! Спасибо! Только я согласователь уровней сделал на двух транзисторах.И есть расхождения примерно 20 мм со стрелочным барометром. Как бы подкорректировать?
Ответить
0

[Автор]
Gauss #
Даташит гласит, что эти датчики полностью калиброваны и коэффициенты зашиты уже в нем, а вообще просто ввести еще свой коэффициент и домножать на него финальный результат, например
Ответить
0

[Автор]
Gauss #
У меня кстати, с точностью до 1 мм показывает - все предельно точно, странно, может стрелочный у вас врет
Ответить
0
alex000000 #
Согласование уровней можно не делать. Я запитал дисплей от 5 вольт, а всю остальную схему от 3,3 вольт и всё прекрасно работает.
Ответить
0
alex000000 #
Разобрался по внимательнее с модулем. В этой схеме не нужен стабилизатор 3,3 вольта, микросхема согласования уровней и резисторы подтяжки. Всё это встроено в сам модуль и его надо подключать напрямую к МК, что я и сделал.
Ответить
0
Tonus #
Подскажите в чем у меня "засада"?
Собрал данное устройство на ATmega16, все работает, вот только высота отображается с ошибкой т.е. в первом символе (старший разряд) непонятные значки, а три следующие все в порядке прим.:( ?256).
Ответить
0

[Автор]
Gauss #
Косяк в прошивке
Ответить
0
Tonus #
Оказывается по умолчанию у меня была отрицательная высота ( - 33 м), короче "ихтиандры" мы тут :) Хотя давление вроде правильно показывает. Значит знак "минус" тут ни как? В принципе я нырять не собираюсь, летать буду :)
Ответить
0
normo #
Вместо альтитуды просится 18b20 во дворе.
Ответить
0

[Автор]
Gauss #
Чаво?
Ответить
0
Ал #
Почему при каждом новом включении показывается разная высота?
Ответить
0

[Автор]
Gauss #
Ответ сокрыт или в датчике, или в качестве изготовления схемы
Ответить
0
Ал #
Как понять? Мы же здесь говорим о bmp180, схема с ебау. А у вас как? Соответствует реальной высоте?
Ответить
0

[Автор]
Gauss #
У меня высота соответствует +- 5% и она не меняется при каждом включении - показывает все нормально (но в зависимости от погоды в разное календарное время - высота может быть с погрешностью из-за природного атмосферного давления, которое может немного повышаться или понижаться), если хотите качественные ответы - качественно старайтесь задать вопрос, уточняя все нюансы.
Ответить
0
Ал #
Благодарю за подробный ответ! У меня при каждом включении утром значение высоты может отличаться от предыдущего +- 20-30%. Но в течение дня высота практически не меняется, те же +-5%. Но значения дециметров меняются при каждом запросе данных.
Температура определяется в норме относительно ds18b20.
Может подскажите, как отображается отрицательная температура у bmp180? Т.е знак минус нужно программно прописывать?
Ответить
0

[Автор]
Gauss #
В даташите есть пример получения данных от датчика - там лучше на примере разжевано, чем я объясню на словах
Последите за прогнозом погоды и сравните достоверность показаний давления, у меня отличалось +- несколько мм рт ст максимум независимо от времени суток относительно текущих данных прогноза в интернете (не на всех сайтах погода обновляется несколько раз в день)
Ответить
0
Ал #
Даташит зачитан...
Хочу поблагодарить за хороший пример работы датчика!
Я задаю вопросы только лишь выяснить как правильно работает мой датчик. Просто сравнить не с чем и не где.
Успехов!
Ответить
0

[Автор]
Gauss #
Говорю же сайты с погодой и геологическими данными
Ответить
0
Андрей #
Измерение высоты над уровнем моря в данном случае вообще не возможно. Разве что примерно.
Ответить
0

[Автор]
Gauss #
Да ладно? Подставляй значение текущего давления над уровнем моря и будет счастье
Ответить
0
kk042fjv #
Подскажите как минусовую температуру получить, показывает набор символов. Плюсовую и давление хорошо показывает.
Ответить
0

[Автор]
Gauss #
По принципу перевода двоичной системы в отрицательное, все просто
Ответить
0
bokorez #
А кто нибудь пробовал прикрутить к сему девайсу дисплей от нокии 3310 или 5510?
Ответить
0

[Автор]
Gauss #
Выполнимо
Ответить
0
savantik #
Я так понял что фьюзы должны быть такими:
Прикрепленный файл: 2016-01-13_230600.jpg
Ответить
0
savantik #
А можно и вот так! Если взять Atmega8А или Atmega8L, то и саму микросхему можно запитать от 3.3 вольта.
Прикрепленный файл: Barometr_variant_4.jpg
Ответить
0
savantik #
Не правильно показывает высоту над уровнем моря, мой город находится на высоте 80 - 120 метров. Отображается очень странно, впереди символ q.
Прикрепленный файл: IMAG0257.jpg
Ответить
0

[Автор]
Gauss #
Это значит пошло в отрицательное значение - что-то значит начудил с кодом или купил бракованный датчик
Ответить
0
savantik #
Ни чего не чудил, прошивку взял отсюда с этого сайта, температуру показывает правильно, давление то же правильно, а вот высота не правильно, что то может с прошивкой? Если есть у вас ваша рабочая прошивка то дайте мне я сравню Хэш-суммы.
Отредактирован 25.01.2016 22:27
Ответить
0

[Автор]
Gauss #
Вот скажи, какой смысл нерабочую прошивку прикреплять к статье? Может твой город ниже уровня моря, мало ли? Попробуй другой датчик
Ответить
0
logo374 #
Интересная схема, за что спасибо! Собирал на беспаячной макетке. Давление показывает с разностью 1мм от другого устройства с таким же датчиком. А вот с высотой что-то не пойму- в 3 с лишним раза завышено с официальными данными. Показывает 524м, а реально 160.
Ответить
0

[Автор]
Gauss #
Попробуй открыть сайт с погодой и посмотри сколько в данный момент давление в местности на берегу моря и подставить его в формулу - может получиться точнее, так как тут зависимость от этого, описанная выше, но вообще это слишком большое расхождение
Ответить
0
logo374 #
Gauss, теперь я вообще ничего понять не могу. Оставлял включённым на ночь, утром гляжу, а на экране высота уже 60м и до сих пор. И да, вчера вместо 0 тоже был символ "q", где высота.
Ответить
0

[Автор]
Gauss #
Короче точные показания только если постоянно подставлять текущее значение давления над уровнем моря, q - это ниже уровня моря - я не закладывал расчет ниже уровня моря, это типа обозначение ошибки такое. Ну погода у нас такая непонятная - то снег, то дождь, то солнце в один день, вот и скачет из-за константного значения давления над уровнем моря в формуле
Ответить
0
logo374 #
Gauss, понятно. Да и ну ее эту высоту, главное давление и температуру показывает достаточно точно. Давление можно тоже сделать с точностью до десятых. И ещё не плохо было бы прикрутить датчик BME280 (тоже самое, что и BMP180+влажность), хоть пока дороговат, но все же. Желаю творческих успехов!
Ответить
0

[Автор]
Gauss #
Скоро датчик приедет! Спасибо!
Ответить
0
Павел #
Электросхему можно было бы и исправить. Во-первых, мега отлично будет работать и от 3,3В (возможно, не все меги), поэтому никаких согласований не нужно. 5В может понадобится только для подсветки дисплея. Во-вторых, конденсаторы С3 и С4 стоят параллельно, а значит их можно заменить одним.
Ответить
0
Артур #
А уснановить нулевою точку можно? Например стандартные 1013 гПа, или текущее атмосферное?
Ответить
0

[Автор]
Gauss #
Не понял я вас до конца...
Ответить
0
Сергей #
Запитал мегу 3,3В, работал с мая месяца нормально. Пока с тумбочки не упал, наверное накрылась ВМР180. Заказал другую, убитая по сравнению с местной метеостанцией не врала.
Ответить
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется напряжение?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

Программатор Pickit3
Программатор Pickit3
UNI-T UT-61A МиниПК MK809V - 4 ядра, Android 4.4.2
вверх