how can use i2c for external sensor

kishan patel
Posts: 45
Joined: Wed Aug 30, 2017 4:56 am

how can use i2c for external sensor

Postby kishan patel » Tue Nov 21, 2017 9:32 am

I want to use i2c for external sensor.
Can anyone tell me that which pin should i use.

and how can i read data from the external sensor.I have also mention my code as below.
I am trying to read device_id of external sensor.but i could not receive/communicate with it.


void i2c_master_init(void)
{
int i2c_master_port = I2C_MASTER_NUM;

i2c_config_t conf;
conf.mode = I2C_MODE_MASTER;
conf.sda_io_num = I2C_MASTER_SDA_IO;
conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
conf.scl_io_num = I2C_MASTER_SCL_IO;
conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
conf.master.clk_speed = I2C_MASTER_FREQ_HZ;

i2c_param_config(i2c_master_port, &conf);
i2c_driver_install(i2c_master_port, conf.mode,I2C_EXAMPLE_MASTER_RX_BUF_DISABLE,I2C_EXAMPLE_MASTER_TX_BUF_DISABLE, 0);
}

//i have used gpio25 as SDA and gpio26 as SCL.

esp_err_t i2c_master_read_data_kt(char* register_address, uint8_t* data_rd, size_t size)
{
if (size == 0) {
return ESP_OK;
}
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, ( SLAVE_ADDRESS << 1 ) | READ_BIT, ACK_CHECK_EN);
i2c_master_write_byte(cmd,0x00 ,ACK_CHECK_EN);
//i2c_master_write(cmd,0x00,size,ACK_CHECK_EN);
if (size > 1) {
i2c_master_read(cmd, data_rd, size - 1, ACK_VAL);
}
i2c_master_read_byte(cmd, data_rd + size - 1, NACK_VAL);
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
return ret;

}

// i have put register-value(device_id address) directly as 0x00.

tell me steps to communicate with external sensor using i2c.

chegewara
Posts: 1211
Joined: Wed Jun 14, 2017 9:00 pm

Re: how can use i2c for external sensor

Postby chegewara » Tue Nov 21, 2017 7:32 pm

On this diagram you are asking about Single byte read/ master. As you can see, before you can read from device you HAVE to send start + slave device address with write byte + register address you want to read. Since you want to read from device you need to send another start + slave address with byte read + stop.
  1. write address + register:
  2. i2c_cmd_handle_t cmd = i2c_cmd_link_create();
  3. start - i2c_master_start(cmd);
  4. write address - i2c_master_write_byte(cmd, ( SLAVE_ADDRESS << 1 ) | WRITE_BIT, ACK_CHECK_EN);
  5. i2c_master_write_byte(cmd,REGISTER ,ACK_CHECK_EN);
  6. i2c_master_stop(cmd);
  7. esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_RATE_MS);
  8. i2c_cmd_link_delete(cmd);
  • read data:
  • cmd = i2c_cmd_link_create();
  • i2c_master_start(cmd);
  • i2c_master_write_byte(cmd, ( SLAVE_ADDRESS << 1 ) | READ_BIT, ACK_CHECK_EN);
  • i2c_master_read_byte(cmd, data_rd + size - 1, NACK_VAL);
  • i2c_master_stop(cmd);
  • esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_RATE_MS);
  • i2c_cmd_link_delete(cmd);
Image

kishan patel
Posts: 45
Joined: Wed Aug 30, 2017 4:56 am

Re: how can use i2c for external sensor

Postby kishan patel » Wed Nov 22, 2017 9:39 am

thanks for reply.
i have worked same as u suggest.You can see my code to read single byte as below.

void i2c_read_data_byte_kt(char register_address,uint8_t* read_buffer)
{
i2c_cmd_handle_t cmd = i2c_cmd_link_create();

i2c_master_start(cmd);
i2c_master_write_byte(cmd,(SLAVE_ADDRESS << 1) | WRITE_BIT ,ACK_CHECK_EN);
i2c_master_write_byte(cmd,register_address,ACK_CHECK_EN);
i2c_master_stop(cmd);
i2c_master_cmd_begin(I2C_MASTER_NUM,cmd,1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);

cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (SLAVE_ADDRESS << 1) | I2C_MASTER_READ, true);
i2c_master_read_byte(cmd, read_buffer, NACK_VAL);
i2c_master_stop(cmd);
i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);

}


its working fine.

now,i want to write single byte.I have searched much about it.But i could not successful in that.Please,see my code to write single byte. and guide me.



void i2c_write_data_byte_kt(void)
{
uint8_t write_data = 0x08;

i2c_cmd_handle_t cmd = i2c_cmd_link_create();

i2c_master_start(cmd);
i2c_master_write_byte(cmd,(SLAVE_ADDRESS << 1) | WRITE_BIT ,ACK_CHECK_EN);
i2c_master_write_byte(cmd,0x2D,ACK_CHECK_EN);
// i2c_master_write_byte(cmd,0x80,ACK_CHECK_EN);
// i2c_master_write_byte(cmd,&write_data,ACK_CHECK_EN);
i2c_master_write(cmd,0x80,1,ACK_CHECK_EN);
i2c_master_stop(cmd);
i2c_master_cmd_begin(I2C_MASTER_NUM,cmd,1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);

/*
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (SLAVE_ADDRESS << 1) | I2C_MASTER_WRITE, true);
i2c_master_write(cmd,0x08,1,ACK_CHECK_EN);
i2c_master_stop(cmd);
i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
*/
}

I HAVE TRIED BY MANY CHANGES.SO,THERE ARE SOME COMMENTS.

chegewara
Posts: 1211
Joined: Wed Jun 14, 2017 9:00 pm

Re: how can use i2c for external sensor

Postby chegewara » Wed Nov 22, 2017 5:45 pm

When you write to I2C all but last one byte need to be acknowledged. Since you are trying to write just one byte you need to send it with NACK_VAL:

Code: Select all

i2c_master_write(cmd,0x08,1,NACK_VAL);	

Who is online

Users browsing this forum: No registered users and 26 guests