BMI323 sensor not detected

#include <SPI.h>

#define BMI323_CS 10 // Chip Select Pin

#define ACC_CONF 0x20 // Accelerometer configuration register
#define GYR_CONF 0x21 // Gyroscope configuration register
#define CMD 0x7E // Command register
#define CHIP_ID 0x00 // Chip ID register

void setup() {
Serial.begin(115200);
SPI.begin();

pinMode(BMI323_CS, OUTPUT);
digitalWrite(BMI323_CS, HIGH); // Deselect sensor

delay(100);

uint8_t chipID = readRegister(CHIP_ID);
Serial.print("Chip ID: 0x");
Serial.println(chipID, HEX);

if (chipID != 0x41) { // Check the expected chip ID
    Serial.println("ERROR: BMI323 not detected correctly!");
    while (1);
}

writeRegister(ACC_CONF, 0x708B); // Configure Accelerometer
writeRegister(GYR_CONF, 0x708B); // Configure Gyroscope

}

void loop() {
int16_t x = readRegister16(0x03);
int16_t y = readRegister16(0x05);
int16_t z = readRegister16(0x07);

Serial.print("X: "); Serial.print(x);
Serial.print("\tY: "); Serial.print(y);
Serial.print("\tZ: "); Serial.println(z);

delay(500);

}

// SPI Read
uint8_t readRegister(uint8_t reg) {
digitalWrite(BMI323_CS, LOW);
SPI.transfer(reg | 0x80); // Set Read bit
uint8_t data = SPI.transfer(0x00);
digitalWrite(BMI323_CS, HIGH);
return data;
}

// SPI Read 16-bit
uint16_t readRegister16(uint8_t reg) {
digitalWrite(BMI323_CS, LOW);
SPI.transfer(reg | 0x80); // Set Read bit
uint8_t highByte = SPI.transfer(0x00);
uint8_t lowByte = SPI.transfer(0x00);
digitalWrite(BMI323_CS, HIGH);
return (highByte << 8) | lowByte;
}

// SPI Write
void writeRegister(uint8_t reg, uint8_t value) {
digitalWrite(BMI323_CS, LOW);
SPI.transfer(reg & 0x7F); // Clear Read bit
SPI.transfer(value);
digitalWrite(BMI323_CS, HIGH);
}
i try this code using spi in arduino uno but my sensor is not detected

Is the BMI323 part of a module? If so, which one? Please provide a link.

Please edit your post as some of your code has escaped the code tags.

Yep it is in one of the lines of code or maybe a hardware error. I cannot read your code or follow the non existent annotated schematic showing exactly how you wired it. The links to the hardware technical information did not show on my screen.

hello @markd833 , yaa its BMI323 module and what to edit in code

Which one? Where did you get it from?

EDIT: The BMI323, according to the manufacturers website, can be configured to use an SPI or I2C interface. You need to figure out which interface your module is configured for.


i am using sensor which provided in pic , can u give me code using i2c

Your original code was for an SPI interface. Are you sure you are now using the I2C interface?

I would start by running an I2C scanner to see if the device can be detected first.

Perhaps this earlier discussion in the forum would help you get started:

yes , i want to configure bmi323 with i2c now i m not able to detect sensor

thanks for your reply

Seems like a standard Bosch interface. For using I²C and I3C, it is recommended to hard-wire the CSB line to VDDIO.

hey @surfertim , i shorted VDD and VDDIO is it right ,can u explain me in brief.

Bosch uses about the same interface for all it's products.
The chip select (CS) determines the protocol.
If CS remains HIGH during boot. It uses i2c.
If CS is at any time LOW, it uses SPI.
All my Bosch devices use the same interface.

hey @surferTim , can u provide me the code using i2c

I don't have a BMI323. I have several Bosch devices.
The best I can do is help you get the Arduino to detect it on i2c.

@ravikumarch If you believe that you have correctly configured the sensor to operate in I2C mode, then run an I2C scanner sketch to see if the sensor is detected.

In addition to markd833, the i2c address will be dependent on the SDO pin level.
If LOW (GND), the address is 0x68,
If HIGH (VDDIO), the address is 0x69

hey @markd833 and @SurferTim ,
here is my code :
#include <Wire.h>

#define BMI323_ADDR 0x69 // I2C Address of BMI323

#if defined(ESP32)
#define I2C_SDA 21 // ESP32-S3: Change as needed
#define I2C_SCL 22 // ESP32-S3: Change as needed
#endif

void i2cWrite(uint8_t reg, uint8_t value) {
Wire.beginTransmission(BMI323_ADDR);
Wire.write(reg);
Wire.write(value);
Wire.endTransmission();
}

uint8_t i2cRead(uint8_t reg) {
Wire.beginTransmission(BMI323_ADDR);
Wire.write(reg);
Wire.endTransmission(false);
Wire.requestFrom(BMI323_ADDR, 1);
return Wire.available() ? Wire.read() : 0;
}

void i2cReadBytes(uint8_t reg, uint8_t *data, size_t len) {
Wire.beginTransmission(BMI323_ADDR);
Wire.write(reg);
Wire.endTransmission(false);
Wire.requestFrom(BMI323_ADDR, len);
for (size_t i = 0; i < len && Wire.available(); i++) {
data[i] = Wire.read();
}
}

void bmi323_init() {
Serial.println("Initializing BMI323...");

uint8_t chip_id = i2cRead(0x00);  // Read chip ID
Serial.print("Chip ID: 0x");
Serial.println(chip_id, HEX);

if (chip_id != 0x41) {  // Expected chip ID for BMI323
    Serial.println("ERROR: Invalid Chip ID!");
    while (1);  // Halt execution
}

// Reset BMI323
i2cWrite(0x7E, 0xB6);
delay(10);

// Enable accelerometer
i2cWrite(0x41, 0x04);  // ACC power mode: Normal
i2cWrite(0x40, 0x01);  // Enable ACC

// Set accelerometer range to ±4g
i2cWrite(0x59, 0x01);

// Set output data rate (ODR) to 100 Hz
i2cWrite(0x58, 0x08);

Serial.println("BMI323 Initialized!");

}

void bmi323_read_acceleration() {
uint8_t data[6];
i2cReadBytes(0x0C, data, 6);

int16_t ax = (int16_t)((data[1] << 8) | data[0]);
int16_t ay = (int16_t)((data[3] << 8) | data[2]);
int16_t az = (int16_t)((data[5] << 8) | data[4]);

Serial.print("Accel X: "); Serial.print(ax);
Serial.print(", Y: "); Serial.print(ay);
Serial.print(", Z: "); Serial.println(az);

}

void setup() {
Serial.begin(115200);

#if defined(ESP32)
    Wire.begin(I2C_SDA, I2C_SCL, 400000);  // ESP32-S3: Use custom SDA/SCL
#else
    Wire.begin();  // Arduino Uno: Uses default SDA=A4, SCL=A5
#endif

bmi323_init();

}

void loop() {
bmi323_read_acceleration();
delay(1000);
}
output given in screenshot:

I've got zero knowledge of the BMI323 chip so this may be wrong, but page 61 the datasheet has a table showing the chip ID at register address 0x00, which is what your code appears to be accessing.

However, the datasheet seems to indicate that the register holds a 16-bit value. In order to get the whole value, you need to read 2 bytes and combine them to get a 16-bit word. Maybe using your i2creadbytes function?

Did the I2C scanner detect the device?

Did you try I2C scanner?

hello @markd833, no my device is not detect.

hello @ahsrabrifat , yes i try scanner i get i2c address 0x69

:exclamation_question_mark: Your device is either detected or it isn't.

The I2C scanner should detect a device at address 0x68 or 0x69. Your response to @ahsrabrifat says it was detected at address 0x69.

Your code is using that address so assuming the device can reliably be detected, we can move on to other sources of error.

Take a look at the datasheet. I think all register parameters were 16-bits (from memory). You could modify your i2cRead function to perform 2 wire.read calls and combine them to provide a single 16-bit answer. You would need to change the return datatype of the function to uint16_t and any variables that hold the response in your code too.