В этом уроке мы научимся подключать барометрический датчик BMP180 к плате ESP32 с использованием. Сначала мы познакомим вас с датчиком, затем подключим его к нашей плате разработки и запрограммируем для измерения температуры и давления с помощью ESP-IDF. Для демонстрации мы сначала измерим данные с датчика BMP180 и выведем их на консоль ESP-IDF. Затем мы подключим OLED-дисплей SSD1306 к плате ESP32, чтобы также отображать результаты измерений датчика на OLED-дисплее.
Вы можете посмотреть на нашем сайте и другие проекты с использованием датчика BMP180:
- подключение датчика измерения давления BMP180 к Arduino Uno;
- метеостанция IoT Live на NodeMCU ESP8266;
- метеостанция на Raspberry Pi: измерение температуры, влажности и давления через сеть Интернет.
Датчик измерения давления BMP180
Датчик BMP180 обычно используется для измерения атмосферного и биометрического давления, хотя он также позволяет измерять температуру и высоту. Он также позволяет измерять давление на уровне моря наряду с реальной высотой. Благодаря высокой точности и экономичности этот барометрический датчик отлично подходит для потребительских приложений, таких как прогнозирование погоды, спортивные устройства, GPS, навигация и т. д. Более того, поскольку датчик BMP180 способен с высокой точностью измерять давление и высоту, он также может использоваться в качестве высотомера.
Давайте обсудим некоторые ключевые особенности датчика BMP180:
- Датчик BMP180 использует протокол I2C для подключения и связи с микроконтроллерами.
- Он может работать в диапазоне напряжений от 1,8 до 3,6 В.
- Он способен измерять атмосферное давление в диапазоне 300-1100 гПа.
- Обладает низким уровнем шума и низким энергопотреблением. Приблизительно 5 мкА при 1 выборке/с в стандартном режиме.
- Также может использоваться для измерения температуры.
Распиновка датчика BMP180
Модуль датчика BMP180 имеет компактные размеры и широко представлен на рынке. На рисунке ниже показан типичный модуль датчика BMP180.
Модуль датчика BMP180, который мы будем использовать в этом руководстве, имеет 4 контакта. Два из них — это контакты питания (Vcc и Gnd), а два — контакты связи I2C (SCL и SDA). В таблице ниже приведено краткое описание этих четырех контактов.
| Vcc | На вывод Vcc подается питание на датчик BMP180. Подключите его к источнику напряжения 3,3-5 В. |
| GND | Это заземляющий контакт, используемый для обеспечения общего заземления. |
| SCL | Это вывод последовательного тактового сигнала, используемый для генерации тактового импульса. Подключите его к выводу SCL микроконтроллера. |
| SDA | Это вывод для передачи последовательных данных, используемый для последовательной связи. Подключите его к выводу SDA микроконтроллера. |
Как видите, распиновка датчика BMP180 достаточно стандартная для всех датчиков, работающих по интерфейсу I2C.
Подключение BMP180 к ESP32
Для подключения платы ESP32 к датчику BMP180 нам понадобятся следующие компоненты:
- Плата ESP32.
- Датчик BMP180.
- Соединительные провода.
Соединения между устройствами указаны в таблице ниже:
| BMP180 | ESP32 |
| Vcc | Контакт VCC будет соединен с контактом 3,3 В платы ESP32. |
| Gnd | Общий провод (земля) с ESP32 |
| SCL | GPIO22 — это стандартный вывод SCL для ESP32. |
| SDA | GPIO21 — это стандартный вывод SDA для ESP32. |
Подключите датчик BMP180 к плате разработки ESP32, как показано на принципиальной схеме ниже:
Взаимодействие с датчиком BMP180 с помощью ESP-IDF
Мы создадим проект в VS Code с расширением ESP-IDF для отображения данных датчика BMP180, включая температуру, давление и высоту. Код будет считывать данные с датчика и выводить их в терминал ESP-IDF каждую секунду. Мы будем использовать библиотеку BMP180, предоставленную krzychb на GitHub.
Создание примера проекта
Откройте VS Code и перейдите в меню View > Command Palette («Вид» > «Палитра команд»). Введите в строке поиска ESP-IDF: New Project и нажмите Enter.
Укажите название проекта и каталог, а также плату и целевое устройство ESP-IDF. Для платы ESP-IDF мы выбрали опцию custom board («пользовательская плата»). Для целевого устройства ESP-IDF мы выбрали модуль ESP32. Нажмите кнопку ‘Choose Template’ («Выбрать шаблон»), чтобы продолжить.
В разделе «Расширение» выберите опцию ESP-IDF:
На вкладке get-started («Начало работы») мы щелкнем по пункту «sample_project». Затем нажмем ‘Create project using template sample_project’) («Создать проект, используя шаблон sample_project»).
Вы получите уведомление о создании проекта. Чтобы открыть проект в новом окне, нажмите «Да».
Это откроет проект, который мы создали на вкладке «Проводник». Внутри папки проекта находится несколько папок. Это справедливо для каждого проекта, который вы будете создавать с помощью ESP-IDF Explorer.
Для начала добавим необходимые заголовочные файлы для библиотек, требуемых для этого проекта. Создайте новую папку с названием «components» и добавьте в неё три файла, перечисленные ниже:
- bmp180.c
- bmp180.h
- CMakeLists.txt
bmp180.c
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 |
/* bmp180.c - BMP180 pressure sensor driver for ESP32 This file is part of the ESP32 Everest Run project https://github.com/krzychb/esp32-everest-run Copyright (c) 2016 Krzysztof Budzynski <krzychb@gazeta.pl> This work is licensed under the Apache License, Version 2.0, January 2004 See the file LICENSE for details. */ #include <math.h> #include <freertos/FreeRTOS.h> #include <freertos/task.h> #include "driver/i2c.h" #include "esp_log.h" #include "bmp180.h" static const char* TAG = "BMP180 I2C Driver"; #define ACK_CHECK_EN 0x1 // I2C master will check ack from slave #define ACK_CHECK_DIS 0x0 // I2C master will not check ack from slave #define ACK_VAL 0x0 // I2C ack value #define NACK_VAL 0x1 // I2C nack value #define BMP180_ADDRESS 0x77 // I2C address of BMP180 #define BMP180_ULTRA_LOW_POWER 0 #define BMP180_STANDARD 1 #define BMP180_HIGH_RES 2 #define BMP180_ULTRA_HIGH_RES 3 #define BMP180_CAL_AC1 0xAA // Calibration data (16 bits) #define BMP180_CAL_AC2 0xAC // Calibration data (16 bits) #define BMP180_CAL_AC3 0xAE // Calibration data (16 bits) #define BMP180_CAL_AC4 0xB0 // Calibration data (16 bits) #define BMP180_CAL_AC5 0xB2 // Calibration data (16 bits) #define BMP180_CAL_AC6 0xB4 // Calibration data (16 bits) #define BMP180_CAL_B1 0xB6 // Calibration data (16 bits) #define BMP180_CAL_B2 0xB8 // Calibration data (16 bits) #define BMP180_CAL_MB 0xBA // Calibration data (16 bits) #define BMP180_CAL_MC 0xBC // Calibration data (16 bits) #define BMP180_CAL_MD 0xBE // Calibration data (16 bits) #define BMP180_CONTROL 0xF4 // Control register #define BMP180_DATA_TO_READ 0xF6 // Read results here #define BMP180_READ_TEMP_CMD 0x2E // Request temperature measurement #define BMP180_READ_PRESSURE_CMD 0x34 // Request pressure measurement // Calibration parameters static int16_t ac1; static int16_t ac2; static int16_t ac3; static uint16_t ac4; static uint16_t ac5; static uint16_t ac6; static int16_t b1; static int16_t b2; static int16_t mb; static int16_t mc; static int16_t md; static uint8_t oversampling = BMP180_ULTRA_HIGH_RES; static esp_err_t bmp180_master_write_slave(i2c_port_t i2c_num, uint8_t* data_wr, size_t size) { i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, ( BMP180_ADDRESS << 1 ) | I2C_MASTER_WRITE, ACK_CHECK_EN); i2c_master_write(cmd, data_wr, size, ACK_CHECK_EN); i2c_master_stop(cmd); esp_err_t ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_RATE_MS); i2c_cmd_link_delete(cmd); return ret; } static esp_err_t bmp180_write_reg(i2c_port_t i2c_num, uint8_t reg, uint8_t cmd) { uint8_t data_wr[] = {reg, cmd}; esp_err_t err = bmp180_master_write_slave(i2c_num, data_wr, 2); if (err != ESP_OK) { ESP_LOGE(TAG, "Write [0x%02x] = 0x%02x failed, err = %d", reg, cmd, err); } return err; } static esp_err_t bmp180_master_read_slave(i2c_port_t i2c_num, uint8_t* data_rd, size_t size) { if (size == 0) { return ESP_OK; } i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, ( BMP180_ADDRESS << 1 ) | I2C_MASTER_READ, ACK_CHECK_EN); if (size > 1) { i2c_master_read(cmd, data_rd, size - 1, ACK_VAL); } i2c_master_read_byte(cmd, data_rd + size - 1, NACK_VAL); i2c_master_stop(cmd); esp_err_t ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_RATE_MS); i2c_cmd_link_delete(cmd); return ret; } static esp_err_t bmp180_read_int16(i2c_port_t i2c_num, uint8_t reg, int16_t* value) { esp_err_t err = bmp180_master_write_slave(i2c_num, ®, 1); if (err == ESP_OK) { uint8_t data_rd[2] = {0}; err = bmp180_master_read_slave(i2c_num, data_rd, 2); if (err == ESP_OK) { *value = (int16_t) ((data_rd[0] << 8) | data_rd[1]); } } if (err != ESP_OK) { ESP_LOGE(TAG, "Read [0x%02x] int16 failed, err = %d", reg, err); } return err; } static esp_err_t bmp180_read_uint16(i2c_port_t i2c_num, uint8_t reg, uint16_t* value) { esp_err_t err = bmp180_master_write_slave(i2c_num, ®, 1); if (err == ESP_OK) { uint8_t data_rd[2] = {0}; err = bmp180_master_read_slave(i2c_num, data_rd, 2); if (err == ESP_OK) { *value = (uint16_t) ((data_rd[0] << 8) | data_rd[1]); } } if (err != ESP_OK) { ESP_LOGE(TAG, "Read [0x%02x] uint16 failed, err = %d", reg, err); } return err; } static esp_err_t bmp180_read_uint32(i2c_port_t i2c_num, uint8_t reg, uint32_t* value) { esp_err_t err = bmp180_master_write_slave(i2c_num, ®, 1); if (err == ESP_OK) { uint8_t data_rd[3] = {0}; err = bmp180_master_read_slave(i2c_num, data_rd, 3); if (err == ESP_OK) { *value = (uint32_t) ((data_rd[0] << 16) | (data_rd[1] << 8) | data_rd[2]); } } if (err != ESP_OK) { ESP_LOGE(TAG, "Read [0x%02x] uint16 failed, err = %d", reg, err); } return err; } static esp_err_t bmp180_read_uncompensated_temperature(int16_t* temp) { esp_err_t err = bmp180_write_reg(I2C_NUM_0, BMP180_CONTROL, BMP180_READ_TEMP_CMD); if (err == ESP_OK) { TickType_t xDelay = 5 / portTICK_PERIOD_MS; if (xDelay == 0) { xDelay = 1; } vTaskDelay(xDelay); err = bmp180_read_int16(I2C_NUM_0, BMP180_DATA_TO_READ, temp); } if (err != ESP_OK) { ESP_LOGE(TAG, "Read uncompensated temperature failed, err = %d", err); } return err; } static esp_err_t bmp180_calculate_b5(int32_t* b5) { int16_t ut; int32_t x1, x2; esp_err_t err = bmp180_read_uncompensated_temperature(&ut); if (err == ESP_OK) { x1 = ((ut - (int32_t) ac6) * (int32_t) ac5) >> 15; x2 = ((int32_t) mc << 11) / (x1 + md); *b5 = x1 + x2; } else { ESP_LOGE(TAG, "Calculate b5 failed, err = %d", err); } return err; } static uint32_t bmp180_read_uncompensated_pressure(uint32_t* up) { esp_err_t err = bmp180_write_reg(I2C_NUM_0, BMP180_CONTROL, BMP180_READ_PRESSURE_CMD + (oversampling << 6)); if (err == ESP_OK) { TickType_t xDelay = (2 + (3 << oversampling)) / portTICK_PERIOD_MS; if (xDelay == 0) { xDelay = 1; } vTaskDelay(xDelay); err = bmp180_read_uint32(I2C_NUM_0, BMP180_DATA_TO_READ, up); if (err == ESP_OK) { *up >>= (8 - oversampling); } } if (err != ESP_OK) { ESP_LOGE(TAG, "Read uncompensated pressure failed, err = %d", err); } return err; } esp_err_t bmp180_read_temperature(float* temperature) { int32_t b5; esp_err_t err = bmp180_calculate_b5(&b5); if (err == ESP_OK) { *temperature = ((b5 + 8) >> 4) / 10.0; } else { ESP_LOGE(TAG, "Read temperature failed, err = %d", err); } return err; } esp_err_t bmp180_read_pressure(uint32_t* pressure) { int32_t b3, b5, b6, x1, x2, x3, p; uint32_t up, b4, b7; esp_err_t err; err = bmp180_calculate_b5(&b5); if (err == ESP_OK) { b6 = b5 - 4000; x1 = (b2 * (b6 * b6) >> 12) >> 11; x2 = (ac2 * b6) >> 11; x3 = x1 + x2; b3 = (((((int32_t)ac1) * 4 + x3) << oversampling) + 2) >> 2; x1 = (ac3 * b6) >> 13; x2 = (b1 * ((b6 * b6) >> 12)) >> 16; x3 = ((x1 + x2) + 2) >> 2; b4 = (ac4 * (uint32_t)(x3 + 32768)) >> 15; err = bmp180_read_uncompensated_pressure(&up); if (err == ESP_OK) { b7 = ((uint32_t)(up - b3) * (50000 >> oversampling)); if (b7 < 0x80000000) { p = (b7 << 1) / b4; } else { p = (b7 / b4) << 1; } x1 = (p >> 8) * (p >> 8); x1 = (x1 * 3038) >> 16; x2 = (-7357 * p) >> 16; p += (x1 + x2 + 3791) >> 4; *pressure = p; } } if (err != ESP_OK) { ESP_LOGE(TAG, "Pressure compensation failed, err = %d", err); } return err; } esp_err_t bmp180_read_altitude(uint32_t reference_pressure, float* altitude) { uint32_t absolute_pressure; esp_err_t err = bmp180_read_pressure(&absolute_pressure); if (err == ESP_OK) { *altitude = 44330 * (1.0 - powf(absolute_pressure / (float) reference_pressure, 0.190295)); } else { ESP_LOGE(TAG, "Read altitude failed, err = %d", err); } return err; } esp_err_t bmp180_init(int pin_sda, int pin_scl) { esp_err_t err; i2c_config_t conf; conf.mode = I2C_MODE_MASTER; conf.sda_io_num = pin_sda; conf.sda_pullup_en = GPIO_PULLUP_ENABLE; conf.scl_io_num = pin_scl; conf.scl_pullup_en = GPIO_PULLUP_ENABLE; conf.master.clk_speed = 100000; conf.clk_flags = 0; err = i2c_param_config(I2C_NUM_0, &conf); if (err != ESP_OK) { ESP_LOGE(TAG, "I2C driver configuration failed with error = %d", err); return ESP_ERR_BMP180_NOT_DETECTED; } i2c_driver_install(I2C_NUM_0, I2C_MODE_MASTER, 0, 0, 0); if (err != ESP_OK) { ESP_LOGE(TAG, "I2C driver installation failed with error = %d", err); return ESP_ERR_BMP180_NOT_DETECTED; } ESP_LOGI(TAG, "I2C master driver has been installed."); uint8_t reg = 0x00; err = bmp180_master_write_slave(I2C_NUM_0, ®, 1); if (err != ESP_OK) { ESP_LOGE(TAG, "BMP180 sensor not found at 0x%02x", BMP180_ADDRESS); return ESP_ERR_BMP180_NOT_DETECTED; } ESP_LOGI(TAG, "BMP180 sensor found at 0x%02x", BMP180_ADDRESS); err = bmp180_read_int16(I2C_NUM_0, BMP180_CAL_AC1, &ac1); err |= bmp180_read_int16(I2C_NUM_0, BMP180_CAL_AC2, &ac2); err |= bmp180_read_int16(I2C_NUM_0, BMP180_CAL_AC3, &ac3); err |= bmp180_read_uint16(I2C_NUM_0, BMP180_CAL_AC4, &ac4); err |= bmp180_read_uint16(I2C_NUM_0, BMP180_CAL_AC5, &ac5); err |= bmp180_read_uint16(I2C_NUM_0, BMP180_CAL_AC6, &ac6); err |= bmp180_read_int16(I2C_NUM_0, BMP180_CAL_B1, &b1); err |= bmp180_read_int16(I2C_NUM_0, BMP180_CAL_B2, &b2); err |= bmp180_read_int16(I2C_NUM_0, BMP180_CAL_MB, &mb); err |= bmp180_read_int16(I2C_NUM_0, BMP180_CAL_MC, &mc); err |= bmp180_read_int16(I2C_NUM_0, BMP180_CAL_MD, &md); if (err != ESP_OK) { ESP_LOGE(TAG, "BMP180 sensor calibration read failure, err = %d", err); return ESP_ERR_BMP180_CALIBRATION_FAILURE; } ESP_LOGI(TAG, "AC1: %d, AC2: %d, AC3: %d, AC4: %d, AC5: %d, AC6: %d", ac1, ac2, ac3, ac4, ac5, ac6); ESP_LOGI(TAG, "B1: %d, B2: %d, MB: %d, MC: %d, MD: %d", b1, b2, mb, mc, md); return ESP_OK; } |
bmp180.h
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
/* bmp180.h - BMP180 pressure sensor I2C driver for ESP32 This file is part of the ESP32 Everest Run project https://github.com/krzychb/esp32-everest-run Copyright (c) 2016 Krzysztof Budzynski <krzychb@gazeta.pl> This work is licensed under the Apache License, Version 2.0, January 2004 See the file LICENSE for details. */ #ifndef BMP180_H #define BMP180_H #include "esp_err.h" #ifdef __cplusplus extern "C" { #endif #define ESP_ERR_BMP180_BASE 0x30000 #define ESP_ERR_TOO_SLOW_TICK_RATE (ESP_ERR_BMP180_BASE + 1) #define ESP_ERR_BMP180_NOT_DETECTED (ESP_ERR_BMP180_BASE + 2) #define ESP_ERR_BMP180_CALIBRATION_FAILURE (ESP_ERR_BMP180_BASE + 3) esp_err_t bmp180_init(int pin_sda, int pin_scl); esp_err_t bmp180_read_temperature(float* temperature); esp_err_t bmp180_read_pressure(uint32_t* pressure); esp_err_t bmp180_read_altitude(uint32_t reference_pressure, float* altitude); #ifdef __cplusplus } #endif #endif // BMP180_H |
CMakeLists.txt
|
1 2 |
idf_component_register(SRCS "bmp180.c" INCLUDE_DIRS .) |
Теперь перейдите к файлу main.c. В папке main находится исходный код, то есть файл main.c будет находиться здесь. Перейдите в папку main > main.c и откройте его. Скопируйте приведенный ниже код из этого файла и сохраните его.
Код ESP32 для работы с датчиком BMP180
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
#include <stdio.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/gpio.h" #include "esp_log.h" #include "bmp180.h" static const char *TAG = "BMP180 I2C Read"; #define REFERENCE_PRESSURE 101325l #define I2C_PIN_SDA 21 #define I2C_PIN_SCL 22 void bmp180_task(void *pvParameter) { while(1) { esp_err_t err; uint32_t pressure; float altitude; float temperature; err = bmp180_read_pressure(&pressure); if (err != ESP_OK) { ESP_LOGE(TAG, "Reading of pressure from BMP180 failed, err = %d", err); } err = bmp180_read_altitude(REFERENCE_PRESSURE, &altitude); if (err != ESP_OK) { ESP_LOGE(TAG, "Reading of altitude from BMP180 failed, err = %d", err); } err = bmp180_read_temperature(&temperature); if (err != ESP_OK) { ESP_LOGE(TAG, "Reading of temperature from BMP180 failed, err = %d", err); } ESP_LOGI(TAG, "Pressure %d Pa, Altitude %.1f m, Temperature : %.1f degC", pressure, altitude, temperature); vTaskDelay(1000 / portTICK_PERIOD_MS); } } void app_main() { esp_err_t err; err = bmp180_init(I2C_PIN_SDA, I2C_PIN_SCL); if(err == ESP_OK){ xTaskCreate(&bmp180_task, "bmp180_task", 1024*4, NULL, 5, NULL); } else { ESP_LOGE(TAG, "BMP180 init failed with error = %d", err); } } |
Данный код можно также скачать по следующей ссылке.
Как работает код?
Начнём с включения всех необходимых библиотек для этого проекта. Это включает в себя библиотеки FreeRTOS для создания задач и генерации задержек, драйвер gpio для настройки контактов I2C GPIO ESP32, esp_log.h в качестве библиотеки для ведения логов и bmp180.h для использования функциональности датчика BMP180.
|
1 2 3 4 5 6 7 |
#include <stdio.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/gpio.h" #include "esp_log.h" #include "bmp180.h" |
Этот код использует информационное логирование. Функция логирования принимает два аргумента. Первый аргумент — это тег, а второй — отформатированная строка. Поэтому эта глобальная переменная будет полезна при вызове функций ESP_LOGI(). Здесь «BMP180 I2C Read» — это тег, который будет использоваться при логировании.
|
1 |
static const char *TAG = "BMP180 I2C Read"; |
В качестве опорного давления мы примем давление на уровне моря.
|
1 |
#define REFERENCE_PRESSURE 101325l |
Далее приведены определения контактов SCL и SDA, которые будут использоваться для связи по протоколу I2C между платой ESP32 и датчиком BMP180. Мы используем контакты I2C по умолчанию, однако вы также можете определить другие контакты GPIO как контакты SDA/SCL.
|
1 2 |
#define I2C_PIN_SDA 21 #define I2C_PIN_SCL 22 |
Внутри функции bmp180_task() мы начнем захватывать показания датчика BMP180 и выводить их на терминал ESP-IDF каждую секунду.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
void bmp180_task(void *pvParameter) { while(1) { esp_err_t err; uint32_t pressure; float altitude; float temperature; err = bmp180_read_pressure(&pressure); if (err != ESP_OK) { ESP_LOGE(TAG, "Reading of pressure from BMP180 failed, err = %d", err); } err = bmp180_read_altitude(REFERENCE_PRESSURE, &altitude); if (err != ESP_OK) { ESP_LOGE(TAG, "Reading of altitude from BMP180 failed, err = %d", err); } err = bmp180_read_temperature(&temperature); if (err != ESP_OK) { ESP_LOGE(TAG, "Reading of temperature from BMP180 failed, err = %d", err); } ESP_LOGI(TAG, "Pressure %d Pa, Altitude %.1f m, Temperature : %.1f degC", pressure, altitude, temperature); vTaskDelay(1000 / portTICK_PERIOD_MS); } } |
Следующие функции используются для считывания показаний давления, высоты и температуры соответственно.
|
1 2 3 |
err = bmp180_read_pressure(&pressure); err = bmp180_read_altitude(REFERENCE_PRESSURE, &altitude); err = bmp180_read_temperature(&temperature); |
Если ответ об ошибке ESP не равен ESP_OK, то для данного показания датчика будет выведено сообщение об ошибке.
|
1 2 3 4 5 6 7 8 9 10 11 12 |
err = bmp180_read_pressure(&pressure); if (err != ESP_OK) { ESP_LOGE(TAG, "Reading of pressure from BMP180 failed, err = %d", err); } err = bmp180_read_altitude(REFERENCE_PRESSURE, &altitude); if (err != ESP_OK) { ESP_LOGE(TAG, "Reading of altitude from BMP180 failed, err = %d", err); } err = bmp180_read_temperature(&temperature); if (err != ESP_OK) { ESP_LOGE(TAG, "Reading of temperature from BMP180 failed, err = %d", err); } |
В противном случае, показания давления, высоты и температуры, а также их единицы измерения будут выводиться на терминал ESP-IDF каждую секунду.
|
1 2 |
ESP_LOGI(TAG, "Pressure %d Pa, Altitude %.1f m, Temperature : %.1f degC", pressure, altitude, temperature); vTaskDelay(1000 / portTICK_PERIOD_MS); |
Внутри функции app_main() мы сначала инициализируем датчик BMP180, вызвав функцию bmp180_init() и передав в качестве параметров контакты SDA и SCL. После этого мы проверим результат инициализации датчика. Если инициализация датчика прошла успешно, мы создадим задачу bmp180 с помощью функции xTaskCreate(). В противном случае на терминал будет выведено сообщение об ошибке инициализации BMP180 вместе с кодом ошибки.
|
1 2 3 4 5 6 7 8 9 10 11 |
void app_main() { esp_err_t err; err = bmp180_init(I2C_PIN_SDA, I2C_PIN_SCL); if(err == ESP_OK){ xTaskCreate(&bmp180_task, "bmp180_task", 1024*4, NULL, 5, NULL); } else { ESP_LOGE(TAG, "BMP180 init failed with error = %d", err); } } |
Компиляция скетча
Для прошивки микросхемы введите следующую команду в последовательном терминале. Не забудьте заменить COM-порт на тот, через который подключена ваша плата.
|
1 |
idf.py -p COMX flash monitor |
После успешной прошивки кода вы сможете наблюдать за показаниями давления, высоты и температуры, обновляющимися в консоли каждую секунду.
