01-07-2021 11:16 AM
Hello,
I am trying to get the BME680 working with the Bosch Lib and a PIC32MM0256GPM064.
I am able to read and write registers and see the correct values via printf's and on my logic analyzer.
If the example code is reading the sensor data via bme680_get_sensor_data the rslt is everytime BME680_W_NO_NEW_DATA.
I also tried it with a PIC18F46K42 and got the same problem (but different I2C code provided by MCC).
My code to verify the I2C functions:
user_i2c_read(0x77, 0xD0, buffer, 1);
printf("Read Reg 0x%X: 0x%X (0x61 expected)\n",(0xD0),buffer[0]);
user_delay_ms(100);
buffer[0] = 0x03;
user_i2c_write(0x77, 0x72, buffer, 1);
printf("writing 0x03 to 0x72...\n");
buffer[0] = 0x04;
user_i2c_write(0x77, 0x64, buffer, 1);
printf("writing 0x04 to 0x64...\n");
buffer[0] = 0x05;
user_i2c_write(0x77, 0x5A, buffer, 1);
printf("writing 0x05 to 0x5A...\n");
buffer[0] = 0x06;
user_i2c_write(0x77, 0x50, buffer, 1);
printf("writing 0x06 to 0x50...\n");
user_delay_ms(100);
buffer[0] = 0;
user_i2c_read(0x77, 0x72, buffer, 1); // read
printf("Read Reg 0x%X: 0x%X (0x03 expected)\n",(0x72),buffer[0]);
buffer[0] = 0;
user_i2c_read(0x77, 0x64, buffer, 1); // read
printf("Read Reg 0x%X: 0x%X (0x04 expected)\n",(0x64),buffer[0]);
buffer[0] = 0;
user_i2c_read(0x77, 0x5A, buffer, 1); // read
printf("Read Reg 0x%X: 0x%X (0x05 expected)\n",(0x5A),buffer[0]);
buffer[0] = 0;
user_i2c_read(0x77, 0x50, buffer, 1); // read
printf("Read Reg 0x%X: 0x%X (0x06 expected)\n",(0x50),buffer[0]);
Console output is:
Logic Analyzer:
Looks good for me.
But if I let the example code running, BME680_W_NO_NEW_DATA is the result.
If I let it run once and then read out the wait and heat registers there are wrong (but constant) numbers in.
What could I do? Is my verification correct?
Thanks!
01-14-2021 03:40 AM - edited 01-14-2021 03:41 AM
Hi Sir:
I want to know whether you verified our API code, I don't care about your source code with writing and reading register directly.
I verified your source code with API part, change " gas_sensor.dev_id = BME680_I2C_ADDR_PRIMARY << 1;", and then I got the correct values. Please see the following log and the attachment I verified.
T: 26.42 degC, P: 1016.56 hPa, H 25.62 %rH , G: 736019 ohms
T: 26.42 degC, P: 1016.56 hPa, H 25.62 %rH , G: 739283 ohms
T: 26.42 degC, P: 1016.55 hPa, H 25.62 %rH , G: 741750 ohms
T: 26.42 degC, P: 1016.56 hPa, H 25.62 %rH , G: 738464 ohms
T: 26.41 degC, P: 1016.56 hPa, H 25.63 %rH , G: 740926 ohms
T: 26.41 degC, P: 1016.56 hPa, H 25.62 %rH , G: 730376 ohms
T: 26.41 degC, P: 1016.56 hPa, H 25.63 %rH , G: 740926 ohms
T: 26.41 degC, P: 1016.55 hPa, H 25.62 %rH , G: 733590 ohms
T: 26.41 degC, P: 1016.55 hPa, H 25.63 %rH , G: 736019 ohms
T: 26.41 degC, P: 1016.56 hPa, H 25.63 %rH , G: 738464 ohms
If you use the same code don't get the correct values, recommend you to check I2C or SPI communcation.
01-14-2021 05:30 PM
Hi Sir,
and how can I verify your API code? Please give me an example.
I used your function prototype to verfiy it like its descripted in your library.
Regarding your shifting of the address one to the left, for the SPI it will not be used because SPI is not using an address (so still not working).
And if I move the address one to the left with the I2C function, I will not get any ACK from the BME680 anymore (without the change I am getting).
Thanks.
01-15-2021 02:32 AM
Hi Sir:
Shifting of the address is only for my platform, I am not sure that is fit on your platform.
I also use the same example code as yours, which you posted and is from github.
The example code please see the attachment of the last reply.
01-15-2021 09:06 PM
Hello
To get the sensor data correct, the following shoud be checked
1) i2c read/write should work as expected, the BME680 API uses burst read and burst write
2) sensor HW is configured properly (essentially correct values are written to registers, also make sure delays are respected otherwise this could abuse the sensor and something may stop working), that's why a delay_ms function needs to be supplied to the BME680 API
It looks your I2C read / write are working, and let's assume this is the case.Then the next step is to make sure the sensor is configured properly, and this is best done by calling the APIs because all the requirements/specs are taken into account by the APIs and they are verified, when working with HW like sensors, one common issue is that some bit might have been missed and the HW doesn't work as expected and when you find it out, it turns on like a magic.
Since you have implemented the i2c_read and i2c_write, you just need to implement a delay_ms and feed those callbacks to the API, and all the detailed configurations are taken care of automatically, see details at: https://github.com/BoschSensortec/BME680_driver/blob/master/README.md
a lot of the code could be copied and pasted to your project and simply works, all you need to focus on is to make sure:
the read(), write(), and delay_ms() are working as expected per the API requirment.
if that still doesn't help, a much more tedious way is to: dump all the registers from the sensor, and check line by line which register does not have expected value.
hopefully this helps.
01-22-2021 03:31 PM - edited 01-22-2021 03:38 PM
Hi all,
like I wrote before and you can see my code, I implemented the delay routine.
I looked a lot in the library and I could more identify what the problem could be. I read back the registers after the library should wrote the values in and there are still zero (osrs_x, filter).
Then I was filling the registers by my own and the library gives me data back, temperature, pressure and humidity.
---> that mean that my read function is working well
Lets concentrate on the write function.
The documentation in the h file give the following introduction:
/*
* Data on the bus should be like
* |---------------------+--------------+-------------|
* | MOSI | MISO | Chip Select |
* |---------------------+--------------|-------------|
* | (don't care) | (don't care) | HIGH |
* | (reg_addr) | (don't care) | LOW |
* | (reg_data[0]) | (don't care) | LOW |
* | (....) | (....) | LOW |
* | (reg_data[len - 1]) | (don't care) | LOW |
* | (don't care) | (don't care) | HIGH |
* |---------------------+--------------|-------------|
*/
But the datasheet is saying:
A multiplye byte write is not auto-incrementing. Does that mean I have to add between every two bytes the register address again?
E.g:
/*
* Data on the bus should be like
* |---------------------+--------------+-------------|
* | MOSI | MISO | Chip Select |
* |---------------------+--------------|-------------|
* | (don't care) | (don't care) | HIGH |
* | (reg_addr[0]) | (don't care) | LOW |
* | (reg_data[0]) | (don't care) | LOW |
* | (reg_addr[1]) | (don't care) | LOW |
* | (reg_data[1]) | (don't care) | LOW |
* | (reg_addr[2]) | (don't care) | LOW |
* | (reg_data[2]) | (don't care) | LOW |
* | (....) | (....) | LOW |
* | (reg_addr[len - 1]) | (don't care) | LOW |
* | (reg_data[len - 1]) | (don't care) | LOW |
* | (don't care) | (don't care) | HIGH |
* |---------------------+--------------|-------------|
*/
Or is the bosch library filling the reg_data with addresses? I tried both ways but the library is still not able to write...
Could you give me some more information about that please. Maybe also some logic analyzer plots.
Like I am said, if I write the config registers by myself, I am able to read out sensor data, with the library not.
My write function without incrementing from my side:
uint8_t WriteBuffer[100];
uint8_t i;
for (i = 0; i < len; i++) {
WriteBuffer[i+1] = reg_data[i];
}
WriteBuffer[0] = reg_addr;
SPI_CS_SetLow();
SPI1_WriteBlock(WriteBuffer, len+1);
SPI_CS_SetHigh();
Or my write function with incrementing addresses from my side:
uint8_t WriteBuffer[100];
uint8_t i;
for (i = 0; i < (len*2); i = i + 2) {
WriteBuffer[i] = reg_addr + (i/2);
WriteBuffer[i+1] = reg_data[i/2];
}
WriteBuffer[0] = reg_addr;
SPI_CS_SetLow();
SPI1_WriteBlock(WriteBuffer, len*2);
SPI_CS_SetHigh();