(solved) I2C device poses a challenge

fivdiAtESP32
Posts: 39
Joined: Thu Dec 20, 2018 9:47 am

Re: I2C device poses a challenge

Postby fivdiAtESP32 » Sun Jan 06, 2019 5:22 pm

Hmm..., what's the value of I2C_WAITTIME_TICKS?

User avatar
mzimmers
Posts: 278
Joined: Wed Mar 07, 2018 11:54 pm
Location: USA

Re: I2C device poses a challenge

Postby mzimmers » Sun Jan 06, 2019 5:24 pm

Currently it's 500. I've tried all sorts of values (beginning with 5); no change in results.

Evidently someone else had this problem about a year ago:

viewtopic.php?t=1226

Still trying to make sense of it.

ADDED: I just put a call to i2c_get_timeout in my read -- came back as 640. As the units are APB 80Mhz clock cycle, that sounds like 8us. Doesn't seem like enough for this device, does it?

User avatar
mzimmers
Posts: 278
Joined: Wed Mar 07, 2018 11:54 pm
Location: USA

Re: I2C device poses a challenge

Postby mzimmers » Mon Jan 07, 2019 8:57 pm

I'm getting closer (I think)...here's my code:

Code: Select all

    m_i2c_cmd = i2c_cmd_link_create();
    ESP_ERROR_CHECK(i2c_master_start(m_i2c_cmd));
    ESP_ERROR_CHECK(i2c_master_write_byte(m_i2c_cmd, SHT20_ADDR_WRITE, true));
    ESP_ERROR_CHECK(i2c_master_write_byte(m_i2c_cmd, cmd, true));
    ESP_ERROR_CHECK(i2c_master_stop(m_i2c_cmd));
    rc = (i2c_master_cmd_begin(I2C_PORT_NBR, m_i2c_cmd, I2C_WAITTIME_TICKS));
    i2c_cmd_link_delete(m_i2c_cmd);
    if (rc == ESP_OK)
    {
        ESP_LOGI(TAG, "thermRead(): command write successful.");
    }
    else
    {
        ESP_LOGE(TAG, "thermRead(): command write error \"%s\".", esp_err_to_name(rc));
    }

    // write the read address.
    do
    {
        m_i2c_cmd = i2c_cmd_link_create();
        ESP_ERROR_CHECK(i2c_master_start(m_i2c_cmd));
        ESP_ERROR_CHECK(i2c_master_write_byte(m_i2c_cmd, SHT20_ADDR_READ, true));
        ESP_ERROR_CHECK(i2c_master_read(m_i2c_cmd, data, 3, I2C_MASTER_ACK));
        rc = (i2c_master_cmd_begin(I2C_PORT_NBR, m_i2c_cmd, I2C_WAITTIME_TICKS));
        i2c_cmd_link_delete(m_i2c_cmd);
        if (rc == ESP_OK)
        {
            ESP_LOGI(TAG, "thermRead(): send of read address successful.");
            break;
        }
        else if (rc == ESP_FAIL)
        {
            ESP_LOGE(TAG, "thermRead(): read error; SHT20 didn't send an ACK");
            m_i2c_cmd = i2c_cmd_link_create();
            ESP_ERROR_CHECK(i2c_master_stop(m_i2c_cmd));
            ESP_ERROR_CHECK(i2c_master_cmd_begin(I2C_PORT_NBR, m_i2c_cmd, I2C_WAITTIME_TICKS));
            i2c_cmd_link_delete(m_i2c_cmd);
        }
        else
        {
            ESP_LOGE(TAG, "thermRead(): send of read address error \"%s\".", esp_err_to_name(rc));
        }
    }
    while (i++ < 10);
And I get timeouts. Any suggestions? Thanks.
i2c.PNG
i2c.PNG (95.34 KiB) Viewed 387 times

WiFive
Posts: 2163
Joined: Tue Dec 01, 2015 7:35 am

Re: I2C device poses a challenge

Postby WiFive » Mon Jan 07, 2019 10:25 pm

You are still using E3 instead of F3. A conversion can take up to 85ms, would your loop cover that amount of time?

User avatar
mzimmers
Posts: 278
Joined: Wed Mar 07, 2018 11:54 pm
Location: USA

Re: I2C device poses a challenge

Postby mzimmers » Mon Jan 07, 2019 10:50 pm

Noted about F3. Thanks for that catch; I hadn't noticed that, and was wondering about how to choose a mode.

I set my timeout value to 6400 (units of 80MHz clock). I thought that would be enough for a single loop iteration, but maybe I dropped a digit in my mental calculation.

Because...
I (205) Thermometer: i2cInit(): i2c_param_config() completed successfully.
I (205) Thermometer: i2cInit(): i2c_driver_install() completed successfully.
I (455) Thermometer: thermReset(): successful
I (465) Thermometer: thermRead(): timeout value is 6400.
I (465) Thermometer: thermRead(): command write successful.
E (465) Thermometer: thermRead(): read error; SHT20 didn't send an ACK
E (465) Thermometer: thermRead(): read error; SHT20 didn't send an ACK
E (475) Thermometer: thermRead(): read error; SHT20 didn't send an ACK
E (485) Thermometer: thermRead(): read error; SHT20 didn't send an ACK
E (495) Thermometer: thermRead(): read error; SHT20 didn't send an ACK
E (495) Thermometer: thermRead(): read error; SHT20 didn't send an ACK
E (505) Thermometer: thermRead(): read error; SHT20 didn't send an ACK
E (515) Thermometer: thermRead(): read error; SHT20 didn't send an ACK
E (515) Thermometer: thermRead(): read error; SHT20 didn't send an ACK
I (525) Thermometer: thermRead(): send of read address successful.
I (535) Thermometer: the temperature is 19.C.
Works on the last iteration.

Strangely, it works on the last iteration for a variety of timeout settings: 6400, 10000, 20000. Any idea why this might be?

19C seems a little off, too. I'm going to put the sensor over a cup of coffee and re-test.

WiFive
Posts: 2163
Joined: Tue Dec 01, 2015 7:35 am

Re: I2C device poses a challenge

Postby WiFive » Tue Jan 08, 2019 1:42 am

20000 = 250 microseconds, max timeout would be 0xFFFFF = 13ms. However in no hold mode the device should be just nacking so you shouldn't be depending on that for your loop delay, use an actual delay.

User avatar
mzimmers
Posts: 278
Joined: Wed Mar 07, 2018 11:54 pm
Location: USA

Re: I2C device poses a challenge

Postby mzimmers » Tue Jan 08, 2019 10:23 pm

Do you mean something like a call to vTaskDelay() between loop iterations?

WiFive
Posts: 2163
Joined: Tue Dec 01, 2015 7:35 am

Re: I2C device poses a challenge

Postby WiFive » Wed Jan 09, 2019 3:38 am

Yes

Who is online

Users browsing this forum: No registered users and 31 guests