Thanks for answers. About using BSEC I already understood for what purpose it was made. For first time I will try to work only with BME api. But sensor still not working. On the same bus I have SHT20, I attached it to check if I2C bus is working. And it working but BME does not. I cant attach screensot from logic analyzer window now, but it is clearly seen that MCU sends start condition, then address 0x76(SDO pin connected to GND) but ther is no ACK from BME. Later I will attach screenshot. For the first time I desoldered BME from chinese module (CJMCU-680) and soldered it to my pcb. Sensor did not answered. I decided that I killed sensor during soldering. Then I took the same new module and connected it with my pcb with short wires but result is the same, no answer from bme. For pullup I used 4,7 k resistors. Some code: //================================ BUS WRITE ===========================================//
/*!
* @brief Write operation in I2C
*
* param[in] dev_addr I2C device address
* param[in] reg_addr register address
* param[in] reg_data_ptr pointer to the data to be written
* param[in] data_len number of bytes to be written
*
* @return result of the bus communication function
*/
int8_t bus_write(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data_ptr, uint16_t data_len)
{
uint16_t i;
int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */
/*
* Data on the bus should be like
* |------------+---------------------|
* | I2C action | Data |
* |------------+---------------------|
* | Start | - |
* | Write | (reg_addr) |
* | Write | (reg_data[0]) |
* | Write | (....) |
* | Write | (reg_data[len - 1]) |
* | Stop | - |
* |------------+---------------------|
*/
I2C_AcknowledgeConfig(I2C1,ENABLE); // Enable I2C acknowledgment
I2C_GenerateSTART(I2C1,ENABLE);
while (!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)){}; // Wait for EV5
UART1_Transmit_string("\r\nStart sent");
I2C_Send7bitAddress(I2C1,dev_addr,I2C_Direction_Transmitter); // Send slave address (dev_addr| 0x01)
while (!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){}; // Wait for EV6
UART1_Transmit_string("\r\nDev_addr sent");
I2C_SendData(I2C1,reg_addr); // Send register address
while (!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)){}; // Wait for EV8
UART1_Transmit_string("\r\nReg_addr sent");
for(i=0; i < data_len; i++)
{
I2C_SendData(I2C1, reg_data_ptr[i]); // Send all bytes
while (!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)){}; // Wait for EV8
}
UART1_Transmit_string("\r\nAll data sent");
I2C_GenerateSTOP(I2C1,ENABLE);
UART1_Transmit_string("\r\nStop sent");
return rslt;
}
//================================ BUS READ ===========================================//
/*!
* @brief Read operation in I2C
*
* param[in] dev_addr I2C device address
* param[in] reg_addr register address
* param[out] reg_data_ptr pointer to the memory to be used to store the read data
* param[in] data_len number of bytes to be read
*
* @return result of the bus communication function
*/
int8_t bus_read(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data_ptr, uint16_t data_len)
{
uint16_t i;
uint8_t status = 0;
/*
* Data on the bus should be like
* |------------+---------------------|
* | I2C action | Data |
* |------------+---------------------|
* | Start | - |
* | Write | (reg_addr) |
* | Stop | - |
* | Start | - |
* | Read | (reg_data[0]) |
* | Read | (....) |
* | Read | (reg_data[len - 1]) |
* | Stop | - |
* |------------+---------------------|
*/
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); // While the bus is busy
I2C_AcknowledgeConfig(I2C1,ENABLE); // Enable I2C acknowledgment
I2C_GenerateSTART(I2C1,ENABLE);
while (!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)){}; // Wait for EV5
I2C_Send7bitAddress(I2C1,dev_addr,I2C_Direction_Transmitter); // Send slave address for write
while (!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){}; // Wait for EV6
I2C_SendData(I2C1,reg_addr); // Send register address
while (!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)){}; // Wait for EV8
I2C_GenerateSTART(I2C1,ENABLE); // Send repeated START condition (aka Re-START)
while (!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)){}; // Wait for EV5
I2C_Send7bitAddress(I2C1,dev_addr,I2C_Direction_Receiver); // Send slave address for READ
while (!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)){}; // Wait for EV6
status = I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED);
for(i=0; i < data_len; i++)
{
if(i == data_len - 1) { I2C_AcknowledgeConfig(I2C1,DISABLE); }// Disable I2C acknowledgment if it is last byte to recieve
reg_data_ptr[i] = I2C_ReceiveData(I2C1); // Receive high byte
while (!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED)){}; // Wait for EV7 (Byte received from slave)
}
I2C_GenerateSTOP(I2C1,ENABLE); // Send STOP condition
/* Return 0 for Success, non-zero for failure */
if(status == 1)return 0;
else return status;
}
//===========================================================================================//
// Init I2C with Clock_Speed (in Hz)
void I2C_Port_Init(uint32_t Clock_Speed)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
// Init I2C
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE); // Enable I2C clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
I2C_DeInit(I2C1); // I2C reset to initial state
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; // I2C mode is I2C
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; // I2C fast mode duty cycle
I2C_InitStructure.I2C_OwnAddress1 = 0x00; // This device address (7-bit or 10-bit)
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; // Acknowledgment enable
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; // choose 7-bit address for acknowledgment
I2C_InitStructure.I2C_ClockSpeed = Clock_Speed;
I2C_Cmd(I2C1,ENABLE); // Enable I2C
I2C_Init(I2C1,&I2C_InitStructure); // Configure I2C
I2C_AcknowledgeConfig(I2C1, ENABLE);
while (I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY)); // Wait until I2C free
} Using: int main(void)
{
uint8_t set_required_settings;
uint16_t meas_period;
struct bme680_field_data data;
int8_t rslt = BME680_OK;
bme680_port_init();
BME680_On; // power on
I2C_Port_Init(100000); // init I2C
UART1_Transmit_string("\r\nI2C Init OK");
// Sensor settings
//Fixed I2C configuration
gas_sensor.dev_id = BME680_I2C_ADDR_PRIMARY; // 0x76
gas_sensor.intf = BME680_I2C_INTF;
gas_sensor.read = bus_read;
gas_sensor.write = bus_write;
gas_sensor.delay_ms = delay_ms_sys; // SysTickTimer
// amb_temp can be set to 25 prior to configuring the gas sensor
//or by performing a few temperature readings without operating the gas sensor.
gas_sensor.amb_temp = 25;
rslt = bme680_init(&gas_sensor);
if (rslt == BME680_OK)
{
sprintf(uart_buf,"\nBME680 Init OK -> result %i", rslt);
UART1_Transmit_string(uart_buf);
}
// Set the temperature, pressure and humidity settings
gas_sensor.tph_sett.os_hum = BME680_OS_2X;
gas_sensor.tph_sett.os_pres = BME680_OS_4X;
gas_sensor.tph_sett.os_temp = BME680_OS_8X;
gas_sensor.tph_sett.filter = BME680_FILTER_SIZE_3;
// Set the remaining gas sensor settings and link the heating profile
gas_sensor.gas_sett.run_gas = BME680_ENABLE_GAS_MEAS;
// Create a ramp heat waveform in 3 steps
gas_sensor.gas_sett.heatr_temp = 320; // degree Celsius
gas_sensor.gas_sett.heatr_dur = 150; // milliseconds
// Select the power mode
// Must be set before writing the sensor configuration
gas_sensor.power_mode = BME680_FORCED_MODE;
// Set the required sensor settings needed
set_required_settings = BME680_OST_SEL | BME680_OSP_SEL | BME680_OSH_SEL | BME680_FILTER_SEL | BME680_GAS_SENSOR_SEL;
// Set the desired sensor configuration
rslt = bme680_set_sensor_settings(set_required_settings, &gas_sensor);
if (rslt == BME680_OK)
{
sprintf(uart_buf,"\nBME680 set sensor settings OK ->result %i", rslt);
UART1_Transmit_string(uart_buf);
}
// Set the power mode
rslt = bme680_set_sensor_mode(&gas_sensor);
if (rslt == BME680_OK)
{
sprintf(uart_buf,"\nBME680 set sensor mode OK ->result %i", rslt);
UART1_Transmit_string(uart_buf);
}
// Get the profile duration of the sensor
bme680_get_profile_dur(&meas_period, &gas_sensor);
while (1)
{
delay_ms_sys(meas_period); // Delay till the measurement is ready
rslt = bme680_get_sensor_data(&data, &gas_sensor);
sprintf(uart_buf,"T: %.2f degC, P: %.2f hPa, H %.2f %%rH ", data.temperature / 100.0f, data.pressure / 100.0f, data.humidity / 1000.0f );
UART1_Transmit_string(uart_buf);
if(data.status & BME680_GASM_VALID_MSK) // Avoid using measurements from an unstable heating setup
{
sprintf(uart_buf,", G: %d ohms", data.gas_resistance);
UART1_Transmit_string(uart_buf);
}
UART1_Transmit_string("\r\n");
// Trigger the next measurement if you would like to read data out continuously
if (gas_sensor.power_mode == BME680_FORCED_MODE) {
rslt = bme680_set_sensor_mode(&gas_sensor);
}
... View more