From 4a2679271e9ab447741d30eeff9e1a9438791e73 Mon Sep 17 00:00:00 2001 From: sheinz Date: Thu, 7 Jul 2016 18:04:17 +0300 Subject: [PATCH 1/6] BMP280 pressure sensor driver draft implementation. --- examples/bmp280/Makefile | 3 + examples/bmp280/bmp280_example.c | 49 ++++++ extras/bmp280/bmp280.c | 257 +++++++++++++++++++++++++++++++ extras/bmp280/bmp280.h | 119 ++++++++++++++ extras/bmp280/component.mk | 9 ++ 5 files changed, 437 insertions(+) create mode 100644 examples/bmp280/Makefile create mode 100644 examples/bmp280/bmp280_example.c create mode 100644 extras/bmp280/bmp280.c create mode 100644 extras/bmp280/bmp280.h create mode 100644 extras/bmp280/component.mk diff --git a/examples/bmp280/Makefile b/examples/bmp280/Makefile new file mode 100644 index 0000000..8340fcc --- /dev/null +++ b/examples/bmp280/Makefile @@ -0,0 +1,3 @@ +PROGRAM=BMP280_example +EXTRA_COMPONENTS = extras/i2c extras/bmp280 +include ../../common.mk diff --git a/examples/bmp280/bmp280_example.c b/examples/bmp280/bmp280_example.c new file mode 100644 index 0000000..a9d6325 --- /dev/null +++ b/examples/bmp280/bmp280_example.c @@ -0,0 +1,49 @@ +#include + +#include "espressif/esp_common.h" +#include "esp/uart.h" + +#include "FreeRTOS.h" +#include "task.h" + +#include "bmp280/bmp280.h" + + +const uint8_t scl_pin = 5; +const uint8_t sda_pin = 4; + + +static void bmp280_task(void *pvParameters) +{ + bmp280_params_t params; + float pressure, temperature; + + bmp280_init_default_params(¶ms); + while (1) { + while (!bmp280_init(¶ms, scl_pin, sda_pin)) { + printf("BMP280 initialization failed\n"); + vTaskDelay(1000 / portTICK_RATE_MS); + } + + while(1) { + vTaskDelay(1000 / portTICK_RATE_MS); + if (!bmp280_read(&temperature, &pressure)) { + printf("Temperature/pressure reading failed\n"); + break; + } + printf("Pressure: %.2f Pa, Temperature: %.2f C\n", pressure, temperature); + } + } +} + +void user_init(void) +{ + uart_set_baud(0, 115200); + + // Just some information + printf("\n"); + printf("SDK version : %s\n", sdk_system_get_sdk_version()); + printf("GIT version : %s\n", GITSHORTREV); + + xTaskCreate(bmp280_task, (signed char *)"bmp280_task", 256, NULL, 2, NULL); +} diff --git a/extras/bmp280/bmp280.c b/extras/bmp280/bmp280.c new file mode 100644 index 0000000..9d8939e --- /dev/null +++ b/extras/bmp280/bmp280.c @@ -0,0 +1,257 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2016 sheinz (https://github.com/sheinz) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "bmp280.h" +#include "i2c/i2c.h" + + +#ifdef BMP280_DEBUG +#include +#define debug(fmt, ...) printf("%s" fmt "\n", "bmp280: ", ## __VA_ARGS__); +#else +#define debug(fmt, ...) +#endif + +/** + * BMP280 registers + */ +#define BMP280_REG_TEMP_XLSB 0xFC /* bits: 7-4 */ +#define BMP280_REG_TEMP_LSB 0xFB +#define BMP280_REG_TEMP_MSB 0xFA +#define BMP280_REG_TEMP (BMP280_REG_TEMP_MSB) +#define BMP280_REG_PRESS_XLSB 0xF9 /* bits: 7-4 */ +#define BMP280_REG_PRESS_LSB 0xF8 +#define BMP280_REG_PRESS_MSB 0xF7 +#define BMP280_REG_PRESSURE (BMP280_REG_PRESS_MSB) +#define BMP280_REG_CONFIG 0xF5 /* bits: 7-5 t_sb; 4-2 filter; 0 spi3w_en */ +#define BMP280_REG_CTRL 0xF4 /* bits: 7-5 osrs_t; 4-2 osrs_p; 1-0 mode */ +#define BMP280_REG_STATUS 0xF3 /* bits: 3 measuring; 0 im_update */ +#define BMP280_REG_RESET 0xE0 +#define BMP280_REG_ID 0xD0 +#define BMP280_REG_CALLIB 0x88 + + +#define BMP280_CHIP_ID 0x58 /* BMP280 has chip-id 0x58 */ +#define BMP280_RESET_VALUE 0xB6 + +typedef struct __attribute__((packed)) { + uint16_t dig_T1; + int16_t dig_T2; + int16_t dig_T3; + uint16_t dig_P1; + int16_t dig_P2; + int16_t dig_P3; + int16_t dig_P4; + int16_t dig_P5; + int16_t dig_P6; + int16_t dig_P7; + int16_t dig_P8; + int16_t dig_P9; +} BMP280_Callib; + +static BMP280_Callib callib_data; + +void bmp280_init_default_params(bmp280_params_t *params) +{ + params->mode = BMP280_MODE_NORMAL; + params->filter = BMP280_FILTER_OFF; + params->oversampling = BMP280_STANDARD; + params->standby = BMP280_STANDBY_250; +} + +static uint8_t read_register8(uint8_t addr) +{ + uint8_t r = 0; + if (!i2c_slave_read(BMP280_ADDRESS, addr, &r, 1)) { + r = 0; + } + return r; +} + +/** + * Even though value is signed the actual value is always positive. + * So, no need to take care of sign bit. + */ +static bool read_register24(uint8_t addr, int32_t *value) +{ + uint8_t d[] = {0, 0, 0}; + if (i2c_slave_read(BMP280_ADDRESS, addr, d, sizeof(d))) { + *value = d[0]; + *value <<= 8; + *value |= d[1]; + *value <<= 4; + *value |= d[2]>>4; + return true; + } + return false; +} + +static bool check_chip_id() +{ + return (read_register8(BMP280_REG_ID)==BMP280_CHIP_ID); +} + +static bool read_callibration_data() +{ + if (!i2c_slave_read(BMP280_ADDRESS, BMP280_REG_CALLIB, + (uint8_t*)&callib_data, sizeof(callib_data))) { + return false; + } + debug("Calibration data received:"); + debug("dig_T1=%d", callib_data.dig_T1); + debug("dig_T2=%d", callib_data.dig_T2); + debug("dig_T3=%d", callib_data.dig_T3); + debug("dig_P1=%d", callib_data.dig_P1); + debug("dig_P2=%d", callib_data.dig_P2); + debug("dig_P3=%d", callib_data.dig_P3); + debug("dig_P4=%d", callib_data.dig_P4); + debug("dig_P5=%d", callib_data.dig_P5); + debug("dig_P6=%d", callib_data.dig_P6); + debug("dig_P7=%d", callib_data.dig_P7); + debug("dig_P8=%d", callib_data.dig_P8); + debug("dig_P9=%d", callib_data.dig_P9); + return true; +} + +static bool write_register8(uint8_t addr, uint8_t value) +{ + uint8_t d[] = {addr, value}; + + return i2c_slave_write(BMP280_ADDRESS, d, 2); +} + +bool bmp280_init(bmp280_params_t *params, uint8_t scl_pin, uint8_t sda_pin) +{ + i2c_init(scl_pin, sda_pin); + if (!check_chip_id()) { + debug("Sensor not found or wrong sensor version"); + return false; + } + + if (!read_callibration_data()) { + debug("Failed to read calibration data"); + return false; + } + + uint8_t config = (params->standby << 5) | (params->filter << 2); + debug("Writing config reg=%x", config); + if (!write_register8(BMP280_REG_CONFIG, config)) { + debug("Failed configuring sensor"); + return false; + } + + uint8_t oversampling_temp = + (params->oversampling == BMP280_ULTRA_HIGH_RES) ? 2 : 1; + + uint8_t ctrl = (oversampling_temp << 5) | (params->oversampling << 2) + | (params->mode); + + debug("Writing ctrl reg=%x", ctrl); + if (!write_register8(BMP280_REG_CTRL, ctrl)) { + debug("Failed controlling sensor"); + return false; + } + return true; +} + +bool bmp280_force_measurement() +{ + // TODO: implement + return false; +} + +/** + * Compensation algorithm is taken from BMP280 datasheet. + * + * Return value is in degrees Celsius. + */ +static inline float compensate_temperature(int32_t raw_temp, int32_t *fine_temp) +{ + int32_t var1, var2, T; + + var1 = ((((raw_temp>>3) - ((int32_t)callib_data.dig_T1<<1))) + * ((int32_t)callib_data.dig_T2)) >> 11; + + var2 = (((((raw_temp>>4) - ((int32_t)callib_data.dig_T1)) + * ((raw_temp>>4) - ((int32_t)callib_data.dig_T1))) >> 12) + * ((int32_t)callib_data.dig_T3)) >> 14; + + *fine_temp = var1 + var2; + T = (*fine_temp * 5 + 128) >> 8; + return (float)T/100; +} + +/** + * Compensation algorithm is taken from BMP280 datasheet. + * + * Return value is in Pa. + */ +static inline float compensate_pressure(int32_t raw_press, int32_t fine_temp) +{ + int64_t var1, var2, p; + + var1 = ((int64_t)fine_temp) - 128000; + var2 = var1 * var1 * (int64_t)callib_data.dig_P6; + var2 = var2 + ((var1*(int64_t)callib_data.dig_P5)<<17); + var2 = var2 + (((int64_t)callib_data.dig_P4)<<35); + var1 = ((var1 * var1 * (int64_t)callib_data.dig_P3)>>8) + + ((var1 * (int64_t)callib_data.dig_P2)<<12); + var1 = (((((int64_t)1)<<47)+var1))*((int64_t)callib_data.dig_P1)>>33; + + if (var1 == 0) { + return 0; // avoid exception caused by division by zero + } + + p = 1048576 - raw_press; + p = (((p<<31) - var2)*3125) / var1; + var1 = (((int64_t)callib_data.dig_P9) * (p>>13) * (p>>13)) >> 25; + var2 = (((int64_t)callib_data.dig_P8) * p) >> 19; + + p = ((p + var1 + var2) >> 8) + (((int64_t)callib_data.dig_P7)<<4); + return (float)p/256; +} + +bool bmp280_read(float *temperature, float *pressure) +{ + int32_t raw_pressure; + int32_t raw_temp; + int32_t fine_temp; + + if (!read_register24(BMP280_REG_TEMP, &raw_temp)) { + debug("Failed reading temperature"); + return false; + } + + if (!read_register24(BMP280_REG_PRESSURE, &raw_pressure)) { + debug("Failed reading pressure"); + return false; + } + + debug("Raw temperature: %d", raw_temp); + debug("Raw pressure: %d", raw_pressure); + + *temperature = compensate_temperature(raw_temp, &fine_temp); + *pressure = compensate_pressure(raw_pressure, fine_temp); + + return true; +} diff --git a/extras/bmp280/bmp280.h b/extras/bmp280/bmp280.h new file mode 100644 index 0000000..fab5a8e --- /dev/null +++ b/extras/bmp280/bmp280.h @@ -0,0 +1,119 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2016 sheinz (https://github.com/sheinz) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef __BMP280_H__ +#define __BMP280_H__ + +#include +#include + +/** + * Uncomment to enable debug output. + */ +#define BMP280_DEBUG + +/** + * BMP280 address is 0x77 if SDO pin is high, + * Address is 0x76 if SDO pin is low. + */ +#define BMP280_ADDRESS 0x77 + +/** + * Mode of BMP280 module operation. + * Forced - Measurement is initiated by user. + * Normal - Continues measurement. + */ +typedef enum { + BMP280_MODE_FORCED = 1, + BMP280_MODE_NORMAL = 3 +} BMP280_Mode; + +typedef enum { + BMP280_FILTER_OFF = 0, + BMP280_FILTER_2 = 1, + BMP280_FILTER_4 = 2, + BMP280_FILTER_8 = 3, + BMP280_FILTER_16 = 4 +} BMP280_Filter; + +/** + * Pressure oversampling settings + */ +typedef enum { + BMP280_ULTRA_LOW_POWER = 1, /* oversampling x1 */ + BMP280_LOW_POWER = 2, /* oversampling x2 */ + BMP280_STANDARD = 3, /* oversampling x4 */ + BMP280_HIGH_RES = 4, /* oversampling x8 */ + BMP280_ULTRA_HIGH_RES = 5 /* oversampling x16 */ +} BMP280_Oversampling; + +/** + * Stand by time between measurements in normal mode + */ +typedef enum { + BMP280_STANDBY_05 = 0, /* stand by time 0.5ms */ + BMP280_STANDBY_62 = 1, /* stand by time 62.5ms */ + BMP280_STANDBY_125 = 2, /* stand by time 125ms */ + BMP280_STANDBY_250 = 3, /* stand by time 250ms */ + BMP280_STANDBY_500 = 4, /* stand by time 500ms */ + BMP280_STANDBY_1000 = 5, /* stand by time 1s */ + BMP280_STANDBY_2000 = 6, /* stand by time 2s */ + BMP280_STANDBY_4000 = 7, /* stand by time 4s */ +} BMP280_StandbyTime; + +/** + * Configuration parameters for BMP280 module. + * Use function bmp280_init_default_params to use default configuration. + */ +typedef struct { + BMP280_Mode mode; + BMP280_Filter filter; + BMP280_Oversampling oversampling; // pressure oversampling + BMP280_StandbyTime standby; +} bmp280_params_t; + + +/** + * Initialize default parameters. + * Default configuration is NORMAL mode. + */ +void bmp280_init_default_params(bmp280_params_t *params); + +/** + * Initialize BMP280 module. + */ +bool bmp280_init(bmp280_params_t *params, uint8_t scl_pin, uint8_t sda_pin); + +/** + * Start measurement in forced mode. + * The module remains in forced mode after this call. + * Do not call this method in normal mode. + */ +bool bmp280_force_measurement(); + +/** + * Read compensated temperature and pressure data. + */ +bool bmp280_read(float *temperature, float *pressure); + +#endif // __BMP280_H__ diff --git a/extras/bmp280/component.mk b/extras/bmp280/component.mk new file mode 100644 index 0000000..a075916 --- /dev/null +++ b/extras/bmp280/component.mk @@ -0,0 +1,9 @@ +# Component makefile for extras/bmp1280 + +# expected anyone using bmp driver includes it as 'bmp280/bmp280.h' +INC_DIRS += $(bmp280_ROOT).. + +# args for passing into compile rule generation +bmp280_SRC_DIR = $(bmp280_ROOT) + +$(eval $(call component_compile_rules,bmp280)) From 440ad6783494fb072abbcbb96ff4ada5e21acf52 Mon Sep 17 00:00:00 2001 From: sheinz Date: Thu, 7 Jul 2016 23:39:25 +0300 Subject: [PATCH 2/6] BMP280 driver: Forced mode. Soft reset. --- examples/bmp280/bmp280_example.c | 43 ++++++++++++++++++++++++++++++-- extras/bmp280/bmp280.c | 33 +++++++++++++++++++++++- extras/bmp280/bmp280.h | 22 ++++++++++++++-- 3 files changed, 93 insertions(+), 5 deletions(-) diff --git a/examples/bmp280/bmp280_example.c b/examples/bmp280/bmp280_example.c index a9d6325..625a60e 100644 --- a/examples/bmp280/bmp280_example.c +++ b/examples/bmp280/bmp280_example.c @@ -8,12 +8,46 @@ #include "bmp280/bmp280.h" +// In forced mode user initiate measurement each time. +// In normal mode measurement is done continuously with specified standby time. +// #define MODE_FORCED const uint8_t scl_pin = 5; const uint8_t sda_pin = 4; +#ifdef MODE_FORCED +static void bmp280_task_forced(void *pvParameters) +{ + bmp280_params_t params; + float pressure, temperature; -static void bmp280_task(void *pvParameters) + bmp280_init_default_params(¶ms); + params.mode = BMP280_MODE_FORCED; + + while (1) { + while (!bmp280_init(¶ms, scl_pin, sda_pin)) { + printf("BMP280 initialization failed\n"); + vTaskDelay(1000 / portTICK_RATE_MS); + } + + while(1) { + vTaskDelay(1000 / portTICK_RATE_MS); + if (!bmp280_force_measurement()) { + printf("Failed initiating measurement\n"); + break; + } + while (bmp280_is_measuring()) {}; // wait for measurement to complete + + if (!bmp280_read(&temperature, &pressure)) { + printf("Temperature/pressure reading failed\n"); + break; + } + printf("Pressure: %.2f Pa, Temperature: %.2f C\n", pressure, temperature); + } + } +} +#else +static void bmp280_task_normal(void *pvParameters) { bmp280_params_t params; float pressure, temperature; @@ -35,6 +69,7 @@ static void bmp280_task(void *pvParameters) } } } +#endif void user_init(void) { @@ -45,5 +80,9 @@ void user_init(void) printf("SDK version : %s\n", sdk_system_get_sdk_version()); printf("GIT version : %s\n", GITSHORTREV); - xTaskCreate(bmp280_task, (signed char *)"bmp280_task", 256, NULL, 2, NULL); +#ifdef MODE_FORCED + xTaskCreate(bmp280_task_forced, (signed char *)"bmp280_task", 256, NULL, 2, NULL); +#else + xTaskCreate(bmp280_task_normal, (signed char *)"bmp280_task", 256, NULL, 2, NULL); +#endif } diff --git a/extras/bmp280/bmp280.c b/extras/bmp280/bmp280.c index 9d8939e..dc07bf5 100644 --- a/extras/bmp280/bmp280.c +++ b/extras/bmp280/bmp280.c @@ -163,6 +163,10 @@ bool bmp280_init(bmp280_params_t *params, uint8_t scl_pin, uint8_t sda_pin) uint8_t oversampling_temp = (params->oversampling == BMP280_ULTRA_HIGH_RES) ? 2 : 1; + if (params->mode == BMP280_MODE_FORCED) { + params->mode = BMP280_MODE_SLEEP; // initial mode for forced is sleep + } + uint8_t ctrl = (oversampling_temp << 5) | (params->oversampling << 2) | (params->mode); @@ -176,7 +180,25 @@ bool bmp280_init(bmp280_params_t *params, uint8_t scl_pin, uint8_t sda_pin) bool bmp280_force_measurement() { - // TODO: implement + uint8_t ctrl = read_register8(BMP280_REG_CTRL); + ctrl &= ~0b11; // clear two lower bits + ctrl |= BMP280_MODE_FORCED; + debug("Writing ctrl reg=%x", ctrl); + if (!write_register8(BMP280_REG_CTRL, ctrl)) { + debug("Failed starting forced mode"); + return false; + } + return true; +} + +bool bmp280_is_measuring() +{ + uint8_t status = read_register8(BMP280_REG_STATUS); + if (status & (1<<3)) { + debug("Status: measuring"); + return true; + } + debug("Status: idle"); return false; } @@ -255,3 +277,12 @@ bool bmp280_read(float *temperature, float *pressure) return true; } + +bool bmp280_soft_reset() +{ + if (!write_register8(BMP280_REG_RESET, BMP280_RESET_VALUE)) { + debug("Failed resetting sensor"); + return false; + } + return true; +} diff --git a/extras/bmp280/bmp280.h b/extras/bmp280/bmp280.h index fab5a8e..9307932 100644 --- a/extras/bmp280/bmp280.h +++ b/extras/bmp280/bmp280.h @@ -30,7 +30,7 @@ /** * Uncomment to enable debug output. */ -#define BMP280_DEBUG +// #define BMP280_DEBUG /** * BMP280 address is 0x77 if SDO pin is high, @@ -44,6 +44,7 @@ * Normal - Continues measurement. */ typedef enum { + BMP280_MODE_SLEEP = 0, BMP280_MODE_FORCED = 1, BMP280_MODE_NORMAL = 3 } BMP280_Mode; @@ -95,7 +96,11 @@ typedef struct { /** * Initialize default parameters. - * Default configuration is NORMAL mode. + * Default configuration: + * mode: NORAML + * filter: OFF + * oversampling: x4 + * standby time: 250ms */ void bmp280_init_default_params(bmp280_params_t *params); @@ -111,9 +116,22 @@ bool bmp280_init(bmp280_params_t *params, uint8_t scl_pin, uint8_t sda_pin); */ bool bmp280_force_measurement(); +/** + * Check if BMP280 is busy with measuring temperature/pressure. + * Return true if BMP280 is busy. + */ +bool bmp280_is_measuring(); + /** * Read compensated temperature and pressure data. + * Temperature in degrees Celsius. + * Pressure in Pascals. */ bool bmp280_read(float *temperature, float *pressure); +/** + * Restart BMP280 module. + */ +bool bmp280_soft_reset(); + #endif // __BMP280_H__ From c19126fc13eb598455f2bc6f9a8fcc5ee6f73f98 Mon Sep 17 00:00:00 2001 From: sheinz Date: Fri, 8 Jul 2016 12:40:15 +0300 Subject: [PATCH 3/6] BMP280 driver: Add README.md --- extras/bmp280/README.md | 85 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 extras/bmp280/README.md diff --git a/extras/bmp280/README.md b/extras/bmp280/README.md new file mode 100644 index 0000000..ad9ff87 --- /dev/null +++ b/extras/bmp280/README.md @@ -0,0 +1,85 @@ +# Driver for BMP280 absolute barometric pressure sensor + +The driver works only with BMP280 sensor. For BMP080/BMP180 there's a separate +driver. Even though BMP280 is a successor of BMP180 they are not compatible. +They have different registers and different operation modes. +BMP280 supports two ways of communication: spi and i2c. +This driver provides only i2c communication. +The driver is written for [esp-open-rtos](https://github.com/SuperHouse/esp-open-rtos) +framework and requires [i2c driver](https://github.com/SuperHouse/esp-open-rtos/tree/master/extras/i2c) +from it. + +## Features + + * I2C communication. + * Forced mode (Similar to BMP180 operation). + * Normal mode. Continuous measurement. + * Soft reset. + +## Usage + +Connect BMP280 module to you ESP8266 module and specify SCL and SDA pins: + +``` +const uint8_t scl_pin = 5; +const uint8_t sda_pin = 4; +``` + +Pull up SDO pin of BMP280 in order to have address 0x77. +Or pull down SDO pin and change `#define BMP280_ADDRESS 0x77` to +`#define BMP280_ADDRESS 0x76`. Otherwise your sensor will not work. +By default address 0x77 is used, so SDO pin should be high. + +BMP280 supports two operation modes. + +### Forced mode + +In forced mode, a single measurement is performed according to selected +configuration. When the measurement is finished, the sensor returns to +sleep mode and the measurement results can be read. + +### Normal mode + +Normal mode continuously cycles between measurement period and standby period, +whose time is defined by standby_time. + +## Example + +### Forced mode + +``` +const uint8_t scl_pin = 5; +const uint8_t sda_pin = 4; +bmp280_params_t params; +float pressure, temperature; + +bmp280_init_default_params(¶ms); +params.mode = BMP280_MODE_FORCED; +bmp280_init(¶ms, scl_pin, sda_pin); + +bmp280_force_measurement(); + +while (bmp280_is_measuring()) {}; // wait for measurement to complete + +bmp280_read(&temperature, &pressure); +printf("Pressure: %.2f Pa, Temperature: %.2f C\n", pressure, temperature); +``` + +### Normal mode + +``` +bmp280_params_t params; +float pressure, temperature; + +bmp280_init_default_params(¶ms); +bmp280_init(¶ms, scl_pin, sda_pin); + +bmp280_read(&temperature, &pressure); +printf("Pressure: %.2f Pa, Temperature: %.2f C\n", pressure, temperature); + +``` + +## License + +The driver is released under MIT license. +Copyright (c) 2016 sheinz (https://github.com/sheinz) From a155928f199ac0ffaae14cc02b448979094aa6ae Mon Sep 17 00:00:00 2001 From: sheinz Date: Fri, 8 Jul 2016 12:49:51 +0300 Subject: [PATCH 4/6] Update README.md --- extras/bmp280/README.md | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/extras/bmp280/README.md b/extras/bmp280/README.md index ad9ff87..64ffc1c 100644 --- a/extras/bmp280/README.md +++ b/extras/bmp280/README.md @@ -57,12 +57,14 @@ bmp280_init_default_params(¶ms); params.mode = BMP280_MODE_FORCED; bmp280_init(¶ms, scl_pin, sda_pin); -bmp280_force_measurement(); +while (1) { + bmp280_force_measurement(); + while (bmp280_is_measuring()) {}; // wait for measurement to complete -while (bmp280_is_measuring()) {}; // wait for measurement to complete - -bmp280_read(&temperature, &pressure); -printf("Pressure: %.2f Pa, Temperature: %.2f C\n", pressure, temperature); + bmp280_read(&temperature, &pressure); + printf("Pressure: %.2f Pa, Temperature: %.2f C\n", pressure, temperature); + vTaskDelay(1000 / portTICK_RATE_MS); +} ``` ### Normal mode @@ -74,12 +76,15 @@ float pressure, temperature; bmp280_init_default_params(¶ms); bmp280_init(¶ms, scl_pin, sda_pin); -bmp280_read(&temperature, &pressure); -printf("Pressure: %.2f Pa, Temperature: %.2f C\n", pressure, temperature); - +while (1) { + bmp280_read(&temperature, &pressure); + printf("Pressure: %.2f Pa, Temperature: %.2f C\n", pressure, temperature); + vTaskDelay(1000 / portTICK_RATE_MS); +} ``` ## License The driver is released under MIT license. + Copyright (c) 2016 sheinz (https://github.com/sheinz) From db4e39b8bdc4afe16b6da713df733b002d875a0c Mon Sep 17 00:00:00 2001 From: sheinz Date: Fri, 8 Jul 2016 12:52:54 +0300 Subject: [PATCH 5/6] Update component.mk Comment typo fixed. --- extras/bmp280/component.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/bmp280/component.mk b/extras/bmp280/component.mk index a075916..21323ba 100644 --- a/extras/bmp280/component.mk +++ b/extras/bmp280/component.mk @@ -1,4 +1,4 @@ -# Component makefile for extras/bmp1280 +# Component makefile for extras/bmp280 # expected anyone using bmp driver includes it as 'bmp280/bmp280.h' INC_DIRS += $(bmp280_ROOT).. From 91e2f6c0a119ec4bb1c1764124cd05fc8b5100b8 Mon Sep 17 00:00:00 2001 From: sheinz Date: Fri, 8 Jul 2016 14:59:21 +0300 Subject: [PATCH 6/6] BMP280 driver: typo fixed --- extras/bmp280/bmp280.c | 66 +++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/extras/bmp280/bmp280.c b/extras/bmp280/bmp280.c index dc07bf5..b880254 100644 --- a/extras/bmp280/bmp280.c +++ b/extras/bmp280/bmp280.c @@ -48,7 +48,7 @@ #define BMP280_REG_STATUS 0xF3 /* bits: 3 measuring; 0 im_update */ #define BMP280_REG_RESET 0xE0 #define BMP280_REG_ID 0xD0 -#define BMP280_REG_CALLIB 0x88 +#define BMP280_REG_CALIB 0x88 #define BMP280_CHIP_ID 0x58 /* BMP280 has chip-id 0x58 */ @@ -67,9 +67,9 @@ typedef struct __attribute__((packed)) { int16_t dig_P7; int16_t dig_P8; int16_t dig_P9; -} BMP280_Callib; +} BMP280_Calib; -static BMP280_Callib callib_data; +static BMP280_Calib calib_data; void bmp280_init_default_params(bmp280_params_t *params) { @@ -111,25 +111,25 @@ static bool check_chip_id() return (read_register8(BMP280_REG_ID)==BMP280_CHIP_ID); } -static bool read_callibration_data() +static bool read_calibration_data() { - if (!i2c_slave_read(BMP280_ADDRESS, BMP280_REG_CALLIB, - (uint8_t*)&callib_data, sizeof(callib_data))) { + if (!i2c_slave_read(BMP280_ADDRESS, BMP280_REG_CALIB, + (uint8_t*)&calib_data, sizeof(calib_data))) { return false; } debug("Calibration data received:"); - debug("dig_T1=%d", callib_data.dig_T1); - debug("dig_T2=%d", callib_data.dig_T2); - debug("dig_T3=%d", callib_data.dig_T3); - debug("dig_P1=%d", callib_data.dig_P1); - debug("dig_P2=%d", callib_data.dig_P2); - debug("dig_P3=%d", callib_data.dig_P3); - debug("dig_P4=%d", callib_data.dig_P4); - debug("dig_P5=%d", callib_data.dig_P5); - debug("dig_P6=%d", callib_data.dig_P6); - debug("dig_P7=%d", callib_data.dig_P7); - debug("dig_P8=%d", callib_data.dig_P8); - debug("dig_P9=%d", callib_data.dig_P9); + debug("dig_T1=%d", calib_data.dig_T1); + debug("dig_T2=%d", calib_data.dig_T2); + debug("dig_T3=%d", calib_data.dig_T3); + debug("dig_P1=%d", calib_data.dig_P1); + debug("dig_P2=%d", calib_data.dig_P2); + debug("dig_P3=%d", calib_data.dig_P3); + debug("dig_P4=%d", calib_data.dig_P4); + debug("dig_P5=%d", calib_data.dig_P5); + debug("dig_P6=%d", calib_data.dig_P6); + debug("dig_P7=%d", calib_data.dig_P7); + debug("dig_P8=%d", calib_data.dig_P8); + debug("dig_P9=%d", calib_data.dig_P9); return true; } @@ -148,7 +148,7 @@ bool bmp280_init(bmp280_params_t *params, uint8_t scl_pin, uint8_t sda_pin) return false; } - if (!read_callibration_data()) { + if (!read_calibration_data()) { debug("Failed to read calibration data"); return false; } @@ -211,12 +211,12 @@ static inline float compensate_temperature(int32_t raw_temp, int32_t *fine_temp) { int32_t var1, var2, T; - var1 = ((((raw_temp>>3) - ((int32_t)callib_data.dig_T1<<1))) - * ((int32_t)callib_data.dig_T2)) >> 11; + var1 = ((((raw_temp>>3) - ((int32_t)calib_data.dig_T1<<1))) + * ((int32_t)calib_data.dig_T2)) >> 11; - var2 = (((((raw_temp>>4) - ((int32_t)callib_data.dig_T1)) - * ((raw_temp>>4) - ((int32_t)callib_data.dig_T1))) >> 12) - * ((int32_t)callib_data.dig_T3)) >> 14; + var2 = (((((raw_temp>>4) - ((int32_t)calib_data.dig_T1)) + * ((raw_temp>>4) - ((int32_t)calib_data.dig_T1))) >> 12) + * ((int32_t)calib_data.dig_T3)) >> 14; *fine_temp = var1 + var2; T = (*fine_temp * 5 + 128) >> 8; @@ -233,12 +233,12 @@ static inline float compensate_pressure(int32_t raw_press, int32_t fine_temp) int64_t var1, var2, p; var1 = ((int64_t)fine_temp) - 128000; - var2 = var1 * var1 * (int64_t)callib_data.dig_P6; - var2 = var2 + ((var1*(int64_t)callib_data.dig_P5)<<17); - var2 = var2 + (((int64_t)callib_data.dig_P4)<<35); - var1 = ((var1 * var1 * (int64_t)callib_data.dig_P3)>>8) + - ((var1 * (int64_t)callib_data.dig_P2)<<12); - var1 = (((((int64_t)1)<<47)+var1))*((int64_t)callib_data.dig_P1)>>33; + var2 = var1 * var1 * (int64_t)calib_data.dig_P6; + var2 = var2 + ((var1*(int64_t)calib_data.dig_P5)<<17); + var2 = var2 + (((int64_t)calib_data.dig_P4)<<35); + var1 = ((var1 * var1 * (int64_t)calib_data.dig_P3)>>8) + + ((var1 * (int64_t)calib_data.dig_P2)<<12); + var1 = (((((int64_t)1)<<47)+var1))*((int64_t)calib_data.dig_P1)>>33; if (var1 == 0) { return 0; // avoid exception caused by division by zero @@ -246,10 +246,10 @@ static inline float compensate_pressure(int32_t raw_press, int32_t fine_temp) p = 1048576 - raw_press; p = (((p<<31) - var2)*3125) / var1; - var1 = (((int64_t)callib_data.dig_P9) * (p>>13) * (p>>13)) >> 25; - var2 = (((int64_t)callib_data.dig_P8) * p) >> 19; + var1 = (((int64_t)calib_data.dig_P9) * (p>>13) * (p>>13)) >> 25; + var2 = (((int64_t)calib_data.dig_P8) * p) >> 19; - p = ((p + var1 + var2) >> 8) + (((int64_t)callib_data.dig_P7)<<4); + p = ((p + var1 + var2) >> 8) + (((int64_t)calib_data.dig_P7)<<4); return (float)p/256; }