Page 1 of 2

Problem reading I2C sensor

Posted: Sun Feb 19, 2017 2:59 pm
by Maq_aux
Hello,

i´ve been trying to get data out of a SDP600 differential pressure sensor from Sensirion for a couple of days now.
The problem is that i can not read back data at all. The sensor is wired correctly and answering a scan request. To start the transmission of measuring data, you have to write a command (0xF1) to the sensor, then trigger the reading of 2-3 bytes (if additional crc byte is needed) and then wait for about 5ms while the sensor is processing the data.
All these steps are working but when the sensor is finished (SCA and SDA are released to high), the ESP32 does not read back any data (see attached picture from logic analyzer).
Does anyone have an idea how to solve this and read back the data?

Code:

Code: Select all

	i2c_cmd_handle_t cmd = i2c_cmd_link_create();
	i2c_master_start(cmd);
	i2c_master_write_byte(cmd, (hwaddr << 1) | I2C_MASTER_WRITE, 1 /* expect ack */);
	i2c_master_write_byte(cmd, 0xF1, 1);
	i2c_master_stop(cmd);
	i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000/portTICK_PERIOD_MS);
	i2c_cmd_link_delete(cmd);

	cmd = i2c_cmd_link_create();
	i2c_master_start(cmd);
	i2c_master_write_byte(cmd, (hwaddr << 1) | I2C_MASTER_READ, 1 /* expect ack */);
	i2c_master_stop(cmd);
	i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000/portTICK_PERIOD_MS);
	i2c_master_start(cmd);
	i2c_master_read_byte(cmd, &msb, 1);
	i2c_master_read_byte(cmd, &lsb, 1);
	i2c_master_read_byte(cmd, &xlsb, 0);
	i2c_master_stop(cmd);
	i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000/portTICK_PERIOD_MS);
	i2c_cmd_link_delete(cmd);
	
Pictures from logic analyzer:

Image

Image

kind regards,
Markus

Re: Problem reading I2C sensor

Posted: Mon Feb 20, 2017 6:32 am
by ChrisHolza
Please check

https://github.com/espressif/esp-idf/issues/304

and

https://github.com/espressif/esp-idf/issues/344

, maybe one of these applies to your problem.

Re: Problem reading I2C sensor

Posted: Mon Feb 20, 2017 1:18 pm
by kolban
At a guess, you don't want the I2C stop/start in the middle of your read logic. This might be what you need for that fragment:

Code: Select all

   cmd = i2c_cmd_link_create();
   i2c_master_start(cmd);
   i2c_master_write_byte(cmd, (hwaddr << 1) | I2C_MASTER_READ, 1 /* expect ack */);
   i2c_master_read_byte(cmd, &msb, 0);
   i2c_master_read_byte(cmd, &lsb, 0);
   i2c_master_read_byte(cmd, &xlsb, 1);
   i2c_master_stop(cmd);
   i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000/portTICK_PERIOD_MS);
   i2c_cmd_link_delete(cmd);

Re: Problem reading I2C sensor

Posted: Mon Feb 20, 2017 8:12 pm
by Maq_aux
Hey guys,

thanks for your replies! After the correct usage of the Ack/Nack bit when reading back data, my results look a bit better.
After some attempts and trying to stick to the measurement triggering example on page 5 of the sensor´s datasheet, the following code works best so far even if it seems very unclean to me.

Code: Select all

	i2c_cmd_handle_t cmd = i2c_cmd_link_create();
	i2c_master_start(cmd);
	i2c_master_write_byte(cmd, (hwaddr << 1) | I2C_MASTER_WRITE, 1);
	i2c_master_write_byte(cmd, 0xF1, 1);

	uint8_t msb;
	uint8_t lsb;
	uint8_t xlsb;
	
	i2c_master_write_byte(cmd, (hwaddr << 1) | I2C_MASTER_READ, 0);
	i2c_master_read_byte(cmd, &msb, 0);
	i2c_master_read_byte(cmd, &lsb, 0);
	i2c_master_read_byte(cmd, &xlsb, 0);
	i2c_master_stop(cmd);
	i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000/portTICK_PERIOD_MS);
	i2c_cmd_link_delete(cmd);
The result is the following:

Image

So now i get back three bytes but they are invalid and always "255" because the sensor did not have enough time for the conversion.
If I change line 10 to

Code: Select all

i2c_master_write_byte(cmd, (hwaddr << 1) | I2C_MASTER_READ, 0);
, i get exactly the same result as before.

Re: Problem reading I2C sensor

Posted: Tue Feb 21, 2017 5:39 pm
by Maq_aux
Thanks for your replies!

Unfortunately even with the new knowledge about the ACK/NACK bit nothing has changed.
I can reproduce the I2C error when running in release config but i´ve already been using the debug config all the time.
Do you know if clock stretching is already working correctly on the ESP32? Do you have any other suggestions what I´m doing wrong when looking at the proposed measurement triggering on page 5 of the datasheet? https://www.sensirion.com/fileadmin/use ... _V.1.9.pdf

regards,
Markus

Re: Problem reading I2C sensor

Posted: Sun Feb 26, 2017 4:40 pm
by telanoc
Didn't you say there had to be a 5 msec delay before reading the data back from the sensor? I don't see a delay in the code you posted.

Best regards,
Pete C.

Re: Problem reading I2C sensor

Posted: Sun Feb 26, 2017 7:17 pm
by WiFive
It appears the read timeout is hardcoded to 2.5ms in the driver so if you are relying on clock stretching of 5ms you may have to adjust it.

Re: Problem reading I2C sensor

Posted: Sun May 07, 2017 3:25 pm
by Maq_aux
After I had to take care of many other things in the last weeks and I got the sensor to work with a very simple bitbanging I2C driver (got it up and running on second try), I had some time to get the sensor working with the I2C driver of the IDF today.

WiFive´s hint was correct, I changed the timeout to 10ms (components\driver\i2c.c -> "set timeout of receiving data") in the code and now everything is working fine.

Thank you very much for all your help, here is the working code fragment in case someone needs it in the future:

Code: Select all

	
	uint8_t Byte1;
	uint8_t Byte2;
	uint8_t Byte3;

	cmd = i2c_cmd_link_create();
	i2c_master_start(cmd);
	i2c_master_write_byte(cmd, (0x40 << 1) | I2C_MASTER_WRITE, 1 /* expect ack */);
	i2c_master_write_byte(cmd, (0xF1), 1 /* expect ack */);
	i2c_master_start(cmd);
	i2c_master_write_byte(cmd, (0x40 << 1) | I2C_MASTER_READ, 1 /* expect ack */);

	i2c_master_read_byte(cmd, &Byte1, ACK_VAL);
	i2c_master_read_byte(cmd, &Byte2, ACK_VAL);
	i2c_master_read_byte(cmd, &Byte3, ACK_VAL);
	i2c_master_stop(cmd);
	i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000/portTICK_PERIOD_MS);
	i2c_cmd_link_delete(cmd);

Re: Problem reading I2C sensor

Posted: Thu Jul 27, 2017 4:50 pm
by Aveave
Hello guys,
i am having exactly the same problem with the same sensor.
i have made the recommended changes from Markus (changing i2c driver timeout to 10ms):
File : esp-idf/components/driver/i2c.c

From :

Code: Select all

//set timeout of receving data 
I2C[i2c_num]->timeout.tout = 200000;
To :

Code: Select all

//set timeout of receving data 
I2C[i2c_num]->timeout.tout = 10000 / portTICK_RATE_MS;
and used his code :

Code: Select all

 
 uint8_t Byte1;
   uint8_t Byte2;
   uint8_t Byte3;

   cmd = i2c_cmd_link_create();
   i2c_master_start(cmd);
   i2c_master_write_byte(cmd, (0x40 << 1) | I2C_MASTER_WRITE, 1 /* expect ack */);
   i2c_master_write_byte(cmd, (0xF1), 1 /* expect ack */);
   i2c_master_start(cmd);
   i2c_master_write_byte(cmd, (0x40 << 1) | I2C_MASTER_READ, 1 /* expect ack */);

   i2c_master_read_byte(cmd, &Byte1, ACK_VAL);
   i2c_master_read_byte(cmd, &Byte2, ACK_VAL);
   i2c_master_read_byte(cmd, &Byte3, ACK_VAL);
   i2c_master_stop(cmd);
   i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000/portTICK_PERIOD_MS);
   i2c_cmd_link_delete(cmd);
   
But so far, i get an ESP_ERR_TIMEOUT error....

I have the feeling i'm not changing the timeout correctly, can somebody help me on that please ?

Re: Problem reading I2C sensor

Posted: Sat Jul 29, 2017 8:22 am
by Maq_aux
Hi Aveave,

do you have a logic analyzer to see whats going on?
In some cases my I2C still gets stuck on the esp32 in combination with the sensor but i hope we can get it running for you.

Regards,
Markus