ESP8266 NodeMCU с датчиком BMP388 – барометр/альтиметр (Arduino IDE)
BMP388 – это крошечный и точный абсолютный барометрический датчик давления. Благодаря своей точности он часто используется для оценки высоты в приложениях для дронов. Он также может использоваться для навигации в помещении/на улице, GPS-приложений и других задач. В этом руководстве вы узнаете, как использовать датчик давления BMP388 с платой Arduino – мы покажем схему подключения и пример кода.
В этом руководстве мы рассмотрим:
У нас есть похожее руководство для платы ESP32: :doc:`ESP32 с датчиком BMP388 барометр/альтиметр (Arduino) </esp32/rnt/esp32-bmp388-arduino/index>`_
Знакомство с барометрическим датчиком 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 |
Общий GND |
SCK |
Вывод SCL для I2C-связи; вывод SCK для SPI-связи |
SDO |
Вывод SDO (MISO) для SPI-связи |
SDI |
Вывод SDI (MOSI) для SPI-связи; вывод SDA для I2C-связи |
CS |
Вывод выбора чипа (Chip Select) для SPI-связи |
INT |
Вывод прерывания |
Интерфейс BMP388
Как упоминалось ранее, датчик BMP388 поддерживает интерфейсы I2C и SPI.
BMP388 I2C
Для использования протокола связи I2C используйте следующие выводы:
BMP388 |
ESP8266 |
|---|---|
SDI (SDA) |
GPIO 4 (D2) |
SCK (SCL) |
GPIO 5 (D1) |
BMP388 SPI
Для использования протокола связи SPI используйте следующие выводы:
BMP388 |
ESP8266 |
|---|---|
SCK |
GPIO 14 (D5) |
SDI (MOSI) |
GPIO 13 (D7) |
SDO (MISO) |
GPIO 12 (D6) |
CS (Chip Select) |
GPIO 15 (D8) |
Необходимые компоненты
Для выполнения этого руководства вам понадобятся следующие компоненты:
ESP8266 (читайте Лучшие платы разработки ESP8266)
Вы можете использовать ссылки выше или перейти напрямую на MakerAdvisor.com/tools, чтобы найти все компоненты для ваших проектов по лучшей цене!
Схема – ESP8266 NodeMCU с BMP388
BMP388 может обмениваться данными по протоколам связи I2C или SPI.
ESP8266 с BMP388 через I2C
Следуйте следующей схеме подключения, чтобы подключить BMP388 к ESP8266 с использованием выводов I2C по умолчанию.
ESP8266 с BMP388 через SPI
В качестве альтернативы вы можете захотеть использовать протокол связи SPI. В этом случае следуйте следующей схеме подключения, чтобы подключить BMP388 к ESP8266 с использованием выводов SPI по умолчанию.
Подготовка Arduino IDE
Мы будем программировать плату ESP8266 с помощью Arduino IDE. Поэтому убедитесь, что у вас установлено дополнение ESP8266. Следуйте следующему руководству:
Если вы хотите использовать VS Code с расширением PlatformIO, следуйте следующему руководству, чтобы узнать, как программировать ESP8266:
Установка библиотеки Adafruit BMP3XX
Существуют различные библиотеки, совместимые с датчиком BMP388 и ESP8266. В этом руководстве мы будем использовать библиотеку 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
Лучший способ познакомиться с новым датчиком – начать с базового примера, предоставленного библиотекой.
После установки библиотеки BMP3XX откройте Arduino IDE и перейдите в File > Examples > Adafruit BMP3XX Library > bmp3XX_simpletest. Мы внесли несколько изменений, чтобы сделать его полностью совместимым с ESP8266.
/***************************************************************************
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/esp8266-nodemcu-bmp388-arduino/
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BMP3XX.h"
#define BMP_SCK 14
#define BMP_MISO 12
#define BMP_MOSI 13
#define BMP_CS 15
#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 14
#define BMP_MISO 12
#define BMP_MOSI 13
#define BMP_CS 15
Давление на уровне моря
Создаётся переменная SEALEVELPRESSURE_HPA.
#define SEALEVELPRESSURE_HPA (1013.25)
Эта переменная сохраняет давление на уровне моря в гектопаскалях (эквивалентно миллибарам). Эта переменная используется для оценки высоты при заданном давлении путём сравнения его с давлением на уровне моря. В этом примере используется значение по умолчанию, но для точных результатов замените значение текущим давлением на уровне моря в вашем местоположении. Вы можете использовать этот сайт для проверки давления на уровне моря.
setup()
В setup() запускается последовательная связь.
Serial.begin(115200);
Инициализация датчика BMP388 I2C
В этом примере по умолчанию используется протокол связи I2C. Следующая строка запускает объект Adafruit_BMP3XX с именем bmp на выводах I2C ESP8266 по умолчанию: GPIO 5 (SCL), GPIO 4 (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_OVERSAMPLINGBMP3_OVERSAMPLING_2XBMP3_OVERSAMPLING_4XBMP3_OVERSAMPLING_8XBMP3_OVERSAMPLING_16XBMP3_OVERSAMPLING_32X
Функция setIIRFilterCoeff() устанавливает коэффициент фильтра (в отсчётах). Он может быть:
BMP3_IIR_FILTER_DISABLE(без фильтрации)BMP3_IIR_FILTER_COEFF_1BMP3_IIR_FILTER_COEFF_3BMP3_IIR_FILTER_COEFF_7BMP3_IIR_FILTER_COEFF_15BMP3_IIR_FILTER_COEFF_31BMP3_IIR_FILTER_COEFF_63BMP3_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.
Обратите внимание, что если вы увеличите высоту датчика, это отразится в показании высоты. Оценка высоты довольно точная. Она может обнаруживать небольшие изменения в диапазоне сантиметров или дюймов. Вы можете проверить это, сравнив получаемую высоту с высотой вашего местоположения. Чтобы узнать высоту вашего местоположения, вы можете использовать этот сайт.
Веб-сервер ESP8266 NodeMCU с BMP388
В этом разделе мы приводим пример веб-сервера, который вы можете создать с ESP8266 для отображения показаний BMP388 на веб-странице.
Установка библиотек – Async Web Server
Для создания веб-сервера вам необходимо установить следующие библиотеки. Нажмите на ссылки ниже, чтобы скачать библиотеки.
Эти библиотеки недоступны для установки через менеджер библиотек Arduino, поэтому вам нужно скопировать файлы библиотек в папку библиотек Arduino. В качестве альтернативы, в Arduino IDE вы можете перейти в Sketch > Include Library > Add .zip Library и выбрать только что скачанные библиотеки.
Код
Затем загрузите следующий код на вашу плату (введите ваш SSID и пароль).
/*********
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at https://RandomNerdTutorials.com/esp8266-nodemcu-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 <ESP8266WiFi.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 14
#define BMP_MISO 12
#define BMP_MOSI 13
#define BMP_CS 15*/
#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 ºC \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-адрес ESP8266.
Откройте браузер и введите IP-адрес. Вы должны получить доступ к веб-серверу с последними показаниями датчика. Вы можете получить доступ к веб-серверу с вашего компьютера, планшета или смартфона в вашей локальной сети.
Показания обновляются автоматически на веб-сервере с помощью Server-Sent Events. Вы можете ознакомиться с :doc:`руководством по Server-Sent Events </esp32/rnt/esp8266-nodemcu-web-server-sent-events-sse/index>`_, чтобы узнать, как это работает.
Заключение
BMP388 – это маленький и очень точный датчик давления, который позволяет оценивать высоту с большой точностью. Датчик также измеряет температуру. Он отлично подходит для навигации на открытом воздухе/в помещении, дронов, метеостанций и других приложений.
В этом руководстве вы узнали, как использовать датчик с платой разработки ESP8266 и Arduino IDE. Мы надеемся, что это руководство по началу работы было полезным. Кроме того, у нас есть руководства для других популярных датчиков:
Узнайте больше о ESP8266 с помощью наших ресурсов:
Спасибо за чтение.