Датчик абсолютного давления и температуры (последним сегодня уже никого не удивишь) Bosch BMP180. Датчик не нов и хорошо известен, datasheet изучен вдоль и поперек, а библиотек целая куча.
Характеристики :
- Диапазон измерения давления: 300 – 1100 hPa.
- Напряжение питания: от 1.8 — 3.3 и 5V(если на плате стоит стабилизатор напряжения).
- Низкое энергопотребление: 3 мкА (режим ультра-низкого энергопотребления)
- Точность: режим пониженного энергопотребления, разрешение 0.06hPa (0,5 м).
- Высокий линейный режим с разрешением 0.02hPa (0,17 м).
- Подключение: интерфейс I2C.
- Возможность измерения температуры в диапазоне -40 … +85 ° C.
- Время отклика: 5ms — 7.5ms (standart mode).
- Ток в режиме ожидания: 0,1 мкA
Более подробно можно прочитать в Datasheet.
Принцип действия датчика BMP180:
В датчике имеется герметичная камера, одна из стенок которой является гибкой мембраной с установленными на ней тензодатчиками. Мембрана прогибается пропорционально разности давлений внутри камеры и снаружи, что влияет на изменение сопротивления тензодатчиков электрическому току. Так же имеется термодатчик, сопротивление которого меняется пропорционально температуре. АЦП (аналого-цифровой преобразователь) переводит результаты изменений датчиков в цифровые данные «некомпенсированные результаты», которые доступны для чтения из регистров датчика: «Out MSB», «Out LSB» и «Out xLSB». Для компенсации указанных результатов (компенсации смещения, температурной зависимости, погрешностей при изготовлении, неоднородностей материалов и т.д.) каждый датчик калибруется на заводе, и в EEPROM записываются индивидуальные для каждого датчика 11 калибровочных коэффициентов
(176 бит), которые доступны для чтения из регистров датчика: «AC1», «AC2», «AC3», «AC4», «AC5», «AC6», «B1», «B2», «MB», «MC», «MD».
Не допускайте попадания на датчик влаги и прямых солнечных лучей.
Алгоритм получения данных:
- Чтение калибровочных коэффициентов:
Чтение значений из одноименных регистров:
short AC1, AC2, AC3, B1, B2, MB, MC, MD;
unsigned short AC4, AC5, AC6;
- Чтение температуры: (некомпенсированное значение)
Записываем в регистр «Measurement Control» значение: 0x2E;
Ожидаем спад флага состояния «CSO» в «0»;
Читаем результат из регистров «Out MSB» и «Out LSB»;
- Чтение давления: (некомпенсированное значение)
Записываем в регистр «Measurement Control» значение: 0x34 + (OSS<<6);
Ожидаем спад флага состояния «CSO» в «0»;
Читаем результат из регистров «Out MSB», «Out LSB» и «Out xLSB»;
long UP = («Out MSB»<<16 + «Out LSB»<<8 + «Out xLSB») >> (8-OSS);
- Вычисление действительных значений
Код и подключение.
Датчик достаточно популярный. Чаще всего он идет уже с обвязкой в виде готового модуля. Вы без труда найдете много разных, готовых библиотек. Я остановился на BMP180_Breakout_Arduino_Library. Скачать можно с GitHub или с нашего сайта.
Подключение описано в библиотеке, но я его продублирую на всякий случай:
SCL(clock)
- Uno,Nano,Pro к А5
- Mega,Due к 21
- Leonardo к 3
SDA(Data)
- Uno,Nano,Pro к А4
- Mega,Due к 20
- Leonardo к 2
VIN — к +5 вольта.
IO — Этот вывод есть на некоторых платах, питание в обход стабилизатора. НЕ больше 3.3 вольта.
GND — подключаем к минус.
Ну вот примерочный код с пояснениями :
#include <SFE_BMP180.h> #include <Wire.h> // Объявим переменную для доступа к SFE_BMP180: SFE_BMP180 pressure; #define ALTITUDE 203.0 // высота над уровнем моря в метрах. void setup() { Serial.begin(9600); Serial.println("REBOOT"); // инициализация if (pressure.begin()) Serial.println("BMP180 init ok"); else { // Если мы тут то что-то не срослось. Как правило косяки с подключением Serial.println("BMP180 init fail\n\n"); while(1); // зависаем } } void loop() { char status; double T,P,p0,a; // Если вы хотите знать давление воздуха, откорректированное по уровню моря, которое обычно используется в прогнозах погоды // Вам надо знать уровень моря в вашей местности где проводится замер // Ее и надо указать в константе ALTITUDE в начале кода Serial.println(); Serial.print("Уровень моря: "); Serial.print(ALTITUDE,0); Serial.print(" метров, "); Serial.print(ALTITUDE*3.28084,0); Serial.println(" футов"); // Если вы хотите наоборот узнать высоту над уровнем моря, а давление вам известно // надо указать текущее атмосферное давление. Как это сделать написано в конце кода. // Если все ровно, pressure.startTemperature вернет в status количество милисекунд, // которое нужно подождать для замера температуры // Если какой-то ошибка, вернет 0 status = pressure.startTemperature(); if (status != 0) { // ждем: delay(status); // Получаем температуру // Функция вернет 1 если все ОК, 0 если не ОК status = pressure.getTemperature(T); if (status != 0) { Serial.print("Температура: "); Serial.print(T,2); Serial.print(" градусов C, "); // в цельсиях Serial.print((9.0/5.0)*T+32.0,2); Serial.println(" градусов F"); // в фаренгейтах // Определяем атм. давление: // Параметр указывает разрешение, от 0 до 3 (чем больше разрешение, тем выше точность, тем дольше ждать). status = pressure.startPressure(3); if (status != 0) { delay(status); // Теперь можно получить давление в переменную P. //Функция вернет 1 если все ОК, 0 если не ОК. status = pressure.getPressure(P,T); if (status != 0) { Serial.print("Абсолютное давление: "); Serial.print(P,2); Serial.print(" миллибар, "); //millibar (mb) Serial.print(P*0.750064,2); Serial.println(" мм ртутного столба"); // Параметры: P = давленик с датчика в миллибарах, ALTITUDE = высота над уровнем моря в метрах. // Результат: p0 = давление, откорректированное по уровню моря p0 = pressure.sealevel(P,ALTITUDE); Serial.print("Давление по уровню моря: "); Serial.print(p0,2); Serial.print(" миллибар, "); Serial.print(p0*0.750064,2); Serial.println("мм ртутного столба"); // Или если вы хотите сделать наоборот и определить высоту над уровнем моря по известному давлению, // Parameters: P = давление с датчика в миллибарах, p0 = давление, откорректированное по уровню моря. // Результат: a = высота над уровнем моря в метрах. a = pressure.altitude(P,p0); Serial.print("Рассчитанная высота над уровнем моря: "); Serial.print(a,0); Serial.print(" метров, "); Serial.print(a*3.28084,0); Serial.println(" футов"); } else Serial.println("ошибка получение давления\n"); } else Serial.println("ошибка запуска получения давления\n"); } else Serial.println("ошибка получения температуры\n"); } else Serial.println("ошибка запуска получения температуры\n"); delay(5000); // пауза 5 секунд. }
выводит какуето чепуху за место русских слов выводит знаки вопроса
что делать?
Это проблема кодировки. Поищите в вашем терминали настройки кодировки.