Skip to content

I2C Master Wire.requestFrom timeout not obeyed, takes a whole second to read when slave is not present #5934

Closed
@leifclaesson

Description

@leifclaesson
Contributor

What you are trying to do?
I'm trying to read from an I2C device which is not always present.
With ESP32 Arduino 1.0.6, the read fails instantly as it should. With 2.0.1 it blocks for a full second (1000ms) every time.

This sketch will duplicate the error, no hardware required.

#include <Wire.h>

void setup()
{
	Serial.begin(115200);

	Wire.begin();
}

void loop()
{

	uint32_t time_before=millis();

	const int address=10;
	const int length=16;

	int rcvd = Wire.requestFrom(address, (uint8_t) length, (uint8_t) true);
	if(rcvd==length)
	{
		uint8_t data[length];
		Wire.readBytes(data, length);
	}

	Serial.printf("I2C: Received %u bytes in %u ms\n",rcvd,millis()-time_before);

	delay(250);
}

If run on a regular ESP32 board with Arduino Core version 1.0.6, each Wire.requestFrom completes instantly or within 1 millisecond. With 2.0.1 it takes 1001 milliseconds.

I discovered the issue when recompiling a large project with the new Arduino core, so I stripped it down until I found the issue, but I don't know what's causing it.

I followed the code into esp32-hal-i2c.c and attempted to change the last parameter of i2c_master_cmd_begin to a hardcoded 1, and it still took a full second to complete the failed read -- the parameter change made no difference at all, so it seems perhaps the issue is all the way down inside the IDF?

Hardware:

Board: Generic 38-pin ESP32 dev board
Core Installation version: 2.0.1 (and for reference 1.0.6)
IDE name: Sloeber 4.4.0
Flash Frequency: 40Mhz
PSRAM enabled: no
Upload Speed: 921600
Computer OS: Windows 10

Debug Messages:

I tried, there are no I2C related debug messages even on Verbose.

Activity

self-assigned this
on Nov 27, 2021
leifclaesson

leifclaesson commented on Nov 28, 2021

@leifclaesson
ContributorAuthor

Thanks @me-no-dev

CarlosGS

CarlosGS commented on Dec 2, 2021

@CarlosGS

Looks related to espressif/esp-idf#4999

leifclaesson

leifclaesson commented on Dec 8, 2021

@leifclaesson
ContributorAuthor

Looks related to espressif/esp-idf#4999

Now that you mention it yes, it does look similar.. but that thread is from April 2020 which is over a year ago. This was not a problem in 1.0.6 (as far as I could tell?) which is from March 2021 which is only 7 months ago at the time of this writing?

CarlosGS

CarlosGS commented on Dec 8, 2021

@CarlosGS

Sorry I hadn't seen the dates. But since 1.0.6 is based on IDF v3.3.5 and that thread is about IDF v4.2, maybe the bug was introduced in between those IDF versions?

leifclaesson

leifclaesson commented on Dec 9, 2021

@leifclaesson
ContributorAuthor

Sorry I hadn't seen the dates. But since 1.0.6 is based on IDF v3.3.5 and that thread is about IDF v4.2, maybe the bug was introduced in between those IDF versions?

Definitely possible. :)

leifclaesson

leifclaesson commented on Dec 18, 2021

@leifclaesson
ContributorAuthor

Did you get a change to test it yet? The example code above requires no additional hardware to reproduce the issue.

pgrawehr

pgrawehr commented on Dec 25, 2021

@pgrawehr
Contributor

I can definitelly confirm the bug. When there's no device listening on the given address, Wire.requestFrom takes at least 1 second before it returns.

simondddd

simondddd commented on Feb 16, 2022

@simondddd

Is there a simple workaround for this?
I have tried to recompile the libraries using https://github.com/espressif/esp32-arduino-lib-builder modifying the driver i2c.c as seen in espressif/esp-idf#4999 but I get errors when I use the libraries I obtain.

45 remaining items

gian-didom

gian-didom commented on Oct 3, 2024

@gian-didom

I am experiencing the same problem and can confirm that the latest version of the SDK does not fix the issue. I still have a 1000ms minimum timeout despite setting it to 50 ms.

modified the milestones: 3.0.5, 3.1.0 on Oct 21, 2024
VojtechBartoska

VojtechBartoska commented on Oct 21, 2024

@VojtechBartoska
Contributor

@lucasssvaz Do you know if there have been any updates regarding this?

lucasssvaz

lucasssvaz commented on Oct 28, 2024

@lucasssvaz
Collaborator

This might be due to I2C_CMD_ALIVE_INTERVAL_TICK being to high: https://github.com/espressif/esp-idf/blob/release/v5.3/components/driver/i2c/i2c.c#L84

I have not tested but using Arduino as a component and lowering this value might result in a shorter timeout.

modified the milestones: 3.1.0, 3.1.1 on Jan 6, 2025
modified the milestones: 3.1.1, 3.2.0 on Jan 14, 2025
modified the milestones: 3.2.0, 3.3.0 on Mar 12, 2025
Jason2866

Jason2866 commented on Mar 12, 2025

@Jason2866
Collaborator

closing since outdated. Please open a new issue if the issue still exists with actual Arduino core

leifclaesson

leifclaesson commented on May 6, 2025

@leifclaesson
ContributorAuthor

Can confirm greatly improved in 3.1.3, however there is still a 50ms delay which did not happen in 1.0.6, but at least it's not 1000ms.

3.2.0 however has a new issue where tons of I2C error messages are printed to Serial, even though Core Debug Level is set to None. I'll open a new issue.

The Quick Fix suggested by @shalomberm above does solve the problem by detecting whether a device is present without throwing errors or causing delays, so I will implement this solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Area: ESP-IDF relatedESP-IDF related issuesArea: Peripherals APIRelates to peripheral's APIs.Status: Blocked by ESP-IDFThis issue/PR is currently blocked due to limitations, bugs, or pending changes in ESP-IDF.Status: Needs investigationWe need to do some research before taking next steps on this issue

Type

No type

Projects

Status

Done

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @leifclaesson@CarlosGS@theotherjenkutler@me-no-dev@pgrawehr

      Issue actions

        I2C Master Wire.requestFrom timeout not obeyed, takes a whole second to read when slave is not present · Issue #5934 · espressif/arduino-esp32