Gravity: MEMS Gas Sensor (MiCS-4514)
I am trying to get the MEMS sensor ( which is working via i2c) running with esp32. I am trying to write a C code running on esp-idf .Unfortunately only examples for arduino code is provided other than that I can't find any documentation on how to communicate with the sensor ( on which frequency does the sensor operate ? ). I can't establish a successful communication with the sensors via i2c and i am not sure where the problem is. I waited for 3 mins warm up and then tried to wake up the sensors and finally reading values. however I don't receive any acknowledgement from the sensor. I tried the four different addresses ( 0x75 till 0x78) provided in the datasheet. I would appreciate if someone take a look in the code.
#define I2C_MASTER_SCL_IO 22 /*!< gpio number for i2c slave clock */
#define I2C_MASTER_SDA_IO 21 /*!< gpio number for i2c slave Data */
#define I2C_MASTER_FREQ_HZ 100000 /*!< I2C master clock frequency */
#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
#define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */
#define READ_BIT I2C_MASTER_READ /*!< I2C master read */
#define MEMS_SENSOR_ADDR 0x75 /*!< slave address for BH1750 sensor */
#define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */
#define READ_BIT I2C_MASTER_READ /*!< I2C master read */
#define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/
#define ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */
#define ACK_VAL 0x0 /*!< I2C ack value */
#define NACK_VAL 0x1 /*!< I2C nack value */
#define OX_REGISTER_HIGH 0x04
#define OX_REGISTER_LOW 0x05
#define RED_REGISTER_HIGH 0x06
#define RED_REGISTER_LOW 0x07
#define POWER_REGISTER_HIGH 0x08
#define POWER_REGISTER_LOW 0x09
#define POWER_MODE_REGISTER 0x0a
#define SLEEP_MODE 0x00
#define WAKE_UP_MODE 0x01
#define OX_MODE 0x00
#define RED_MODE 0x01
#define CO 0x01 // Carbon Monoxide
#define CH4 0x02 // Methane
#define C2H5OH 0x03 // Ethanol
#define C3H8 0x04 // Propane
#define C4H10 0x05 // Iso Butane
#define H2 0x06 // Hydrogen
#define H2S 0x07 // Hydrothion
#define NH3 0x08 // Ammonia
#define NO 0x09 // Nitric Oxide
#define NO2 0x0A // Nitrogen Dioxide
static esp_err_t i2c_master_init(void)
{
int i2c_master_port = 0;
i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = I2C_MASTER_SDA_IO,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_io_num = I2C_MASTER_SCL_IO,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = I2C_MASTER_FREQ_HZ, // 100 KHZ
// .clk_flags = 0, /*!< Optional, you can use I2C_SCLK_SRC_FLAG_* flags to choose i2c source clock here. */
};
esp_err_t err = i2c_param_config(i2c_master_port, &conf);
if (err != ESP_OK) {
return err;
}
return i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
}
static esp_err_t i2c_read_sensor_data(i2c_port_t i2c_num, uint8_t* data)
{
int ret=0;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
ESP_ERROR_CHECK(i2c_master_start(cmd));
ret=i2c_master_write_byte(cmd, MEMS_SENSOR_ADDR << 1 | WRITE_BIT, ACK_CHECK_EN);
ret=i2c_master_write_byte(cmd, OX_REGISTER_HIGH, ACK_CHECK_EN);
vTaskDelay(10 / portTICK_PERIOD_MS);
ESP_ERROR_CHECK(i2c_master_start(cmd));
ret=i2c_master_write_byte(cmd, MEMS_SENSOR_ADDR << 1 | READ_BIT, ACK_CHECK_EN);
i2c_master_read(cmd, data, 6, ACK_VAL);
ESP_ERROR_CHECK(i2c_master_stop(cmd));
ret=i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_PERIOD_MS);
printf ("err cmd begin read = %d \n", ret);
ret=0;
i2c_cmd_link_delete(cmd);
return ret;
}
static esp_err_t sensor_wakeup(i2c_port_t i2c_num)
{
int ret=0;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
ESP_ERROR_CHECK(i2c_master_start(cmd));
ret=i2c_master_write_byte(cmd, MEMS_SENSOR_ADDR << 1 | WRITE_BIT, ACK_CHECK_EN);
ret=i2c_master_write_byte(cmd, 0x0a, ACK_CHECK_EN);
ret=i2c_master_write_byte(cmd, 0x01, ACK_CHECK_EN);
ESP_ERROR_CHECK(i2c_master_stop(cmd));
ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_PERIOD_MS);
printf ("err cmd begin write = %d \n", ret);
ret=0;
i2c_cmd_link_delete(cmd);
return ret;
}
void task(void *pvParameters)
{
uint8_t recv_data[6]={0};
int ret=0;;
while (1)
{
ret=i2c_read_sensor_data(0, recv_data);
for (int i =0; i < 6; ++i)
{
printf ("data[%d]= %d \t",i, recv_data[i] );
}
printf ("\n");
for (int i =0; i < 6; ++i)
{
recv_data[i]=0;
}
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
void app_main(void)
{
ESP_ERROR_CHECK(i2c_master_init());
vTaskDelay(100 / portTICK_PERIOD_MS);
sensor_wakeup(0);
xTaskCreate(task, "MEMS_Task", 2048, NULL, 4, &task_handle);
}
Hello! It is recommended that you use the iic bus scan to confirm whether the sensor can be found and the sensor address.
Tonny12138