Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Microseconds, Readme, Examples, several Fixes #88

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 26 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ The sensor driver package includes bme280.c, bme280.h and bme280_defs.h files.
SPI 3-wire is currently not supported in the API.
## Usage guide
### Initializing the sensor
To initialize the sensor, user need to create a device structure. User can do this by
creating an instance of the structure bme280_dev. After creating the device strcuture, user
need to fill in the various parameters as shown below.
To initialize the sensor, user needs to create a device structure. User can do this by
creating an instance of the structure bme280_dev. After creating the device structure, user
needs to fill in the various parameters as shown below.

#### Example for SPI 4-Wire
``` c
Expand All @@ -40,7 +40,7 @@ dev.intf_ptr = &dev_addr;
dev.intf = BME280_SPI_INTF;
dev.read = user_spi_read;
dev.write = user_spi_write;
dev.delay_ms = user_delay_ms;
dev.delay_us = user_delay_us;

rslt = bme280_init(&dev);
```
Expand All @@ -54,43 +54,44 @@ dev.intf_ptr = &dev_addr;
dev.intf = BME280_I2C_INTF;
dev.read = user_i2c_read;
dev.write = user_i2c_write;
dev.delay_ms = user_delay_ms;
dev.delay_us = user_delay_us;

rslt = bme280_init(&dev);
```
Regarding compensation functions for temperature,pressure and humidity we have two implementations.
Regarding compensation functions for temperature, pressure and humidity we have two implementations.
1) Double precision floating point version
2) Integer version
2) Integer versions

By default, integer version is used in the API. If the user needs the floating point version, the user has to uncomment BME280_FLOAT_ENABLE macro in bme280_defs.h file or add that to the compiler flags.
By default, BME280_FLOAT_ENABLE i.e. double precision floating point version is used in the API.
If the user needs an integer version, the user has to define BME280_64BIT_ENABLE or BME280_32BIT_ENABLE macro in bme280_defs.h file or add that to the compiler flags.

In integer compensation functions, we also have below two implementations for pressure.
1) For 32 bit machine.
2) For 64 bit machine.

By default, 64 bit variant is used in the API. If the user wants 32 bit variant, the user can disable the
macro BME280_64BIT_ENABLE in bme280_defs.h file.
When using integer versions the 64 bit variant is recommended to use in the API. If the user wants 32 bit variant, the user can define the
macro BME280_32BIT_ENABLE in bme280_defs.h file.

### Sensor data units
> The sensor data units depends on the following macros being enabled or not,
> The sensor data units depends on the following macros being enabled or not,
> (in bme280_defs.h file or as compiler macros)
> * BME280_FLOAT_ENABLE
> * BME280_64BIT_ENABLE

In case of the macro "BME280_FLOAT_ENABLE" enabled,
In case of the macro "BME280_FLOAT_ENABLE" enabled (default),
The outputs are in double and the units are

- °C for temperature
- % relative humidity
- Pascal for pressure

In case if "BME280_FLOAT_ENABLE" is not enabled, then it is
In case if "BME280_FLOAT_ENABLE" is _not_ enabled, then it is

- int32_t for temperature with the units 100 * °C
- uint32_t for humidity with the units 1024 * % relative humidity
- uint32_t for pressure
If macro "BME280_64BIT_ENABLE" is enabled, which it is by default, the unit is 100 * Pascal
If this macro is disabled, Then the unit is in Pascal
If macro "BME280_64BIT_ENABLE" is enabled, the unit is 100 * Pascal
If macro "BME280_32BIT_ENABLE" is enabled, then the unit is in Pascal

### Stream sensor data
#### Stream sensor data in forced mode
Expand All @@ -100,7 +101,7 @@ int8_t stream_sensor_data_forced_mode(struct bme280_dev *dev)
{
int8_t rslt;
uint8_t settings_sel;
uint32_t req_delay;
uint32_t req_delay;
struct bme280_data comp_data;

/* Recommended mode of operation: Indoor navigation */
Expand All @@ -112,17 +113,17 @@ int8_t stream_sensor_data_forced_mode(struct bme280_dev *dev)
settings_sel = BME280_OSR_PRESS_SEL | BME280_OSR_TEMP_SEL | BME280_OSR_HUM_SEL | BME280_FILTER_SEL;

rslt = bme280_set_sensor_settings(settings_sel, dev);
/*Calculate the minimum delay required between consecutive measurement based upon the sensor enabled
* and the oversampling configuration. */

/* Calculate the minimum delay in microseconds required between consecutive measurements
* based upon the sensor enabled and oversampling configuration. */
req_delay = bme280_cal_meas_delay(&dev->settings);

printf("Temperature, Pressure, Humidity\r\n");
/* Continuously stream sensor data */
while (1) {
rslt = bme280_set_sensor_mode(BME280_FORCED_MODE, dev);
/* Wait for the measurement to complete and print data @25Hz */
dev->delay_ms(req_delay, dev->intf_ptr);
dev->delay_us(req_delay, dev->intf_ptr);
rslt = bme280_get_sensor_data(BME280_ALL, &comp_data, dev);
print_sensor_data(&comp_data);
}
Expand Down Expand Up @@ -164,7 +165,7 @@ int8_t stream_sensor_data_normal_mode(struct bme280_dev *dev)
printf("Temperature, Pressure, Humidity\r\n");
while (1) {
/* Delay while the sensor completes a measurement */
dev->delay_ms(70, dev->intf_ptr);
dev->delay_us(70000, dev->intf_ptr);
rslt = bme280_get_sensor_data(BME280_ALL, &comp_data, dev);
print_sensor_data(&comp_data);
}
Expand All @@ -185,11 +186,11 @@ void print_sensor_data(struct bme280_data *comp_data)
### Templates for function pointers
``` c

void user_delay_ms(uint32_t period, void *intf_ptr)
void user_delay_us(uint32_t period, void *intf_ptr)
{
/*
* Return control or wait,
* for a period amount of milliseconds
* for a period amount of microseconds
*/
}

Expand Down Expand Up @@ -219,7 +220,7 @@ int8_t user_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *in
return rslt;
}

int8_t user_spi_write(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
int8_t user_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */

Expand Down Expand Up @@ -272,7 +273,7 @@ int8_t user_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *in
return rslt;
}

int8_t user_i2c_write(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
int8_t user_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */

Expand All @@ -296,5 +297,3 @@ int8_t user_i2c_write(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *i

return rslt;
}

```
8 changes: 4 additions & 4 deletions bme280.c
Original file line number Diff line number Diff line change
Expand Up @@ -850,8 +850,8 @@ int8_t bme280_compensate_data(uint8_t sensor_comp,
}

/*!
* @brief This API is used to calculate the maximum delay in milliseconds required for the
* temperature/pressure/humidity(which ever at enabled) measurement to complete.
* @brief This API is used to calculate the maximum delay in microseconds required for the
* temperature/pressure/humidity (whichever are enabled) measurement to complete.
*/
uint32_t bme280_cal_meas_delay(const struct bme280_settings *settings)
{
Expand Down Expand Up @@ -892,9 +892,9 @@ uint32_t bme280_cal_meas_delay(const struct bme280_settings *settings)
}

max_delay =
(uint32_t)((BME280_MEAS_OFFSET + (BME280_MEAS_DUR * temp_osr) +
(uint32_t)(BME280_MEAS_OFFSET + (BME280_MEAS_DUR * temp_osr) +
((BME280_MEAS_DUR * pres_osr) + BME280_PRES_HUM_MEAS_OFFSET) +
((BME280_MEAS_DUR * hum_osr) + BME280_PRES_HUM_MEAS_OFFSET)) / BME280_MEAS_SCALING_FACTOR);
((BME280_MEAS_DUR * hum_osr) + BME280_PRES_HUM_MEAS_OFFSET));

return max_delay;
}
Expand Down
6 changes: 3 additions & 3 deletions bme280.h
Original file line number Diff line number Diff line change
Expand Up @@ -377,13 +377,13 @@ int8_t bme280_compensate_data(uint8_t sensor_comp,
* \code
* uint32_t bme280_cal_meas_delay(const struct bme280_settings *settings);
* \endcode
* @brief This API is used to calculate the maximum delay in milliseconds required for the
* temperature/pressure/humidity(which ever are enabled) measurement to complete.
* @brief This API is used to calculate the maximum delay in microseconds required for the
* temperature/pressure/humidity (whichever are enabled) measurement to complete.
* The delay depends upon the number of sensors enabled and their oversampling configuration.
*
* @param[in] settings : contains the oversampling configurations.
*
* @return delay required in milliseconds.
* @return delay required in microseconds.
*
*/
uint32_t bme280_cal_meas_delay(const struct bme280_settings *settings);
Expand Down
1 change: 0 additions & 1 deletion bme280_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,6 @@
#define BME280_MEAS_OFFSET UINT16_C(1250)
#define BME280_MEAS_DUR UINT16_C(2300)
#define BME280_PRES_HUM_MEAS_OFFSET UINT16_C(575)
#define BME280_MEAS_SCALING_FACTOR UINT16_C(1000)

/**\name Standby duration selection macros */
#define BME280_STANDBY_TIME_0_5_MS (0x00)
Expand Down
55 changes: 36 additions & 19 deletions examples/linux_userspace.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,17 @@
/*!
* @ingroup bme280Examples
* @defgroup bme280GroupExampleLU linux_userspace
* @brief Linux userspace test code, simple and mose code directly from the doco.
* @brief Linux userspace test code, simple and fast code directly from the docs.
* compile like this: gcc linux_userspace.c ../bme280.c -I ../ -o bme280
* tested: Raspberry Pi.
* tested: Beagle Bone Black, Raspberry Pi.
* Use like: ./bme280 /dev/i2c-0
* \include linux_userspace.c
*/

#ifdef __KERNEL__
/* For compiling not with Beagle Bone Black (tested) uncomment following line: */
#define USE_IOCTL

#if defined __KERNEL__ || defined USE_IOCTL
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#endif
Expand Down Expand Up @@ -139,6 +142,9 @@ int main(int argc, char* argv[])

struct identifier id;

/* Make sure to select BME280_I2C_ADDR_PRIM or BME280_I2C_ADDR_SEC as needed */
id.dev_addr = BME280_I2C_ADDR_PRIM;

/* Variable to define the result */
int8_t rslt = BME280_OK;

Expand All @@ -154,7 +160,7 @@ int main(int argc, char* argv[])
exit(1);
}

#ifdef __KERNEL__
#if defined __KERNEL__ || defined USE_IOCTL
if (ioctl(id.fd, I2C_SLAVE, id.dev_addr) < 0)
{
fprintf(stderr, "Failed to acquire bus access and/or talk to slave.\n");
Expand All @@ -163,9 +169,6 @@ int main(int argc, char* argv[])

#endif

/* Make sure to select BME280_I2C_ADDR_PRIM or BME280_I2C_ADDR_SEC as needed */
id.dev_addr = BME280_I2C_ADDR_PRIM;

dev.intf = BME280_I2C_INTF;
dev.read = user_i2c_read;
dev.write = user_i2c_write;
Expand Down Expand Up @@ -201,10 +204,15 @@ int8_t user_i2c_read(uint8_t reg_addr, uint8_t *data, uint32_t len, void *intf_p

id = *((struct identifier *)intf_ptr);

write(id.fd, &reg_addr, 1);
read(id.fd, data, len);

return 0;
if (write(id.fd, &reg_addr, 1) != 1)
{
return BME280_E_COMM_FAIL;
}
if (read(id.fd, data, len) != (ssize_t)len)
{
return BME280_E_COMM_FAIL;
}
return BME280_OK;
}

/*!
Expand All @@ -213,6 +221,7 @@ int8_t user_i2c_read(uint8_t reg_addr, uint8_t *data, uint32_t len, void *intf_p
*/
void user_delay_us(uint32_t period, void *intf_ptr)
{
(void)intf_ptr; /* unused parameter, suppress warnings */
usleep(period);
}

Expand All @@ -223,20 +232,28 @@ int8_t user_i2c_write(uint8_t reg_addr, const uint8_t *data, uint32_t len, void
{
uint8_t *buf;
struct identifier id;
int8_t ret = BME280_OK;

id = *((struct identifier *)intf_ptr);

buf = malloc(len + 1);
buf[0] = reg_addr;
memcpy(buf + 1, data, len);
if (write(id.fd, buf, len + 1) < (uint16_t)len)
if (buf == NULL) /* could not allocate enough memory */
{
return BME280_E_COMM_FAIL;
return BME280_E_NULL_PTR;
}

do
{
buf[0] = reg_addr;
memcpy(buf + 1, data, len);
if (write(id.fd, buf, len + 1) != (ssize_t)(len+1))
{
ret = BME280_E_COMM_FAIL;
break;
}
} while(0);
free(buf);

return BME280_OK;
return ret;
}

/*!
Expand Down Expand Up @@ -300,8 +317,8 @@ int8_t stream_sensor_data_forced_mode(struct bme280_dev *dev)

printf("Temperature, Pressure, Humidity\n");

/*Calculate the minimum delay required between consecutive measurement based upon the sensor enabled
* and the oversampling configuration. */
/* Calculate the minimum delay in microseconds required between consecutive measurements
* based upon the sensor enabled and oversampling configuration. */
req_delay = bme280_cal_meas_delay(&dev->settings);

/* Continuously stream sensor data */
Expand Down