I'm trying to use the BMP3-Sensor-API library from Github to read a BMP388 sensor via I2C, but I always get the same answer of raw values 00 00 80 00 00 80. The hardware is okay, measurements do work with the Adafruit Python library. I have implemented the i2c read and write functions similarly as for the BMP280_driver library, which does work. What am I missing? Here is my code that works with BMP280 but not with BMP388: #ifdef BMP280
#include "bmp280.h"
#else
#include "bmp3.h"
#endif
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <time.h>
#include <errno.h>
#include <stdbool.h>
#define DEVICE "/dev/i2c-1" // bus 1 on gpio 23 = sda, gpio 24 = scl
int fd_i2c; // file descriptor for i2c
bool i2c_interface_init(const char* device, const uint8_t address);
bool i2c_read(const uint8_t reg_addr, uint8_t *reg_data, const uint16_t length);
bool i2c_write(const uint8_t reg_addr, const uint8_t *reg_data, const uint16_t length);
/* Functions needed by the BMP library */
#ifdef BMP280
void delay_ms(uint32_t period_ms);
int8_t i2c_reg_write(uint8_t i2c_addr, uint8_t reg_addr, uint8_t *reg_data, uint16_t length);
int8_t i2c_reg_read(uint8_t i2c_addr, uint8_t reg_addr, uint8_t *reg_data, uint16_t length);
void print_rslt(const char api_name[], int8_t rslt);
#else
void bmp3_delay_us(uint32_t period, void *intf_ptr);
BMP3_INTF_RET_TYPE bmp3_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr);
BMP3_INTF_RET_TYPE bmp3_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr);
void bmp3_check_rslt(const char api_name[], int8_t rslt);
#endif
int main(int argc, char** argv)
{
/* Initialize bmp object. */
int8_t rslt;
#ifdef BMP280
struct bmp280_dev bmp;
bmp.dev_id = BMP280_I2C_ADDR_SEC; /* Assign device I2C address based on the status of SDO pin (GND for PRIMARY(0x76) & VDD for SECONDARY(0x77)) */
bmp.intf = BMP280_I2C_INTF; /* Select the interface mode as I2C */
/* Map the I2C read & write function pointer with the functions responsible for I2C bus transfer */
bmp.read = i2c_reg_read;
bmp.write = i2c_reg_write;
bmp.delay_ms = delay_ms; /* Map the delay function pointer with the function responsible for implementing the delay */
if (i2c_interface_init(DEVICE, bmp.dev_id) == false)
return EXIT_FAILURE;
rslt = bmp280_init(&bmp);
print_rslt(" bmp_init status", rslt);
#else
struct bmp3_dev dev;
dev.intf = BMP3_I2C_INTF;
uint8_t dev_addr = BMP3_ADDR_I2C_SEC;
dev.intf_ptr = &dev_addr;
dev.read = bmp3_i2c_read;
dev.write = bmp3_i2c_write;
dev.delay_us = bmp3_delay_us;
if (i2c_interface_init(DEVICE, dev_addr) == false)
return EXIT_FAILURE;
rslt = bmp3_init(&dev);
bmp3_check_rslt("bmp3_init", rslt);
#endif
/* Configure sensor settings. */
#ifdef BMP280
struct bmp280_config conf;
rslt = bmp280_get_config(&conf, &bmp); /* Always read the current settings before writing, especially when not all the configuration is modified */
print_rslt(" bmp280_get_config status", rslt);
conf.filter = BMP280_FILTER_COEFF_4; /* IIR filter coeff */
conf.os_pres = BMP280_OS_4X; /* Pressure oversampling set at 4x */
conf.os_temp = BMP280_OS_1X; /* Temperature oversampling set at 1x */
conf.odr = BMP280_ODR_125_MS; /* Setting the output data rate as 1Hz (1000ms) */
rslt = bmp280_set_config(&conf, &bmp);
print_rslt(" bmp280_set_config status", rslt);
rslt = bmp280_set_power_mode(BMP280_NORMAL_MODE, &bmp); /* Always set the power mode after setting the configuration. */
print_rslt(" bmp280_set_power_mode status", rslt);
#else
struct bmp3_settings settings = { 0 };
settings.int_settings.drdy_en = BMP3_ENABLE;
settings.press_en = BMP3_ENABLE;
settings.temp_en = BMP3_ENABLE;
settings.odr_filter.press_os = BMP3_OVERSAMPLING_2X;
settings.odr_filter.temp_os = BMP3_OVERSAMPLING_2X;
settings.odr_filter.odr = BMP3_ODR_12_5_HZ;
uint8_t settings_sel = BMP3_SEL_PRESS_EN | BMP3_SEL_TEMP_EN | BMP3_SEL_PRESS_OS | BMP3_SEL_TEMP_OS | BMP3_SEL_ODR |
BMP3_SEL_DRDY_EN;
rslt = bmp3_set_sensor_settings(settings_sel, &dev);
bmp3_check_rslt("bmp3_set_sensor_settings", rslt);
settings.op_mode = BMP3_MODE_NORMAL;
rslt = bmp3_set_op_mode(&dev);
bmp3_check_rslt("bmp3_set_op_mode", rslt);
#endif
/* Main loop. */
while (1)
{
/* Make a pressure reading. */
double temp = 0.;
double pres = 0.;
#ifdef BMP280
struct bmp280_uncomp_data ucomp_data;
rslt = bmp280_get_uncomp_data(&ucomp_data, &bmp); /* Read the raw data from sensor. */
print_rslt(" bmp280_get_uncomp_data status", rslt);
rslt = bmp280_get_comp_temp_double(&temp, ucomp_data.uncomp_temp, &bmp); /* Get the compensated temperature as floating point value */
print_rslt(" bmp280_get_comp_temp_double status", rslt);
rslt = bmp280_get_comp_pres_double(&pres, ucomp_data.uncomp_press, &bmp); /* Get the compensated pressure as floating point value */
print_rslt(" bmp280_get_comp_pres_double status", rslt);
#else
struct bmp3_data data = { 0 };
rslt = bmp3_get_sensor_data(BMP3_ALL, &data, &dev);
bmp3_check_rslt("bmp3_get_sensor_data", rslt);
rslt = bmp3_get_status(&dev); /* Read status register again to clear data ready interrupt status */
bmp3_check_rslt("bmp3_get_status", rslt);
#ifdef BMP3_DOUBLE_PRECISION_COMPENSATION
temp = data.temperature;
pres = data.pressure;
#else
temp = (double)data.temperature / 100.;
pres = (double)data.pressure / 100.;
#endif /* !BMP3_DOUBLE_PRECISION_COMPENSATION */
#endif
printf("%.1fPa %.1f°C\n", pres, temp);
#ifdef BMP280
bmp.delay_ms(125); /* Sleep time between measurements = BMP280_ODR_125_MS */
#else
usleep(125000); /* Sleep time between measurements */
#endif
}
return EXIT_SUCCESS;
}
bool i2c_interface_init(const char* device, const uint8_t address)
{
/* Open I2C device */
if ((fd_i2c = open(device, O_RDWR)) < 0)
{
fprintf(stderr, "Failed to open the i2c bus %s\n", device);
return false;
}
if (ioctl(fd_i2c, I2C_SLAVE, address) < 0)
{
fprintf(stderr, "Failed to acquire bus access and/or talk to slave.\n");
return false;
}
return true;
}
bool i2c_read(const uint8_t reg_addr, uint8_t *reg_data, const uint16_t length)
{
write(fd_i2c, ®_addr, 1);
read(fd_i2c, reg_data, length);
for (int i=0; i<length; i++)
printf("%02x ", reg_data[i]); // DEBUG
return true;
}
bool i2c_write(const uint8_t reg_addr, const uint8_t *reg_data, const uint16_t length)
{
int8_t *buf;
buf = malloc(length + 1);
buf[0] = reg_addr;
memcpy(buf + 1, reg_data, length);
if (write(fd_i2c, buf, length + 1) < length)
return false;
free(buf);
return true;
}
#ifdef BMP280
void delay_ms(uint32_t period_ms)
{
usleep(period_ms * 1000);
}
int8_t i2c_reg_write(uint8_t i2c_addr, uint8_t reg_addr, uint8_t *reg_data, uint16_t length)
{
if (i2c_write(reg_addr, reg_data, length))
return BMP280_OK;
else
return BMP280_E_COMM_FAIL;
}
int8_t i2c_reg_read(uint8_t i2c_addr, uint8_t reg_addr, uint8_t *reg_data, uint16_t length)
{
i2c_read(reg_addr, reg_data, length);
return BMP280_OK;
}
void print_rslt(const char api_name[], int8_t rslt)
{
if (rslt != BMP280_OK)
{
printf("%s\t", api_name);
if (rslt == BMP280_E_NULL_PTR)
{
printf("Error [%d] : Null pointer error\r\n", rslt);
}
else if (rslt == BMP280_E_COMM_FAIL)
{
printf("Error [%d] : Bus communication failed\r\n", rslt);
}
else if (rslt == BMP280_E_IMPLAUS_TEMP)
{
printf("Error [%d] : Invalid Temperature\r\n", rslt);
}
else if (rslt == BMP280_E_DEV_NOT_FOUND)
{
printf("Error [%d] : Device not found\r\n", rslt);
}
else
{
/* For more error codes refer "*_defs.h" */
printf("Error [%d] : Unknown error code\r\n", rslt);
}
}
}
#else
BMP3_INTF_RET_TYPE bmp3_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
i2c_read(reg_addr, reg_data, len);
return BMP3_INTF_RET_SUCCESS;
}
BMP3_INTF_RET_TYPE bmp3_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
if (i2c_write(reg_addr, reg_data, len))
return BMP3_INTF_RET_SUCCESS;
else
return BMP3_E_COMM_FAIL;
}
void bmp3_delay_us(uint32_t period, void *intf_ptr)
{
usleep(period);
}
void bmp3_check_rslt(const char api_name[], int8_t rslt)
{
switch (rslt)
{
case BMP3_OK:
/* Do nothing */
break;
case BMP3_E_NULL_PTR:
printf("API [%s] Error [%d] : Null pointer\r\n", api_name, rslt);
break;
case BMP3_E_COMM_FAIL:
printf("API [%s] Error [%d] : Communication failure\r\n", api_name, rslt);
break;
case BMP3_E_INVALID_LEN:
printf("API [%s] Error [%d] : Incorrect length parameter\r\n", api_name, rslt);
break;
case BMP3_E_DEV_NOT_FOUND:
printf("API [%s] Error [%d] : Device not found\r\n", api_name, rslt);
break;
case BMP3_E_CONFIGURATION_ERR:
printf("API [%s] Error [%d] : Configuration Error\r\n", api_name, rslt);
break;
case BMP3_W_SENSOR_NOT_ENABLED:
printf("API [%s] Error [%d] : Warning when Sensor not enabled\r\n", api_name, rslt);
break;
case BMP3_W_INVALID_FIFO_REQ_FRAME_CNT:
printf("API [%s] Error [%d] : Warning when Fifo watermark level is not in limit\r\n", api_name, rslt);
break;
default:
printf("API [%s] Error [%d] : Unknown error code\r\n", api_name, rslt);
break;
}
}
#endif
... View more