cancel
Showing results for 
Search instead for 
Did you mean: 

How to read Data with I2C from 3 Byte register?

Y-E-Quit
Associate

Hello, I am new to STM32 so I am currently try get the basic done.

I want to receive like written in the title, the temperature data from the BMP388 sensor.

Therefore I looked up the Datasheet and found out that I need following registers.

#define SLAVE_ADDRESS			        0x76 		// READ ADDRESS
 
#define BMP388_TEMP_MSB_REG 	        0x07
#define BMP388_TEMP_MID_REG		0x08
#define BMP388_TEMP_LSB_REG		0x09

The variables got initialised as:

uint8_t temp_data[3];
  uint8_t i2c_write;
  float temperature;

Then I want to receive the Data from the Sensor and did this as followed:

while (1)
  {
	  // CHECK-Bedingung
	  if(HAL_I2C_IsDeviceReady(&hi2c1, SLAVE_ADDRESS << 1, 1, HAL_MAX_DELAY) == HAL_OK){
		  HAL_GPIO_WritePin(LED_LD3_GPIO_Port, LED_LD3_Pin, SET);
	  }
 
 
	 // I2C read, first need to write to the Register for control Byte --> CONTROLL (00000101)
	 HAL_I2C_Mem_Write(&hi2c1, SLAVE_ADDRESS << 1, i2c_write, I2C_MEMADD_SIZE_8BIT, &i2c_write, 1, 1000);
	 // Read the Data from the SLAVE Device and stores it in the value i2c_rx_buffer with the size of a 3 Byte
	 HAL_I2C_Mem_Read(&hi2c1, SLAVE_ADDRESS << 1, BMP388_TEMP_MSB_REG , 3, temp_data, 3, 1000);
 
 
	 // stores the data of all three byte values in one!
	 temperature = (float)(((int32_t)temp_data[2] << 16) | ((int32_t)temp_data[1] << 8) | (int32_t)temp_data[0]);
	 float celsius = ((float)temperature - 32) * 5/9;
 
	 HAL_Delay(1000);
}

And like mentioned I set the SD0 Pin on the sensor toe GND to not let it floating (in Datasheet it is mentioned it would then not be working).

When looking at the Values of temperature, I get a Value of = 6947.22217 or other confusing values!

The Datasheet: https://www.mouser.com/pdfdocs/BST-BMP388-DS001-01.pdf

I hope you guys can help me.

5 REPLIES 5
KnarfB
Principal III

sensor data is rarely in float format. Read the data sheet carefully, especially Table 6. Looks like fixpoint == int with a small multiplication factor.

Bosch has also a reference library: https://github.com/BoschSensortec/BMP3-Sensor-API

hth

KnarfB

AScha.3
Chief III

or see, what the arduino lib is doing ->

https://github.com/adafruit/Adafruit_BMP3XX

If you feel a post has answered your question, please click "Accept as Solution".

You're building the value in the wrong order. The most significant byte comes first​.

At three bytes I'd assume you have the scaling wrong and sign management wrong too.​

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
S.Ma
Principal

The shortest way to get to the end of it is not to read the chip spec.

Do find the Bosch Driver in Git, it usually has a function to fill for the I2C / SPI Read/Write, and one test function which will power up, read one measurement, power down.

Maintenance of the driver is by the vendor, not you.

Example with other Bosch Sensor BME280 with STM32C0 here

The temperature is definitely NOT in Fahrenheit

I think you have the register naming backward, XLSB is 7, LSB 8, MSB 9

You're likely to need to sign-extend and scale depending on the mode you're using.

int32_t temp;

temp =(((int32_t)temp_data[2] << 16) | ((int32_t)temp_data[1] << 8) | (int32_t)temp_data[0]);

if (temp & 0x800000) temp |= 0xFF000000; // sign extend

float celsius = ((float)temp / 256.0f) * 0.005f; // scale 1x oversample 16-bit

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..