BMP580 – это цифровой датчик абсолютного атмосферного давления и температуры, разработанный компанией Bosch Sensortec. Он является идейным наследником моделей BMP180/280/380. Но, в отличие от них, 580-я модель является принципиально новым поколением барометров, которое предлагает значительно более высокую точность и энергоэффективность, а также расширенные функциональные возможности. Разработчикам удалось добиться более низкого уровня шума, высокой стабильности показаний и минимального дрейфа, благодаря чему 580-й чип идеально подходит для портативных устройств, навигационного оборудования и систем мониторинга высоты.
Этот материал из цикла статей о сенсорах атмосферного давления Bosch. Рекомендую ознакомиться с основами и более ранними моделями:
– BMP180: как устроен пьезорезистивный чувствительный элемент, собираем высотомер;
– BMP280 + AHT20: устройство и принцип работы полимерного емкостного гигрометра, создаём домашнюю метеостанцию:
– BME280: климатический датчик «3 в 1», метеостанция и высотомер.

Содержание
- Общее описание
- Параметры и характеристики
- Режимы работы и настройка
- Буфер FIFO
- Схема подключения
- Программный код (скетч)
- Заключение
Общее описание
BMP580 нельзя назвать просто «улучшенная версия 380-й модели». Это представитель четвертого поколения сенсоров Bosch Sensortec, выпущенный в 2022 году. Он также построен по технологии MEMS (Micro-Electro-Mechanical Systems – микроэлектромеханическая система), но при этом его внутреннее устройство было значительно переработано с целью повышения энергоэффективности. Это обусловлено продуманной архитектурой питания: раздельные аналоговый и цифровой регуляторы напряжения, а также оптимизированный источник опорного напряжения. Всё это позволяет минимизировать потери в состоянии ожидания и при активной работе.
По аналогии с предыдущими моделями, 580-я также имеет барометрический преобразователь и термометр. Однако в официальной документации не упоминается тип чувствительных элементов. Возможно, барометр основан на классических для сенсоров Bosch пьезорезистивных элементах, или же используется емкостной полимерный чувствительный элемент как, например, на DPS310. Термометр, скорее всего, является типичным полупроводниковым преобразователем температуры, который играет крайне важную роль для обеспечения термокомпенсации при регистрации давления.
BMP580 измеряет абсолютное атмосферное давление в диапазоне от 300 до 1100 гПа с точностью ±30 Па при температуре от -5 °C до +65 °C, а во всём рабочем диапазоне температур погрешность составляет ±75 Па.
Относительная точность – погрешность определения разницы давлений между двумя точками по высоте без учёта ошибки нулевого уровня – составляет ±6 Па, что очень важно при фиксации изменений относительной высоты.
Чип также определяет температуру (подразумевается температура кристалла микросхемы для термокомпенсации показаний давления) с погрешностью ±0,5 °C. Измерять температуру воздуха будет не совсем корректно (можно ожидать погрешность примерно ±1…2 °C) из-за саморазогрева и теплового сопротивления корпуса микросхемы.
Одним из явных преимуществ нового чипа является наличие аппаратного накопителя FIFO (First In, First Out), который накапливает до 32 измерений. Это позволяет управляющему микроконтроллеру реже обращаться к датчику, что в высоконагруженных приложениях позволяет освободить процессор на более приоритетные задачи.
Ближайшим аналогом для BMP580 является датчик DPS310 от компании Infineon. У данного конкурента абсолютная погрешность на всём диапазоне составляет ±100 Па (против ±75 Па). Но важно отметить, что если выполнить калибровку хотя бы по 1 точке, то погрешность снизится до ±10 Па. При этом относительная точность аналогична устройству от Bosch: ±6 Па.
Интересной альтернативой может послужить ENS220 от компании ScioSense. Точность несколько хуже (±50 Па против ±30 Па), зато ниже энергопотребление и более точный термометр (±0,1 °C против ±0,5 °C).
Бюджетной альтернативой является сенсор LPS22HB от компании STMicroelectronics. У данной модели погрешность на всём диапазоне составляет ±100 Па, а после одноточечной калибровки можно достичь ±10 Па. Также есть буфер FIFO, но при этом уступает в скорости по I2C (400 кГц).
Чуть лучшее качество и точность у BMP581 – это флагманская модель четвёртого поколения преобразователей Bosch.
На рисунке ниже представлена упрощённая блок-схема из официальной документации:

Микросхема включает в себя следующие основные блоки:
– чувствительные элементы (pressure/temperature sensing element);
– аналоговые входные цепи (analog front-end), которые включают в себя мультиплексор для согласования аналоговых преобразователей с входом аналого-цифрового преобразователя (A/D);
– логический блок (Logic) обработки данных и калибровочных коэффициентов. Этот блок цифровые значения, получаемы от A/D, корректирует с помощью заводских калибровочных коэффициентов, которые хранятся в энергонезависимой памяти (NVM – Non-Volatile Memory);
– встроенные раздельные стабилизаторы напряжения для цифровой и аналоговой части микросхемы (analog voltage regulator, digital voltage regulator), а также источник опорного напряжения (voltage reference);
– схема автоматического сброса по питанию (POR – Power-On Reset);
– генератор тактовых импульсов (OSC – Oscillator), обеспечивает функционирование A/D, внешних интерфейсов I2C, I3C и SPI, а также цифрового IIR-фильтра с бесконечной импульсной характеристикой (IIR – Infinite Impulse Response);
– блок буферной памяти (FIFO-memory), работа которой организована по принципу очереди (первые поступившие данные считываются первыми). В буфере накапливаются результаты измерений (до 32) давления и/или температуры, благодаря чему ведущий микроконтроллер «спит» (экономия энергии) или ресурсы перераспределены на другие более приоритетные задачи. Таким образом, данный блок позволяет считывать данные пакетами, а не запрашивать каждое измерение по отдельности.
Параметры и характеристики
Ниже в таблице приведены основные параметры и характеристики датчика BMP580:

Режимы работы и настройка
По аналогии с BME280, пользователю предоставляется возможность производить гибкую настройку микросхемы, программно задавая различные сценарии с более широкой вариативностью параметров.
После подачи питания или сброса датчик по умолчанию находится в состоянии DEEP STANDBY (глубокий сон, максимальное энергосбережение). В состоянии STANDBY чип просто ожидает и не собирает данные, но предоставляет доступ ко всем регистрам.
Нужно отметить, что DEEP STANDBY не является отдельным режимом, а это особое состояние внутри STANDBY. Поэтому, чтобы DEEP STANDBY автоматически активировался, нужно выполнить три условия:
– запросить STANDBY или NORMAL с паузами между опросом чувствительных элементов;
– частота ODR менее 5 Гц;
– отключить FIFO и IIR-фильтр.
Если хотя бы одно из условий будет нарушено, то чип перейдёт в состояние STANDBY. Чтобы перевести чип из одного активного режима в любой другой (FORCED, NORMAL, CONTINUOUS) и при этом изменить какие-либо конфигурации (для фильтра, накопителя или параметры опроса чувствительных элементов), необходимо сначала перейти в STANDBY/ DEEP STANDBY, а уже потом – в нужное состояние.

Кратко рассмотрим каждый сценарий:
1. Глубокий «сон» (DEEP STANDBY)
Высокая энергоэффективность достигается не только особенностями топологии микросхемы, но и тотальным отключением всех лишних блоков (фильтры, буфер накопления данных, минимальная частота опроса чувствительных элементов), что соответствует состоянию глубокого «сна» (0,55…1,5 мкА);
2. Режим ожидания (STANDBY)
Измерения не производятся, энергопотребление минимально (1,0…5,5 мкА). Все регистры доступны для чтения и записи, накопитель FIFO сохраняет своё содержимое. Это состояние является базовым для настройки датчика перед переходом в активные;
3. Одиночное измерение (FORCED)
При активации данного состояния выполняется только один цикл измерений (давление и/или температура – в зависимости от настроек), сохраняются результаты в регистры данных, после чего автоматически возвращается в STANDBY. Следующий цикл требует повторной активации FORCED. Такой подход применяется в батарейных устройствах с низкой частотой опроса (например, в карманных высотомерах, которые просыпаются раз в минуту).
При одиночных операциях допускается использовать IIR-фильтр, а также определять параметр Oversampling (OSR) – количество внутренних измерений, усредняемых для получения одного выходного значения;
4. Непрерывные измерения с паузами (NORMAL)
Сенсор работает циклически, чередуя активную фазу и период ожидания. Частота выдачи результатов (Output Data Rate – ODR) задаётся в регистре ODR_CONFIG и может принимать значения от 0,125 Гц до 240 Гц. Внутри цикла регистрация проводится с выбранным числом выборок (OSR), затем чип «засыпает» на заданный интервал времени. NORMAL режим оптимален для приложений, где требуется регулярный сбор данных, например в метеостанциях, навигационных устройствах или в системах мониторинга высоты.
Отметим, что если выполняются все условия для DEEP STANDBY (ODR менее 5 Гц, FIFO и IIR-фильтр отключены), то состояние NORMAL автоматически использует глубокий «сон» между измерениями, что значительно снижает энергопотребление. Это так называемый Low Power NORMAL mode. Но если изменить хотя бы одну из настроек (включение FIFO или фильтра, повышение ODR), то датчик перейдёт в обычный NORMAL;
5. Непрерывные измерения без пауз (CONTINUOUS)
В отличие от NORMAL, здесь пауза между опросами отсутствует – сенсор работает на максимальной скорости, определяемой выбранным параметром OSR. При этом частота выдачи данных ODR игнорируется. Этот режим подходит для задач, где критически важна высокая частота обновления данных. Например, для отслеживания быстрых изменений высоты.
Как Вы могли понять из представленных выше описаний, гибкость настройки чипа определяется вариативностью трёх параметров:
– частота выдачи результатов (ODR – Output Data Rate);
– количество внутренних измерений (OSR – Oversampling);
– коэффициент фильтрации (IIR – Infinite Impulse Response).
Для экспериментов с BMP580 на базе ESP32 и среды разработки Arduino IDE будем применять библиотеку Adafruit_BMP5xx_Library, которую можно установить через менеджер библиотек:

Все дальнейшие примеры и объяснения по настройке параметров будут сопровождаться выдержками кода с применением данной библиотеки.
Output Data Rate (ODR)
Output Data Rate – это частота (количество операций в секунду), с которой датчик выполняет регистрацию в режиме NORMAL. Ниже представлена таблица значений ODR из даташита:

Частота менее 5 Гц является необходимым условием для входа в состояние DEEP STANDBY (максимальная экономия энергии).
При таком наборе вариаций легко можно ошибиться в процессе настройки, но разработчики это предусмотрели. Дело в том, что не все комбинации ODR и OSR допустимы. То есть, если время измерения (зависит от OSR) больше интервала ODR, то датчик автоматически подставит корректные OSR.
Например, при величинах ODR более 160 Гц параметр OSR будет принудительно присвоено x1, а при ODR менее 160 Гц параметр OSR будет равен x2. В режиме CONTINUOUS параметр ODR не применяется, поскольку там опрос чувствительных элементов идёт с максимальной скоростью, которая настраивается через OSR.
#include <Adafruit_BMP5xx.h>
Adafruit_BMP5xx bmp;
// Установка режима NORMAL (обязательно для ODR)
bmp.setPowerMode(BMP5XX_POWERMODE_NORMAL);
// Примеры установки разных частот
bmp.setOutputDataRate(BMP5XX_ODR_30_HZ); // 30 Гц
bmp.setOutputDataRate(BMP5XX_ODR_10_HZ); // 10 Гц
bmp.setOutputDataRate(BMP5XX_ODR_1_HZ); // 1 Гц
bmp.setOutputDataRate(BMP5XX_ODR_0_125_HZ); // 1 раз в 8 секунд
// Получение текущего значения ODR
bmp5xx_odr_t current_odr = bmp.getOutputDataRate();
Некоторые рекомендации по выбору величин ODR:

Кстати, при ODR=240 Гц значение OSR автоматически будет установлено в значение x1, поскольку время измерения большего OSR не влезает в интервал 4,17 мс (об этом в подразделе про OSR).
Чтобы избежать ошибок и недопонимания при получении неадекватных данных, стоит обращать внимание на несколько нюансов:
– ODR игнорируется в CONTINUOUS режиме;
– если будет слишком высокий OSR и при этом высокий ODR, то сенсор автоматически понизит OSR, поэтому рекомендуется выполнять проверку через функцию bmp.getPressureOversampling() после установки;
– если читать данные с частотой ниже значения ODR, то можно потерять часть данных, потому как данные в регистрах перезаписываются новыми данными;
– состояние DEEP STANDBY не работает при ODR более 5 Гц, поэтому сенсор будет оставаться в STANDBY между операциями опроса чувствительных элементов.
Oversampling Ratio (OSR)
Oversampling Ratio – это количество внутренних «сырых» измерений, которые усредняются для получения одного выходного результата. Чем выше OSR, тем меньше шум, но дольше время на опрос и выше энергопотребление. Ниже представлена таблица значений OSR из официальной документации от производителя:

OSR настраивается независимо для давления и температуры. Однако нельзя одновременно и для давления, и для температуры уставить выборку x128. Поэтому в даташите приводится таблица с рекомендованными значениями:

Как видно, приоритет у давления, и если для него установить x128, то для температуры будет максимум x8. При некорректной ручной установке каких-либо параметров чип сам подкорректирует значения, которые будут соответствовать таблице.
Также следует помнить, что чем больше число выборок, тем дольше время измерения, а это ограничивает максимальную частоту (количество операций в секунду).
Пример кода с настройкой Oversampling
#include <Adafruit_BMP5xx.h>
Adafruit_BMP5xx bmp;
void setup() {
Serial.begin(115200);
if (!bmp.begin()) {
Serial.println("Sensor not found");
while (1);
}
// Установка OSR для давления
bmp.setPressureOversampling(BMP5XX_OVERSAMPLING_16X);
// Установка OSR для температуры
bmp.setTemperatureOversampling(BMP5XX_OVERSAMPLING_2X);
// Установка режима NORMAL
bmp.setPowerMode(BMP5XX_POWERMODE_NORMAL);
// Получение текущих настроек
bmp5xx_oversampling_t osr_p = bmp.getPressureOversampling();
bmp5xx_oversampling_t osr_t = bmp.getTemperatureOversampling();
Serial.print("Pressure OSR: "); Serial.println(osr_p);
Serial.print("Temperature OSR: "); Serial.println(osr_t);
}
void setupSensor() {
// Сначала устанавливаем желаемый ODR
bmp.setOutputDataRate(BMP5XX_ODR_30_HZ); // 30 Гц
// Устанавливаем OSR
bmp.setPressureOversampling(BMP5XX_OVERSAMPLING_16X);
bmp.setTemperatureOversampling(BMP5XX_OVERSAMPLING_2X);
// Проверяем, что ODR допустим для этих OSR
// Датчик сам скорректирует, если комбинация невалидна
// Можно проверить эффективные настройки:
bmp5xx_oversampling_t eff_osr_p = bmp.getPressureOversampling();
if (eff_osr_p != BMP5XX_OVERSAMPLING_16X) {
Serial.println("Warning: OSR was reduced due to ODR limit");
}
// Включаем измерения
bmp.enablePressure(true);
bmp.setPowerMode(BMP5XX_POWERMODE_NORMAL);
}
Некоторые рекомендации по выбору значения OSR:

IIR-фильтр (бесконечная импульсная характеристика)
Для подавления кратковременных шумов (хлопки дверей, ветер, вибрации) в BMP580 встроен цифровой IIR-фильтр (Infinite Impulse Response) низких частот. Он сглаживает шум, усредняя текущие значения с предыдущими, и применяется независимо к давлению и температуре в NORMAL или CONTINUOUS режимах. Фильтр реализует рекурсивное усреднение, при этом коэффициент фильтрации можно задавать программно. Ниже представлена таблица возможных значений коэффициентов и соответствующая характеристика работы фильтра:

Чем выше коэффициент, тем сильнее сглаживание, но медленнее реакция на резкие изменения. Например, при ODR=10 Гц и коэффициенте 127 время установления составит теоретически 25 секунд. То есть, к примеру, при падении устройства с третьего этажа изменение давления произойдёт за 1-2 секунды, но из-за высокого коэффициента сглаживания IIR-фильтра показания будут меняться с высокой инерцией в течение более 10…20 секунд.
Некоторые рекомендации по конфигурации:

Первое измерение после пробуждения (переход из STANDBY в активный режим) фильтруется некорректно, поскольку внутренняя память фильтра сбрасывается. Новый цикл снятия данных уже «подтянет» конфигурацию фильтра.
Особо отмечу, что нужно понимать то, как сглаживает фильтр: новое значение вычисляется на основе предыдущего сглаженного результата, а не «сырых» данных. Соответственно, чем выше выбран коэффициент, тем больший вес в расчете имеет история предыдущих собранных данных.
Библиотека Adafruit_BMP5xx не предоставляет возможность раздельно устанавливать коэффициент фильтрации отдельно для давления и отдельно для температуры. Конфигурация производится одним методом, присваивая одинаковые значения для обоих параметров. Для раздельной настройки коэффициентов фильтрации можно использовать регистры.
Пример конфигурирования IIR-фильтра
#include <Wire.h>
#include <Adafruit_BMP5xx.h>
// Настройки I2C
#define I2C_SDA 2
#define I2C_SCL 3
Adafruit_BMP5xx bmp;
void setup() {
Serial.begin(115200);
// Инициализация I2C с пользовательскими пинами
Wire.begin(I2C_SDA, I2C_SCL);
if (!bmp.begin(0x46, &Wire)) {
Serial.println("BMP580 not found!");
while (1);
}
// Настройка ODR и OSR через библиотеку
bmp.setOutputDataRate(BMP5XX_ODR_10_HZ);
bmp.setPressureOversampling(BMP5XX_OVERSAMPLING_16X);
bmp.setTemperatureOversampling(BMP5XX_OVERSAMPLING_2X);
bmp.enablePressure(true);
bmp.setPowerMode(BMP5XX_POWERMODE_NORMAL);
// Настройка IIR-фильтра средствами Adafruit_BMP5xx (одинаково для давления и температуры)
bmp.setIIRFilterCoeff(BMP5XX_IIR_FILTER_COEFF_7);
// Либо - раздельная настройка через регистры
// --------------------------участок кода для раздельной настройки IIR-фильтра
// Переводим в STANDBY (обязательно для записи DSP_IIR)
bmp.setPowerMode(BMP5XX_POWERMODE_STANDBY);
delay(3);
// Читаем текущий регистр DSP_IIR (0x31)
uint8_t reg;
Wire.beginTransmission(0x46);
Wire.write(0x31);
Wire.endTransmission(false);
Wire.requestFrom(0x46, (uint8_t)1);
reg = Wire.read();
// Устанавливаем:
// - давление: коэффициент 7 (0b011)
// - температура: коэффициент 1 (0b001)
reg = (reg & 0xC0) | (0b011 << 3) | 0b001;
// Записываем обратно
Wire.beginTransmission(0x46);
Wire.write(0x31);
Wire.write(reg);
Wire.endTransmission();
// --------------------------участок кода для раздельной настройки IIR-фильтра
// Переход в режим NORMAL
bmp.setPowerMode(BMP5XX_POWERMODE_NORMAL);
Serial.println("IIR: давление coeff=7, температура coeff=1");
}
void loop() {
if (bmp.performReading()) {
Serial.print("T: "); Serial.print(bmp.temperature);
Serial.print(" °C, P: "); Serial.print(bmp.pressure);
Serial.println(" hPa");
}
delay(1000);
}
Для общего понимания приведены примеры настройки параметров чипа для типовых сценариев. Примеры даны с учётом синтаксиса библиотеки Adafruit_BMP5xx.
1. Карманный высотомер (быстрая реакция на изменение высоты)
bmp.setPowerMode(BMP5XX_POWERMODE_NORMAL); // Режим NORMAL или CONTINUOUS
bmp.setOutputDataRate(BMP5XX_ODR_240_HZ); // Максимальная частота измерений
bmp.setTemperatureOversampling(BMP5XX_OVERSAMPLING_1X); // Минимальное количество выборок для скорости
bmp.setPressureOversampling(BMP5XX_OVERSAMPLING_1X); // Минимальное количество выборок для скорости
bmp.setIIRFilterCoeff(BMP5XX_IIR_FILTER_BYPASS); // Bypass – фильтр отключен
2. Домашняя метеостанция (высокая точность, низкая частота)
bmp.setPowerMode(BMP5XX_POWERMODE_NORMAL); // Режим NORMAL с длительной паузой (Low Power)
bmp.setOutputDataRate(BMP5XX_ODR_01_HZ); // Минимальная частота (редкие измерения)
bmp.setTemperatureOversampling(BMP5XX_OVERSAMPLING_128X); // Максимум точности
bmp.setPressureOversampling(BMP5XX_OVERSAMPLING_8X); // Максимум точности
bmp.setIIRFilterCoeff(BMP5XX_IIR_FILTER_COEFF_15); // Средняя фильтрация
Буфер FIFO
Аппаратный накопитель FIFO (First In, First Out) сохраняет результаты собранных данных, позволяя считывать их позже одной пачкой, а не в реальном времени.
Проще говоря, он нужен для того, чтобы разгрузить основной процессор (не нужно постоянно опрашивать датчик и читать данные). Это позволяет не пропустить данные, если процессор занят, а также экономит энергию (можно реже выходить из режима «сна»).
Если говорить чуть более подробно, то использование FIFO предоставляет несколько ключевых преимуществ по сравнению с работой без него. Например, без FIFO датчик требует постоянного опроса микроконтроллером после каждого измерения, что приводит к частым пробуждениям системы и, соответственно, повышенному энергопотреблению. Кроме того, если микроконтроллер не успевает вовремя считать данные, возникает риск их потери.
А вот при использовании FIFO микросхема сенсора самостоятельно сохраняет данные в своём хранилище, позволяя внешнему ведущему устройству считывать их пачками. И, вместо того, чтобы постоянно опрашивать сенсор, он может сам генерировать одно уведомление при заполнении буфера, что позволяет ведущему устройству дольше оставаться в спящем режиме и экономить энергию. Таким образом, накопитель FIFO делает систему «контроллер-сенсор» более энергоэффективной, надёжной и производительной, что особенно ощутимо в приложениях, где необходимы частые опросы и ограничено энергопотребление.
Для работы с FIFO предусмотрено несколько параметров:

Рассмотрим каждый из параметров чуть подробнее.
Буфер состоит из кадров (frames), и в каждом из них хранится по одному результату. Для определения типа кадра используется параметр FRAME_SEL:

Если накопитель пуст, то возвращается 0x7F, что соответствует пустому кадру.
Буфер FIFO может работать в двух режимах (параметр MODE):
– потоковый (streaming), при котором старые данные удаляются, а новые – записываются;
– остановка при заполнении (stop-on-full), при которой новые данные не записываются до тех пор, пока нет свободного места.
Для того, чтобы более эффективно и экономно (с точки зрения памяти и энергопотребления) использовать FIFO, разработчики предусмотрели возможность прореживания (децимации) данных. То есть сохраняется не каждое измерение, а только часть данных из общего потока, в зависимости от выбранной степени прореживания.
Работает это следующим образом: датчик продолжает выполнять сбор данных с заданной частотой ODR, но при этом в накопитель отправляется только каждый N-й результат.
Параметр N (в даташите именуется как DEC_SEL) может принимать следующие значения:

Рассмотрим простой пример. Частота опроса ODR = 10 Гц, при этом коэффициент прореживания DEC_SEL = 4. Допустим, каждые 100 миллисекунд выполняется измерение: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10… В буфер FIFO попадают: 1, 5, 9, 13… (то есть каждое 4-е). Остальные – теряются для накопителя.
Отметим, что коэффициент DEC_SEL можно менять только тогда, когда выполнен переход в состояние STANDBY.
Изменение DEC_SEL вызывает сброс FIFO, при этом все накопленные данные теряются.
Если внести какие-либо изменения в NORMAL/CONTINUOUS режиме, то они будут применены только после того, как будет осуществлена активация состояния STANDBY.
Разработчики микросхемы предусмотрели параметр THRESHOLD, который устанавливает число кадров, при заполнении которых датчик самостоятельно автоматически генерирует сигнал на пине INT (то есть создаёт сигнал прерывания), что можно использовать в микроконтроллере как команду на чтение данных. Это экономит энергию и упрощает работу контроллера. Таким образом, пока внешнее ведущее устройство «спит», сенсор собирает данные, а потом сигналом прерывания INT «будит» контроллер, чтобы он прочитал пакет данных.
Параметр THRESHOLD может иметь несколько значение:
– если FRAME_SEL установлен как «P + T», то максимальное число кадров THRESHOLD равно 16;
– если FRAME_SEL установлено либо только как «P», либо только как «T», то максимальное число кадров THRESHOLD равно 32;
– при значении 0 порог отключен и прерывание не генерируется.
В дополнение к параметру THRESHOLD предусмотрен регистр FIFO_COUNT, который показывает текущее количество заполненных кадров на момент запроса. Этот регистр используется в том случае, когда нет возможности организовать прерывание на микроконтроллере. Но поэтому потребуется постоянно опрашивать микросхему сенсора, чтобы мониторить заполненность накопителя.
Как уже было сказано ранее, библиотека Adafruit_BMP5xx не предоставляет методы для гибкой работы с FIFO-буфером. Но в состав библиотеки входят файлы bmp5 (описание Bosch API), в которых есть все необходимые функции для полноценной работы.
Примечание: для тестов с FIFO мы не будем трогать библиотеку, которая устанавливается через менеджер, чтобы не помешать Вашим будущим экспериментам.
Ниже предлагается исключительно только для тестирования простой способ провести практический эксперимент с накопителем. Для того, чтобы подключить эти файлы Bosch API к основному файлу библиотеки, рекомендуется выполнить следующие действия:
1) скачать архив библиотеки с репозитория на GitHub;
2) в папку со скетчем Вашей программы скопировать как отдельный экземпляр файл Adafruit_BMP5xx.h. Таким образом, тот файл, который является частью библиотеки, установленной через менеджер библиотек в среде программирования Arduino IDE, не будет изменён. Скопированный экземпляр файла Adafruit_BMP5xx.h будет только для текущего скетча с экспериментами;
3) откройте, например, через текстовый редактор «Блокнот» h-файл, и найдите там объявление класса Adafruit_BMP5xx (примерно ближе к концу файла). Код должен выглядеть так:
/**
* Driver for the Adafruit BMP5xx barometric pressure sensor.
*/
class Adafruit_BMP5xx {
public:
Adafruit_BMP5xx();
~Adafruit_BMP5xx(void);
bool begin(uint8_t addr = BMP5XX_DEFAULT_ADDRESS, TwoWire* theWire = &Wire);
bool begin(int8_t cspin, SPIClass* theSPI = &SPI);
float readTemperature(void);
float readPressure(void);
float readAltitude(float seaLevel = 1013.25);
// продолжение кода
Добавьте перед объявлением функции float readTemperature(void) следующую строчку:
// Публичный метод для доступа к структуре bmp5_dev
struct bmp5_dev* getDev(void) { return &_bmp5_dev; }
4) Теперь в основном файле скетча (файл с расширением .ino) нужно заменить #include <Adafruit_BMP5xx.h> на #include “Adafruit_BMP5xx.h (то есть вместо угловых скобок должны стоять кавычки). Это укажет компилятору использовать именно локальную версию h-файла библиотеки. После этого вы сможете вызывать bmp.getDev() для доступа к функциям Bosch API:
#include "Adafruit_BMP5xx.h" // Теперь использует локальную версию
Adafruit_BMP5xx bmp;
void setup() {
// некоторый код инициализации
// получаем указатель на внутреннюю структуру датчика (содержит все данные для общения с BMP580 через I2C-интерфейс
struct bmp5_dev* dev = bmp.getDev();
// передаём этот указатель в функцию настройки FIFO согласно параметрам, которые заданы в структуре fifo
bmp5_set_fifo_configuration(&fifo, dev); // Пример настройки FIFO
}
Для наглядности рассмотрим простой пример использования FIFO-буфера на практике. В течение 8 секунд сенсор будет самостоятельно накапливать данные: по 16 измерений давления и температуры, пока контроллер «спит» (сымитирована как пауза delay(waitTime)). Примерно раз в 10 секунд ESP32 будет считывать сразу пачкой все накопленные значения, а потом выводить в монитор порта.
Ниже представлен очень подробно прокомментированный пример кода для FIFO с пояснениями:
#include <Wire.h>
#include <Adafruit_BMP5xx.h>
#define I2C_SDA 2
#define I2C_SCL 3
#define BMP580_ADDRESS 0x46
// Создаём объект bmp класса Adafruit_BMP5xx
Adafruit_BMP5xx bmp;
// Создаём буфер для хранения сырых данных из FIFO датчика
// FIFO может хранить 16 фреймов, каждый фрейм в режиме P+T занимает 6 байт
// 16 × 6 = 96 байт - максимальный объём данных, который мы можем прочитать за раз
uint8_t fifo_buffer[96];
// Создаём структуру fifo типа bmp5_fifo
// Эта структура из библиотеки Bosch содержит:
// - data: указатель на буфер для данных
// - length: размер буфера
// - frame_sel: тип кадров (только T, только P, или P+T)
// - dec_sel: коэффициент децимации (прореживания)
// - mode: режим работы FIFO (Streaming или Stop-on-Full)
// - threshold: порог срабатывания прерывания
struct bmp5_fifo fifo;
void setup() {
Serial.begin(115200);
delay(2000);
Serial.println("------------------------------------------------");
Serial.println("Проверочный код: BMP580 и буфер FIFO");
Serial.println("16 кадров давления и 16 кадров температуры (P+T)");
Serial.println("------------------------------------------------");
Wire.begin(I2C_SDA, I2C_SCL);
Wire.setClock(400000);
// Инициализация датчика BMP580 по I2C адресу 0x46
if (!bmp.begin(BMP580_ADDRESS, &Wire)) {
Serial.println("BMP580 не найден");
while (1) {
}
}
Serial.println("BMP580 инициализирован\n");
// Вызываем функцию настройки FIFO
if (configureFIFO()) {
Serial.println("Система готова к работе\n");
} else {
Serial.println("Ошибка настройки");
while (1);
}
}
// Функция настройки FIFO буфера датчика
bool configureFIFO() {
// Получаем указатель на структуру bmp5_dev из объекта bmp
// Эта структура содержит все внутренние данные датчика
// Метод getDev() был добавлен в библиотеку Adafruit_BMP5xx.h
struct bmp5_dev* dev = bmp.getDev();
// ШАГ 1: Переводим датчик в режим STANDBY
// В этом режиме датчик не выполняет измерений, но позволяет настраивать параметры
// Настройки FIFO можно менять ТОЛЬКО в режиме STANDBY
if (!bmp.setPowerMode(BMP5XX_POWERMODE_STANDBY)) {
return false;
}
delay(50); // Ждём 50 мс - датчику нужно время для перехода в режим STANDBY
// ШАГ 2: Настройка параметров измерений
// Устанавливаем частоту выдачи данных 2 Гц (2 измерения в секунду)
bmp.setOutputDataRate(BMP5XX_ODR_02_HZ);
// Устанавливаем oversampling (передискретизацию) давления в 1x
// 1x - минимальное качество, минимальное энергопотребление
bmp.setPressureOversampling(BMP5XX_OVERSAMPLING_1X);
// Устанавливаем oversampling температуры в 1x
bmp.setTemperatureOversampling(BMP5XX_OVERSAMPLING_1X);
// Включаем измерение давления (true = измерять давление)
// Если отключить - датчик будет измерять только температуру
bmp.enablePressure(true);
// ШАГ 3: Принудительно отключаем режим Deep Standby
// Deep Standby - режим сверхнизкого энергопотребления между измерениями
// Но в этом режиме FIFO не работает! Поэтому его нужно отключить
// Создаём переменную для хранения текущей конфигурации ODR
uint8_t odr_config;
// Читаем текущее значение регистра ODR_CONFIG (адрес 0x37)
// bmp5_get_regs - функция Bosch API для чтения регистров
// Параметры: адрес_регистра, буфер_для_данных, количество_байт, указатель_на_dev
bmp5_get_regs(BMP5_REG_ODR_CONFIG, &odr_config, 1, dev);
// Устанавливаем 7-й бит (бит 0x80) в 1
// Этот бит называется deep_dis - когда он равен 1, Deep Standby отключён
// Операция |= (побитовое ИЛИ) устанавливает бит, не меняя остальные
odr_config |= 0x80; // deep_dis = 1
// Записываем изменённое значение обратно в регистр ODR_CONFIG
// Теперь Deep Standby отключён, FIFO будет работать корректно
bmp5_set_regs(BMP5_REG_ODR_CONFIG, &odr_config, 1, dev);
delay(10); // Даём время на применение настроек
// ШАГ 4: Настройка параметров FIFO
// Указываем, где будет храниться буфер данных
fifo.data = fifo_buffer;
// Указываем размер буфера (96 байт)
fifo.length = sizeof(fifo_buffer);
// Устанавливаем тип кадров: давление И температура (PT-mode)
// BMP5_FIFO_PRESS_TEMP_DATA = 0x03 - каждый кадр содержит 6 байт (3 байта T + 3 байта P)
fifo.frame_sel = BMP5_FIFO_PRESS_TEMP_DATA;
// Отключаем децимацию (прореживание) - сохраняем КАЖДЫЙ семпл
// Если бы было включено, датчик сохранял бы только каждый 2^N-й семпл
fifo.dec_sel = BMP5_FIFO_NO_DOWNSAMPLING;
// Устанавливаем режим Streaming
// При переполнении FIFO старые данные удаляются, новые записываются поверх
fifo.mode = BMP5_FIFO_MODE_STREAMING;
// Устанавливаем порог прерывания в 0 (прерывание по порогу отключено)
fifo.threshold = 0;
// Применяем настройки FIFO к датчику
int8_t rslt = bmp5_set_fifo_configuration(&fifo, dev);
if (rslt != BMP5_OK) {
return false;
}
// ШАГ 5: Очищаем буфер данных
// memset заполняет область памяти заданным значением (здесь 0)
// sizeof(fifo_buffer) вычисляет размер буфера в байтах
memset(fifo_buffer, 0, sizeof(fifo_buffer));
// Обнуляем счётчик кадров в структуре FIFO
// Этот счётчик будет обновлён при следующем чтении из датчика
fifo.fifo_count = 0;
// ШАГ 6: Запускаем датчик в режиме NORMAL
// В этом режиме датчик выполняет измерения непрерывно с заданной частотой ODR
if (!bmp.setPowerMode(BMP5XX_POWERMODE_NORMAL)) {
return false;
}
delay(100);
return true;
}
// Функция чтения данных из FIFO и вывода их в монитор порта
// Возвращает количество прочитанных кадров
int readAndDisplayFIFO() {
// Получаем указатель на структуру bmp5_dev для работы с датчиком
struct bmp5_dev* dev = bmp.getDev();
// Читаем данные из FIFO датчика в наш буфер fifo.data
// bmp5_get_fifo_data автоматически определяет размер данных по fifo.length
// и обновляет fifo.fifo_count (количество кадров в FIFO)
int8_t rslt = bmp5_get_fifo_data(&fifo, dev);
// Проверяем, успешно ли прошло чтение
if (rslt != BMP5_OK) {
Serial.print("Ошибка чтения FIFO: ");
Serial.println(rslt);
return 0;
}
// Проверяем, есть ли вообще данные в FIFO
if (fifo.fifo_count == 0) {
Serial.println("Нет данных в FIFO");
return 0;
}
// Создаём массив структур для хранения извлечённых данных
// 16 - максимальное количество кадров в PT-режиме
struct bmp5_sensor_data measurements[16];
// Извлекаем данные из сырого буфера в удобный формат
// bmp5_extract_fifo_data разбирает буфер, распознаёт кадры и заполняет массив
// Каждая структура bmp5_sensor_data содержит поля:
// - pressure (давление в Паскалях, тип float или uint64_t)
// - temperature (температура в градусах Цельсия, тип float или int64_t)
bmp5_extract_fifo_data(&fifo, measurements);
// Сохраняем количество кадров в локальную переменную для удобства
int frame_count = fifo.fifo_count;
// Защита от выхода за пределы массива (хотя fifo_count не может быть больше 16)
if (frame_count > 16) frame_count = 16;
// Выводим заголовок таблицы
Serial.println("┌─────┬────────────────┬────────────────┐");
Serial.println("│ № │ Давление │ Температура(°C)│");
Serial.println("│ │ (мм рт. ст.) │ │");
Serial.println("├─────┼────────────────┼────────────────┤");
// Цикл по всем прочитанным кадрам
for (int i = 0; i < frame_count; i++) {
// Извлекаем давление из структуры (оно приходит в Паскалях)
// Переменная объявлена, но не используется в выводе
float pressure_hPa = measurements[i].pressure / 100.0f; // Паскали --> гектоПаскали
// Переводим давление из Паскалей в миллиметры ртутного столба
// 1 мм рт.ст. = 133,322 Паскаля
// Формула: мм_рт_ст = Паскали / 133,322
float pressure_mmHg = measurements[i].pressure / 133.322f;
// Извлекаем температуру (уже в градусах Цельсия)
float temperature_c = measurements[i].temperature;
// Выводим строку таблицы с данными
// %3d - номер кадра (3 позиции, выравнивание вправо)
// %3.2f - давление (3 цифры целых, 2 знака после запятой)
// %2.2f - температура (2 цифры целых, 2 знака после запятой)
// \n - перевод строки
Serial.printf("│ %3d │ %3.2f │ %2.2f │\n", i + 1, pressure_mmHg, temperature_c);
}
Serial.println("└─────┴────────────────┴────────────────┘");
// Возвращаем количество прочитанных кадров
return frame_count;
}
// Функция loop() выполняется циклически после завершения setup()
void loop() {
// Статическая переменная хранит время последнего завершённого цикла
// static означает, что переменная сохраняет своё значение между вызовами loop()
static unsigned long lastCycleTime = 0;
// Статический флаг, указывающий, что это первый запуск loop()
static bool firstRun = true;
// Если это не первый запуск (т.е. уже был хотя бы один полный цикл)
if (!firstRun) {
// Вычисляем, сколько времени нужно ждать до следующего цикла
// Цель: делать паузу между циклами ровно 10000 мс (10 секунд)
// millis() - возвращает количество миллисекунд с момента запуска
// lastCycleTime - время начала предыдущего цикла
// Разница - сколько прошло времени
unsigned long waitTime = 10000 - (millis() - lastCycleTime);
// Если время ожидания положительное и не превышает 10 секунд
if (waitTime > 0 && waitTime < 10000) {
delay(waitTime); // Ждём оставшееся время
}
}
// После первого цикла сбрасываем флаг первого запуска
firstRun = false;
// Запоминаем время начала (или окончания ожидания) текущего цикла
lastCycleTime = millis();
// Переконфигурируем FIFO перед каждым циклом
// Это нужно, потому что после чтения FIFO становится пустым
// Переконфигурация заново настраивает FIFO и очищает его
if (!configureFIFO()) {
Serial.println("Ошибка переконфигурации FIFO");
delay(1000);
return;
}
// Выводим начало сбора данных без перевода строки
Serial.print("Сбор данных ");
// Прогресс-бар: 8 секунд ожидания, каждую секунду выводим точку
// За 8 секунд при ODR=2Гц накопится 16 измерений (полный FIFO)
for (int i = 0; i < 8; i++) {
delay(1000); // Ждём 1 секунду
Serial.print("."); // Выводим точку (без перевода строки)
}
Serial.println(" Готово!");
// Читаем данные из FIFO и выводим их в виде таблицы
// Переменная frames получает количество прочитанных кадров
int frames = readAndDisplayFIFO();
Serial.println("Цикл завершён");
Serial.println("--------------------------------------------------");
// Цикл завершён, программа вернётся к началу loop()
// Там сработает механизм ожидания 10 секунд, и цикл повторится
}
Так будут выглядеть в мониторе порта результаты сбора данных:

Схема подключения BMP580 к ESP32
Для проведения экспериментов воспользуемся отладочным модулем (платой) сенсора BMP580, которая уже довольно распространена в отечественных Интернет-магазинах:

Данная отладочная плата имеет всю необходимую обвязку. Модуль включает в себя линейный стабилизатор из серии XC6206 на 1,8 Вольта с низким падением напряжения. Поэтому можно питать модуль от 3,3 или 5 Вольт.
Чтобы согласовать логические уровни между микросхемой сенсора и высоковольтные выводы микроконтроллера (например, Arduino UNO с 5-вольтовой логикой или даже ESP32 c 3,3-вольтовыми уровнями), применены N-канальные MOSFET-транзисторы (транзисторная сборка 2N7002DW).
Подтягивающие резисторы номиналом 4,7 кОм представлены в виде сборки из 4-х штук, что значительно экономит место на плате.
Ниже представлена таблица распиновки модуля и его принципиальная электрическая схема:

Базой для экспериментов станет отладочная плата ESP32-C3 Super Mini, построенная на базе микросхемы ESP32C3FH4. Если нужно освежить в памяти распиновку платы, то рекомендую ознакомиться с обзором на данную плату.
Отображать показания будем на OLED дисплее на базе контроллера SSD1306 с диагональю экрана 0,96” и разрешением 128 на 64 пикселя.
В официальной документации к BMP580 представлены различные варианты подключения сенсора к внешнему ведущему устройству (в зависимости от типа интерфейса). Так как мы будем использовать I2C, то ниже приведена соответствующая схема из даташита:
Тут очень важно обратить внимание на 2 момента:
1) контакт CSB (на плате обозначен как CS) определяет выбор протокола передачи данных. Если CSB подключен к питанию VCC, то будет активирован I2C-интерфейс. А если к GND – то будет включен SPI-интерфейс;
2) контакт SDO определяет адрес I2C-интерфейса. Если SDO подключен к GND, то адрес 0x46. А если к VCC – будет назначен адрес 0x47.
Перед началом работы с конкретным модулем, который Вы приобретёте (возможно, это будет совершенно другой модуль), обязательно проверьте, нет ли на нём предустановленных перемычек для активации какого-то интерфейса или конкретного адреса.
Ещё одним важным нюансом при подключении к Super Mini является тот факт, что стандартные контакты SDA и SCL обозначены как GPIO_8 и GPIO_9 соответственно. При этом к пину GPIO_9 также жёстко привязана встроенная кнопка BOOT. Поэтому, чтобы не было конфликта с кнопкой, предлагается использовать другие свободные пины, например, GPIO_2 как SDA, а GPIO_3 как SCL. Это на тот случай, если Вам понадобится встроенная кнопка на плате для внесения интерактивности в разрабатываемое устройство.
Интерфейс подключения для обоих устройств (BMP580 и OLED-дисплей) – I2C. Таким образом, исходя из представленных условий, ниже представлена таблица подключений модуля датчика и дисплея к отладочной плате ESP32-C3 Super Mini:

Схема подключений и фотография собранного макета:

Программный код (скетч)
Для удобства и простоты разработки прошивки воспользуемся средой программирования Arduino IDE 2. Чтобы программировать ESP32-C3, для среды необходимы дополнительные настройки. Подробная инструкция приведена в статье про Wi-Fi часы на Super Mini.
Для работы с OLED-дисплеем воспользуемся библиотекой Adafruit_SSD1306 (дополнительно можно подключить Adafruit_GFX для отображения графики).
Как уже упоминалось выше, для работы с датчиком воспользуемся библиотекой Adafruit_BMP5xx.
Ниже представлен листинг кода с подробными комментариями касательно настройки сенсора:
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP5xx.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
// Настройки I2C
#define I2C_SDA 2
#define I2C_SCL 3
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define SCREEN_ADDRESS 0x3C
#define BMP580_ADDRESS 0x46
Adafruit_BMP5xx bmp;
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("BMP580 + OLED-дисплей 0.96'' SSD1306");
Wire.begin(I2C_SDA, I2C_SCL);
Wire.setClock(400000);
// Инициализация OLED
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println("OLED ERROR!");
while (1)
;
}
Serial.println("OLED OK");
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("BMP580 Sensor");
display.println("Initializing...");
display.display();
// Инициализация BMP580
Serial.print("BMP580 init... ");
if (!bmp.begin(BMP580_ADDRESS, &Wire)) {
Serial.println("FAIL!");
display.clearDisplay();
display.setCursor(0, 0);
display.println("BMP580 ERROR!");
display.display();
while (1)
;
}
Serial.println("OK");
// Настройка датчика (сохраняем те же параметры, что и в оригинале)
Serial.println("Настройка BMP580:");
// Устанавливаем коэффициент передискретизации (oversampling) для температуры
// BMP5XX_OVERSAMPLING_8X означает: датчик выполнит 8 измерений температуры
// и усреднит их в один результат. Чем выше значение, тем точнее измерение,
// но тем дольше оно длится
// Доступные значения: 1X, 2X, 4X, 8X, 16X, 32X, 64X, 128X
bmp.setTemperatureOversampling(BMP5XX_OVERSAMPLING_8X);
// Устанавливаем коэффициент передискретизации для давления
// Аналогично температуре: 128 измерений давления усредняются в один результат
// При 128X время измерения давления ~20.8 мс (по даташиту)
// Высокий oversampling даёт очень точные показания, но увеличивает
// энергопотребление и время между измерениями
bmp.setPressureOversampling(BMP5XX_OVERSAMPLING_128X);
// Настраиваем IIR-фильтр (цифровой фильтр нижних частот)
// Коэффициент 15 означает среднюю степень сглаживания
// Формула фильтра: output[n] = (output[n-1] * K + input[n]) / (K + 1)
// Чем выше коэффициент, тем сильнее сглаживаются резкие скачки давления
// (например, от ветра или открытой двери), но тем медленнее реакция
// на реальные изменения давления
// Доступно: BYPASS (выключен), 1, 3, 7, 15, 31, 63, 127
bmp.setIIRFilterCoeff(BMP5XX_IIR_FILTER_COEFF_15);
// Устанавливаем частоту выдачи данных (ODR - Output Data Rate)
// Значение 01_HZ означает 1 измерение в секунду (период 1 секунда)
// ВАЖНО: этот параметр используется ТОЛЬКО в режиме NORMAL
// В вашем коде используется режим FORCED, поэтому ODR игнорируется,
// но настройка оставлена для совместимости (если позже переключитесь на NORMAL)
// Доступные значения: от 0.125 Гц до 240 Гц
bmp.setOutputDataRate(BMP5XX_ODR_01_HZ);
// Включаем измерение давления
// Параметр true означает "измерять давление", false - "только температура"
// Важный нюанс: давление НЕ МОЖЕТ измеряться без температуры,
// так как для компенсации дрейфа MEMS-элемента нужны данные температуры
// Если отключить давление (false), датчик будет измерять только температуру,
// что снижает энергопотребление
bmp.enablePressure(true);
Serial.println("Настройка завершена");
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.println("BMP580 Ready");
display.println("Reading data...");
display.display();
delay(1000);
}
void loop() {
static unsigned long last_read = 0;
static int counter = 0;
// Измерение каждые 2 секунды
if (millis() - last_read >= 2000) {
last_read = millis();
counter++;
// Запускаем измерение в режиме FORCED
bmp.setPowerMode(BMP5XX_POWERMODE_FORCED);
// Используем библиотечный метод performReading() для получения данных
if (bmp.performReading()) {
// Данные уже сконвертированы библиотекой:
// bmp.temperature - температура в °C
// bmp.pressure - давление в гектопаскалях (гПа)
float temperature = bmp.temperature;
float pressure_hpa = bmp.pressure;
float pressure_mmHg = pressure_hpa * 0.750062; // гПа → мм рт.ст.
Serial.println("----------------------------");
Serial.print(temperature, 2);
Serial.println(" °C");
Serial.print(pressure_hpa, 2);
Serial.println(" гПа");
Serial.print(pressure_mmHg, 2);
Serial.println(" мм рт. ст.");
// Вывод на OLED (полностью сохранён формат оригинала)
display.clearDisplay();
// Заголовок
display.setTextSize(1);
display.setCursor(0, 0);
display.println(" SPRYTRON.RU BMP580 ");
// Температура
display.setTextSize(2);
display.setCursor(0, 12);
display.printf("%.2f", temperature);
display.setTextSize(1);
display.print(" ");
display.print((char)247);
display.print("C");
// Давление в гПа
display.setTextSize(2);
display.setCursor(0, 30);
display.printf("%.2f", pressure_hpa);
display.setTextSize(1);
display.print(" hPa");
// Давление в мм рт. ст.
display.setTextSize(2);
display.setCursor(0, 48);
display.printf("%.2f", pressure_mmHg);
display.setTextSize(1);
display.print(" mmHg");
display.display();
} else {
// Ошибка чтения данных через библиотеку
Serial.println("Ошибка чтения данных");
// Показываем ошибку на OLED
display.clearDisplay();
display.setCursor(0, 0);
display.println("Error!");
display.println("Check connection");
display.display();
}
}
delay(10);
}
Для того, чтобы активировать монитор порта в ESP32-C3 Super Mini, необходимо в меню «Инструменты» в разделе «USB CDC» выбрать «Enabled», после чего перезапустить среду программирования.

После прошивки контроллера в мониторе порта будут отображаться показания:

Заключение
В данной статье мы познакомились с BMP580, который на текущий момент является актуальным датчиком атмосферного давления, пришедший на смену классическому BMP280 и линейке BMP3xx. Это качественно новый этап развития линейки сенсоров Bosch, предлагающий высокую точность, энергоэффективность и расширенные функциональные возможности.
Ключевыми достоинствами рассмотренного чипа являются:
1. Точность и стабильность
Благодаря продуманной схемотехнике и качественной калибровке, датчик демонстрирует погрешность для давления ±30 Па в диапазоне -5…+65°C (до ±75 Па на всём диапазоне) и для температуры ±0,5 °C, что сопоставимо с конкурентами и превосходит решения предыдущих поколений. Относительная точность составляет ±6 Па (перепад высот примерно 0,5 метра), что является достаточно неплохим результатом для бюджетных решений;
2. Энергоэффективность
Благодаря раздельным регуляторам питания, режиму «глубокого сна», а также продуманной логике переходов между состояниями, сенсор является хорошим вариантом для использования в устройствах с аккумуляторным питанием;
3. Гибкость настройки
Широкий диапазон частот опроса чувствительных элементов (от 0,125 до 240 Гц), вариативность числа выборок (от x1 до x128) и возможность применения IIR-фильтра с разными коэффициентами – всё это позволяют адаптировать датчик под конкретную задачу (от экономичной метеостанции до высокоскоростного высотомера);
4. Буфер FIFO
Наличие аппаратного накопителя на 32 измерения – одно из главных преимуществ. Оно позволяет разгрузить ведущий микроконтроллер, освобождая его вычислительные ресурсы для более приоритетных задач или же снизить общее энергопотребление системы.
Таким образом, BMP580 является современным, технологичным и при этом доступным решением для задач определения атмосферного давления и высоты. Он уверенно занимает нишу между бюджетными решениями и флагманскими моделями, предлагая оптимальный баланс цены, точности и функциональности.


