ESP32 с датчиком барометрического давления BMP388 (Arduino IDE)
В этом руководстве вы узнаете, как использовать датчик давления BMP388 с платой ESP32 в Arduino IDE. BMP388 — это крошечный и точный датчик абсолютного барометрического давления. Благодаря своей точности он часто используется для оценки высоты в приложениях для дронов. Он также может использоваться для навигации внутри и снаружи помещений, GPS-приложений и других задач. Датчик взаимодействует с микроконтроллером через протоколы связи I2C или SPI.
В этом руководстве мы рассмотрим:
У нас есть аналогичное руководство для платы ESP8266: ESP8266 NodeMCU с барометрическим датчиком/высотомером BMP388 (Arduino)
Знакомство с барометрическим датчиком BMP388
BMP388 — это точный, малопотребляющий, малошумный датчик абсолютного барометрического давления, который измеряет абсолютное давление и температуру. Поскольку давление изменяется с высотой, мы также можем оценивать высоту с большой точностью. По этой причине этот датчик удобен для приложений дронов и навигации. Вы также можете использовать его для других задач:
расчёт вертикальной скорости;
Интернет вещей;
прогноз погоды и метеостанции;
приложения для здравоохранения;
фитнес-приложения;
и другие…
Мы используем датчик BMP388 в виде модуля, как показано на рисунке ниже. Он также доступен в других форматах.
На следующем изображении показана другая сторона датчика.
Технические характеристики BMP388
В следующей таблице приведены ключевые характеристики датчика BMP388. Для получения дополнительной информации обратитесь к даташиту.
Диапазон работы |
300…1250 гПа (давление), -40…+85 °C (температура) |
Интерфейс |
I2C и SPI |
Среднее типичное потребление тока |
3,4 мкА при 1 Гц |
Абсолютная точность давления (тип.) P=900…1100 гПа (T=25…40 °C) |
±0,5 гПа |
Относительная точность давления (тип.) P=900…1100 гПа (T=25…40 °C) |
±0,08 гПа |
Шум давления (наименьшая полоса пропускания, наивысшее разрешение) |
0,03 Па |
Максимальная частота выборки |
200 Гц |
Распиновка BMP388
Вот распиновка модуля BMP388, который мы используем — она может немного отличаться для других модулей.
VIN |
Питание датчика (5 В) |
3V3 |
Питание датчика (3,3 В) |
GND |
Общая земля |
SCK |
Вывод SCL для связи I2C / Вывод SCK для связи SPI |
SDO |
Вывод SDO (MISO) для связи SPI |
SDI |
Вывод SDI (MOSI) для связи SPI / Вывод SDA для связи I2C |
CS |
Вывод выбора микросхемы для связи SPI |
INT |
Вывод прерывания |
Интерфейс BMP388
Как упоминалось ранее, датчик BMP388 поддерживает интерфейсы I2C и SPI.
BMP388 I2C
Для использования протокола связи I2C используйте следующие выводы:
BMP388 |
ESP32 |
|---|---|
SDI (SDA) |
GPIO 21 |
SCK (SCL) |
GPIO 22 |
GPIO 22 (SCL) и GPIO 21 (SDA) — это стандартные выводы I2C ESP32. Вы можете использовать другие выводы, если правильно укажете их в коде.
Рекомендуемое чтение: ESP32 I2C Communication: Set Pins, Multiple Bus Interfaces and Peripherals (Arduino IDE)
BMP388 SPI
Для использования протокола связи SPI используйте следующие выводы:
BMP388 |
ESP32 |
|---|---|
SCK |
GPIO 18 |
SDI (MOSI) |
GPIO 23 |
SDO (MISO) |
GPIO 19 |
CS (Chip Select) |
GPIO 5 |
Это стандартные выводы SPI ESP32. Вы можете использовать другие выводы, если правильно укажете их в коде.
Необходимые компоненты
Для выполнения этого руководства вам понадобятся следующие компоненты:
ESP32 (читайте Лучшие платы разработки ESP32)
Вы можете использовать ссылки выше или перейти непосредственно на MakerAdvisor.com/tools, чтобы найти все компоненты для ваших проектов по лучшей цене!
Подключение BMP388 к ESP32
BMP388 может взаимодействовать через протоколы связи I2C или SPI.
ESP32 с BMP388 через I2C
Следуйте следующей схеме подключения, чтобы подключить BMP388 к ESP32 через стандартные выводы I2C.
ESP32 с BMP388 через SPI
В качестве альтернативы вы можете использовать протокол связи SPI. В этом случае следуйте следующей схеме подключения, чтобы подключить BMP388 к ESP32 через стандартные выводы SPI.
Подготовка Arduino IDE
Мы будем программировать плату ESP32 с помощью Arduino IDE. Поэтому убедитесь, что у вас установлено дополнение ESP32. Следуйте следующему руководству:
Если вы хотите использовать VS Code с расширением PlatformIO, следуйте следующему руководству, чтобы научиться программировать ESP32:
Установка библиотеки Adafruit BMP3XX
Существуют различные библиотеки, совместимые с датчиком BMP388 и ESP32. В этом руководстве мы будем использовать библиотеку Adafruit BMP3XX.
Выполните следующие шаги для установки библиотеки в Arduino IDE:
Откройте Arduino IDE и перейдите в Sketch > Include Library > Manage Libraries. Должен открыться менеджер библиотек.
Введите «adafruit bmp3xx» в поле поиска и установите библиотеку.
Установка библиотеки Adafruit_Sensor
Для использования библиотеки BMP3XX вам также необходимо установить библиотеку Adafruit_Sensor. Выполните следующие шаги для установки библиотеки в Arduino IDE:
Перейдите в Sketch > Include Library > Manage Libraries и введите «Adafruit Unified Sensor» в поле поиска. Прокрутите вниз, чтобы найти библиотеку, и установите её.
После установки библиотек перезапустите Arduino IDE.
Получение давления, высоты и температуры BMP388 с ESP32
Лучший способ познакомиться с новым датчиком — начать с базового примера, предоставленного библиотекой.
После установки библиотеки BMP3XX откройте Arduino IDE и перейдите в File > Examples > Adafruit BMP3XX Library > bmp3XX_simpletest. Мы внесли несколько изменений, чтобы сделать его полностью совместимым с ESP32.
/***************************************************************************
This is a library for the BMP3XX temperature & pressure sensor. Designed
specifically to work with the Adafruit BMP388 Breakout
----> http://www.adafruit.com/products/3966
These sensors use I2C or SPI to communicate, 2 or 4 pins are required
to interface. Adafruit invests time and resources providing this open
source code, please support Adafruit and open-source hardware by
purchasing products from Adafruit!
Written by Limor Fried & Kevin Townsend for Adafruit Industries.
BSD license, all text above must be included in any redistribution
***************************************************************************/
// Complete project details: https://RandomNerdTutorials.com/esp32-bmp388-arduino/
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BMP3XX.h"
#define BMP_SCK 18
#define BMP_MISO 19
#define BMP_MOSI 23
#define BMP_CS 5
#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BMP3XX bmp;
void setup() {
Serial.begin(115200);
while (!Serial);
Serial.println("Adafruit BMP388 / BMP390 test");
if (!bmp.begin_I2C()) { // hardware I2C mode, can pass in address & alt Wire
//if (! bmp.begin_SPI(BMP_CS)) { // hardware SPI mode
//if (! bmp.begin_SPI(BMP_CS, BMP_SCK, BMP_MISO, BMP_MOSI)) { // software SPI mode
Serial.println("Could not find a valid BMP3 sensor, check wiring!");
while (1);
}
// Set up oversampling and filter initialization
bmp.setTemperatureOversampling(BMP3_OVERSAMPLING_8X);
bmp.setPressureOversampling(BMP3_OVERSAMPLING_4X);
bmp.setIIRFilterCoeff(BMP3_IIR_FILTER_COEFF_3);
bmp.setOutputDataRate(BMP3_ODR_50_HZ);
}
void loop() {
if (! bmp.performReading()) {
Serial.println("Failed to perform reading :(");
return;
}
Serial.print("Temperature = ");
Serial.print(bmp.temperature);
Serial.println(" *C");
Serial.print("Pressure = ");
Serial.print(bmp.pressure / 100.0);
Serial.println(" hPa");
Serial.print("Approx. Altitude = ");
Serial.print(bmp.readAltitude(SEALEVELPRESSURE_HPA));
Serial.println(" m");
Serial.println();
delay(2000);
}
Давление на уровне моря
Для получения более точных результатов по давлению и высоте мы рекомендуем скорректировать давление на уровне моря для вашего местоположения в переменной SEALEVELPRESSURE_HPA:
#define SEALEVELPRESSURE_HPA (1013.25)
Стандартное значение составляет 1013,25 гПа. Для более точных результатов проверьте давление на уровне моря в вашем местоположении. Вы можете использовать этот сайт для проверки давления на уровне моря.
Как работает код
Продолжайте читать этот раздел, чтобы узнать, как работает код, или перейдите к разделу Демонстрация.
Библиотеки
Код начинается с подключения необходимых библиотек: библиотека Wire для использования I2C, библиотека SPI (если вы хотите использовать SPI вместо I2C), библиотеки Adafruit_Sensor и Adafruit_BMP3XX для взаимодействия с датчиком BMP388.
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BMP3XX.h"
Связь SPI
Мы предпочитаем использовать протокол связи I2C с датчиком. Однако код подготовлен, если вы хотите использовать SPI. Следующие строки кода определяют выводы SPI.
#define BMP_SCK 18
#define BMP_MISO 19
#define BMP_MOSI 23
#define BMP_CS 5
Давление на уровне моря
Создаётся переменная SEALEVELPRESSURE_HPA.
#define SEALEVELPRESSURE_HPA (1013.25)
Эта переменная сохраняет давление на уровне моря в гектопаскалях (эквивалентно миллибарам). Эта переменная используется для оценки высоты при заданном давлении путём сравнения с давлением на уровне моря. В этом примере используется значение по умолчанию, но для получения точных результатов замените его текущим давлением на уровне моря в вашем местоположении. Вы можете использовать этот сайт для проверки давления на уровне моря.
setup()
В функции setup() запускается последовательная связь.
Serial.begin(115200);
Инициализация датчика BMP388 I2C
В этом примере по умолчанию используется протокол связи I2C. Следующая строка запускает объект Adafruit_BMP3XX с именем bmp на стандартных выводах I2C ESP32: GPIO 22 (SCL), GPIO 21 (SDA).
if (!bmp.begin_I2C()) { // hardware I2C mode, can pass in address & alt Wire
Чтобы использовать SPI, необходимо закомментировать предыдущую строку и раскомментировать одну из следующих строк для аппаратного SPI (используйте стандартные выводы SPI и выберите вывод CS) или программного SPI (используйте любые выводы).
//if (! bmp.begin_SPI(BMP_CS)) { // hardware SPI mode
//if (! bmp.begin_SPI(BMP_CS, BMP_SCK, BMP_MISO, BMP_MOSI)) { // software SPI mode
Установите следующие параметры (передискретизация и фильтр) для датчика.
// Set up oversampling and filter initialization
bmp.setTemperatureOversampling(BMP3_OVERSAMPLING_8X);
bmp.setPressureOversampling(BMP3_OVERSAMPLING_4X);
bmp.setIIRFilterCoeff(BMP3_IIR_FILTER_COEFF_3);
bmp.setOutputDataRate(BMP3_ODR_50_HZ);
Для повышения разрешения необработанных данных датчика поддерживается передискретизация. Мы будем использовать параметры передискретизации по умолчанию, но вы можете их изменить.
setTemperatureOversampling(): установка передискретизации температуры.
setPressureOversampling(): установка передискретизации давления.
Эти методы могут принимать один из следующих параметров:
BMP3_NO_OVERSAMPLING
BMP3_OVERSAMPLING_2X
BMP3_OVERSAMPLING_4X
BMP3_OVERSAMPLING_8X
BMP3_OVERSAMPLING_16X
BMP3_OVERSAMPLING_32X
Функция setIIRFilterCoeff() устанавливает коэффициент фильтра (в отсчётах). Он может быть:
BMP3_IIR_FILTER_DISABLE (без фильтрации)
BMP3_IIR_FILTER_COEFF_1
BMP3_IIR_FILTER_COEFF_3
BMP3_IIR_FILTER_COEFF_7
BMP3_IIR_FILTER_COEFF_15
BMP3_IIR_FILTER_COEFF_31
BMP3_IIR_FILTER_COEFF_63
BMP3_IIR_FILTER_COEFF_127
Установите частоту выходных данных с помощью функции setOutputDataRate(). Она может принимать один из следующих вариантов:
BMP3_ODR_200_HZ, BMP3_ODR_100_HZ, BMP3_ODR_50_HZ, BMP3_ODR_25_HZ, BMP3_ODR_12_5_HZ, BMP3_ODR_6_25_HZ, BMP3_ODR_3_1_HZ, BMP3_ODR_1_5_HZ, BMP3_ODR_0_78_HZ, BMP3_ODR_0_39_HZ, BMP3_ODR_0_2_HZ, BMP3_ODR_0_1_HZ, BMP3_ODR_0_05_HZ, BMP3_ODR_0_02_HZ, BMP3_ODR_0_01_HZ, BMP3_ODR_0_006_HZ, BMP3_ODR_0_003_HZ или BMP3_ODR_0_001_HZ
loop()
В функции loop() мы получаем измерения от датчика BMP388. Сначала скажите датчику получить новые показания с помощью bmp.performReading().
if (! bmp.performReading()) {
Serial.println("Failed to perform reading :(");
return;
}
Затем получите и выведите показания температуры, давления и высоты следующим образом:
Serial.print("Temperature = ");
Serial.print(bmp.temperature);
Serial.println(" *C");
Serial.print("Pressure = ");
Serial.print(bmp.pressure / 100.0);
Serial.println(" hPa");
Serial.print("Approx. Altitude = ");
Serial.print(bmp.readAltitude(SEALEVELPRESSURE_HPA));
Serial.println(" m");
Вы получаете каждое конкретное показание следующим образом:
bmp.temperature: возвращает показание температуры
bmp.pressure: возвращает показание давления
bmp.readAltitude(SEALEVELPRESSURE_HPA): возвращает оценку высоты
Демонстрация
После ввода давления на уровне моря для вашего местоположения вы можете загрузить код на плату. В Arduino IDE перейдите в Tools > Boards и выберите вашу плату. Затем в Tools > Port выберите COM-порт.
После загрузки откройте Serial Monitor на скорости 115200 бод. Показания будут выведены в Serial Monitor.
Обратите внимание, что если вы увеличите высоту датчика, это отразится на показаниях высоты. Оценка высоты довольно точна. Она может обнаруживать небольшие изменения в диапазоне сантиметров или дюймов. Вы можете проверить это, сравнив полученную высоту с высотой вашего местоположения. Чтобы получить высоту вашего местоположения, вы можете использовать этот сайт.
Веб-сервер ESP32 с BMP388
В этом разделе мы приводим пример веб-сервера, который вы можете создать с помощью ESP32 для отображения показаний BMP388 на веб-странице.
Установка библиотек — Async Web Server
Для создания веб-сервера вам необходимо установить следующие библиотеки. Нажмите на ссылки ниже, чтобы скачать библиотеки.
Эти библиотеки недоступны для установки через Arduino Library Manager, поэтому вам нужно скопировать файлы библиотеки в папку Libraries Arduino. В качестве альтернативы в Arduino IDE вы можете перейти в Sketch > Include Library > Add .zip Library и выбрать библиотеки, которые вы только что скачали.
Код
Затем загрузите следующий код на вашу плату (введите ваш SSID и пароль).
/*********
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at https://RandomNerdTutorials.com/esp32-bmp388-arduino/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
*********/
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP3XX.h>
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
//Uncomment if using SPI
/*#define BMP_SCK 18
#define BMP_MISO 19
#define BMP_MOSI 23
#define BMP_CS 5*/
#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BMP3XX bmp;
float temp;
float pres;
float alt;
AsyncWebServer server(80);
AsyncEventSource events("/events");
unsigned long lastTime = 0;
unsigned long timerDelay = 30000; // send readings timer
void getBMPReadings(){
if (! bmp.performReading()) {
Serial.println("Failed to perform reading :(");
return;
}
temp = bmp.temperature;
pres = bmp.pressure / 100.0;
alt = bmp.readAltitude(SEALEVELPRESSURE_HPA);
}
String processor(const String& var){
getBMPReadings();
//Serial.println(var);
if(var == "TEMPERATURE"){
return String(temp);
}
else if(var == "PRESSURE"){
return String(pres);
}
else if(var == "ALTITUDE"){
return String(alt);
}
}
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
<title>BMP388 Web Server</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css"
integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr"
crossorigin="anonymous">
<link rel="icon" href="data:,">
<style>
html {font-family: Arial; display: inline-block; text-align: center;}
p { font-size: 1.2rem;}
body { margin: 0;}
.topnav { overflow: hidden; background-color: #0F7173; color: white; font-size: 1.4rem; }
.content { padding: 20px; }
.card { background-color: white; box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5); }
.cards { max-width: 700px; margin: 0 auto; display: grid; grid-gap: 2rem;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
.reading { font-size: 2rem; }
.card.temperature { color: #272932; }
.card.altitude { color: #D8A47F; }
.card.pressure { color: #F05D5E; }
</style>
</head>
<body>
<div class="topnav">
<h3>BMP388 WEB SERVER</h3>
</div>
<div class="content">
<div class="cards">
<div class="card pressure">
<h4><i class="fas fa-angle-double-down"></i> PRESSURE</h4>
<p><span class="reading"><span id="pres">%PRESSURE%</span> hPa</span></p>
</div>
<div class="card altitude">
<h4><i class="fas fa-long-arrow-alt-up"></i> ALTITUDE</h4>
<p><span class="reading"><span id="alt">%ALTITUDE%</span> m</span></p>
</div>
<div class="card temperature">
<h4><i class="fas fa-thermometer-half"></i> TEMPERATURE</h4>
<p><span class="reading"><span id="temp">%TEMPERATURE%</span> °C</span></p>
</div>
</div>
</div>
<script>
if (!!window.EventSource) {
var source = new EventSource('/events');
source.addEventListener('open', function(e) {
console.log("Events Connected");
}, false);
source.addEventListener('error', function(e) {
if (e.target.readyState != EventSource.OPEN) {
console.log("Events Disconnected");
}
}, false);
source.addEventListener('message', function(e) {
console.log("message", e.data);
}, false);
source.addEventListener('temperature', function(e) {
console.log("temperature", e.data);
document.getElementById("temp").textContent = e.data;
}, false);
source.addEventListener('pressure', function(e) {
console.log("pressure", e.data);
document.getElementById("pres").textContent = e.data;
}, false);
source.addEventListener('altitude', function(e) {
console.log("altitude", e.data);
document.getElementById("alt").textContent = e.data;
}, false);
}
</script>
</body>
</html>)rawliteral";
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
// Set device as a Wi-Fi Station
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Setting as a Wi-Fi Station..");
}
Serial.print("Station IP Address: ");
Serial.println(WiFi.localIP());
Serial.println();
// Init BMEP388 sensor
if (!bmp.begin_I2C()) { // hardware I2C mode, can pass in address & alt Wire
//if (! bmp.begin_SPI(BMP_CS)) { // hardware SPI mode
//if (! bmp.begin_SPI(BMP_CS, BMP_SCK, BMP_MISO, BMP_MOSI)) { // software SPI mode
Serial.println("Could not find a valid BMP3 sensor, check wiring!");
while (1);
}
// Set up oversampling and filter initialization
bmp.setTemperatureOversampling(BMP3_OVERSAMPLING_8X);
bmp.setPressureOversampling(BMP3_OVERSAMPLING_4X);
bmp.setIIRFilterCoeff(BMP3_IIR_FILTER_COEFF_3);
bmp.setOutputDataRate(BMP3_ODR_50_HZ);
//Get readings when initializing
getBMPReadings();
// Handle Web Server
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/html", index_html, processor);
});
// Handle Web Server Events
events.onConnect([](AsyncEventSourceClient *client){
if(client->lastId()){
Serial.printf("Client reconnected! Last message ID that it got is: %u\n", client->lastId());
}
// send event with message "hello!", id current millis
// and set reconnect delay to 1 second
client->send("hello!", NULL, millis(), 10000);
});
server.addHandler(&events);
server.begin();
}
void loop() {
if ((millis() - lastTime) > timerDelay) {
getBMPReadings();
Serial.printf("Pressure = %.2f hPa \n", pres);
Serial.printf("Altitude = %.2f m \n", alt);
Serial.printf("Temperature = %.2f oC \n", temp);
Serial.println();
// Send Events to the Web Server with the Sensor Readings
events.send("ping",NULL,millis());
events.send(String(pres).c_str(),"pressure",millis());
events.send(String(alt).c_str(),"altitude",millis());
events.send(String(temp).c_str(),"temperature",millis());
lastTime = millis();
}
}
Демонстрация веб-сервера
После загрузки откройте Serial Monitor на скорости 115200 бод, чтобы получить IP-адрес ESP32.
Откройте браузер и введите IP-адрес. Вы должны получить доступ к веб-серверу с последними показаниями датчика. Вы можете получить доступ к веб-серверу с вашего компьютера, планшета или смартфона в вашей локальной сети.
Показания обновляются автоматически на веб-сервере с помощью Server-Sent Events. Вы можете ознакомиться с руководством по Server-Sent Events, чтобы получить представление о том, как это работает.
Заключение
BMP388 — это маленький и очень точный датчик давления, который позволяет оценивать высоту с высокой точностью. Датчик также измеряет температуру. Он отлично подходит для навигации на улице и в помещении, дронов, метеостанций и других приложений.
В этом руководстве вы научились использовать датчик с платой разработки ESP32 и Arduino IDE. Мы надеемся, что это вводное руководство было полезным. Кроме того, у нас есть руководства для других популярных датчиков:
ESP32 с датчиком температуры и влажности DHT11/DHT22 в Arduino IDE
ESP32 с BME280 в Arduino IDE (давление, температура, влажность)
ESP32 с датчиком окружающей среды BME680 в Arduino IDE (газ, давление, влажность, температура)
ESP32 датчик температуры DS18B20 с Arduino IDE (одиночный, множественный, веб-сервер)
ESP32 с барометрическим датчиком BMP180 (температура и давление)
Узнайте больше об ESP32 с нашими ресурсами:
Источник: ESP32 with BMP388 Barometric/Altimeter Sensor (Arduino IDE)