GravityTroubleshooting

Gravity: MEMS Gas Sensor (MiCS-4514)

userHead AhmedElashouti 2022-05-22 07:50:57 896 Views1 Replies

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);

}

2022-06-17 01:33:52

Hello! It is recommended that you use the iic bus scan to confirm whether the sensor can be found and the sensor address.

userHeadPic Tonny12138