Skip to content

I2C Fail 3.2.0 #11228

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
1 task done
xblack0 opened this issue Apr 7, 2025 · 61 comments
Open
1 task done

I2C Fail 3.2.0 #11228

xblack0 opened this issue Apr 7, 2025 · 61 comments
Assignees
Labels
Area: Peripherals API Relates to peripheral's APIs. Status: Needs investigation We need to do some research before taking next steps on this issue

Comments

@xblack0
Copy link

xblack0 commented Apr 7, 2025

Board

ESP32 - WROOM

Device Description

Custom ESE32 Wroom .

Hardware Configuration

GPIO 33,32, Wire library.

Version

v3.2.0

IDE Name

ARD

Operating System

Windows 11

Flash frequency

40

PSRAM enabled

yes

Upload speed

921600

Description

Compare to 3.1.3

3.2.0 Reported with 2 issues :
1-Executing i2c call time increase.
2-Deadlock [I2C hardware NACK detected] .

Sketch

Board Package from 3.1.3 To 3.2.0

Debug Message

I2C hardware NACK detected.

Dead Lock

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.
@xblack0 xblack0 added the Status: Awaiting triage Issue is waiting for triage label Apr 7, 2025
@enjoyneering
Copy link

enjoyneering commented Apr 7, 2025

I also see strange behavior on the I2c bus. Serial debug is disabled, but I get the message - i2c.master: i2c transaction timeout detected. Full log:

E (1124) i2c.master: I2C transaction timeout detected
E (1125) i2c.master: probe device timeout. Please check if xfer_timeout_ms and pull-ups are correctly set up
E (1138) i2c.master: I2C hardware NACK detected
E (1139) i2c.master: I2C transaction unexpected nack detected
E (1144) i2c.master: s_i2c_synchronous_transaction(924): I2C transaction failed
E (1151) i2c.master: i2c_master_multi_buffer_transmit(1186): I2C transaction failed
E (1161) i2c.master: I2C hardware timeout detected
E (1163) i2c.master: s_i2c_synchronous_transaction(924): I2C transaction failed
E (1170) i2c.master: i2c_master_multi_buffer_transmit(1186): I2C transaction failed
E (1180) i2c.master: I2C hardware timeout detected
E (1182) i2c.master: s_i2c_synchronous_transaction(924): I2C transaction failed
E (1189) i2c.master: i2c_master_multi_buffer_transmit(1186): I2C transaction failed
E (1203) i2c.master: I2C hardware timeout detected
E (1203) i2c.master: s_i2c_synchronous_transaction(924): I2C transaction failed
E (1208) i2c.master: i2c_master_multi_buffer_transmit(1186): I2C transaction failed
E (1217) i2c.master: I2C hardware timeout detected
E (1219) i2c.master: s_i2c_synchronous_transaction(924): I2C transaction failed
E (1226) i2c.master: i2c_master_multi_buffer_transmit(1186): I2C transaction failed
E (1236) i2c.master: I2C hardware timeout detected
E (1238) i2c.master: s_i2c_synchronous_transaction(924): I2C transaction failed
E (1245) i2c.master: i2c_master_multi_buffer_transmit(1186): I2C transaction failed

@me-no-dev
Copy link
Member

  1. The underlying ESP-IDF I2C driver has been changed
  2. The information provided here is not enough to test/confirm any issue

Pleas provide full information and minimal compilable code example

@MarksWizard
Copy link

I am also experiencing this issue. It occurred after Updating Arduino IDE to 2.3.5 from 2.3.4. The ESP IDF also updated at this time. I had never seen this error previously.

@me-no-dev espressif/esp-idf#15734

@MarksWizard
Copy link

@lucasssvaz I noticed some changes attributed to you in the most recent update, any chances that is what’s causing the issue?

test(wokwi): Add I2C Master test and enable GPIO and PSRAM tests by @lucasssvaz in #10848

test(i2c): Add test to scan bus by @lucasssvaz in #11022

test(i2c): Do not use delta as Wokwi timing can be inconsistent by @lucasssvaz in #11080

@lucasssvaz
Copy link
Collaborator

lucasssvaz commented Apr 8, 2025

@MarksWizard These PRs are related only to our I2C test in the CI. It does not affect how I2C works in any way.

@Jason2866 Jason2866 added Area: Peripherals API Relates to peripheral's APIs. Status: Needs investigation We need to do some research before taking next steps on this issue and removed Status: Awaiting triage Issue is waiting for triage labels Apr 14, 2025
@MarksWizard
Copy link

After a bunch of testing, and even more hair pulling... I think it ended up being a wiring issue for me. I finally got code to run without the error, but it would still be nice if that message didn’t spam the serial like it does.

espressif/esp-idf#15734 (comment)

@HanksSaloon
Copy link

I see the same issue, but I can confirm that it does not seem to be a wiring issue.
Board: DoIT ESP32 DEVKIT V1
Arduino IDE 2.3.6
When the sketch is compiled with ESP32 library 3.2.0 it fails, (error messages as above) but after a downgrade to ESP32 ver 3.1.3 it works. No changes made to hardware, nor the sketch, nor other libraries.

@me-no-dev
Copy link
Member

Please list devices and libraries that you use with them, so that we can try to replicate any of the confirmed non-wiring issues.

@MarksWizard
Copy link

MarksWizard commented Apr 16, 2025

@me-no-dev

If everything is wired correctly, the sketch runs fine. If you disconnect a single wire from the OLED and reboot it will trigger the issue. It’s not specifically related to the OLED though, the issue seems to occur when you initialize an I2C device that isn’t connected. Unfortunately the solution isn’t simply “check your wiring”, because this completely eliminates the ability to test code “headless” without a sensor or screen attached. Often times I test code on just an unwired board just to make sure everything is working correctly before I upload to the actual device. Previous to the ESP update, typical initialization code would just tell you the sensor wasn’t present and would maybe report something like -127 or whatever, which is perfectly fine when I’m testing something that doesn’t actually need the sensor to be present. Now it spams the serial with the error messages and the official ESP IDE I2C_oled example I tested caused the device into a boot/crash loop.

I can get it to trigger using the code below, it should trigger before printing “Wire Started” if you don’t have an I2C device connected and should run fine if you do.

#include <Arduino.h> //Library for using Arduinio IDE specific commands
#include <Adafruit_GFX.h> //https://github.com/adafruit/Adafruit-GFX-Library
#include <Adafruit_SSD1306.h> //https://github.com/adafruit/Adafruit_SSD1306
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

int timer = 0;
#define SDA 12 //variables for OLED display
#define SCL 13

void setup() {
  delay(50);

  Serial.begin(115200); //Begin serial connection

  Serial.println("Initializing display”);
  delay(1000);

  Wire.begin(SDA, SCL);
  Serial.println("Wire started”);
  delay(1000);
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed”));
  }

  display.clearDisplay();
  Serial.println("Display Ready”);
}

void loop() {

  while (timer < 10){
    display.clearDisplay();
    display.setTextColor(WHITE);
    display.setTextSize(3);
    display.setCursor(0,0);
    display.print(timer);
    display.display();
    timer = timer + 1;
    delay(1000);
  }
}

@me-no-dev
Copy link
Member

@MarksWizard so this is rather a logging issue. Your terminal gets flooded when there is no device. This I would say is oK. You should check if the device is there and not issue any more I2C transactions. That would stop the logs. I understand this is change in behavior, but that change comes from ESP-IDF's driver and not from Arduino, so we can not control it (other than blank stop it and not allow any logs, which is also not a good idea).

I am looking for a case where everything was working before and is no longer working at all with the new driver and proper wiring.

@HanksSaloon
Copy link

@me-no-dev
To add to @MarksWizard comments: I can submit an export from the logic analyzer (PulseView) showing the I2C behaviour using ESP32 ver 3.1.3 and using ESP32 ver 3.2.0 respectively, if that would help. (?)
My setup is a bit more complex, actually using both kernels separately and both I2C channels, so there might be an issue with the ESP-IDF driver timings. However, with 3.1.3 it works, with 3.2.0 it doesn't.

@me-no-dev
Copy link
Member

@HanksSaloon sure! Please also give some basic info of the setup. What devices you have connected, how do you manage communication with them and pointers to what should we look at in the traces

@MarksWizard
Copy link

MarksWizard commented Apr 16, 2025

@me-no-dev first thanks for all of your help with this, and everything you do on the other projects.. I would not be able to play with these things without all of the hard work you have contributed.

I understand that it’s not an issue with Arduino, since the ESP IDF example code causes the issue. With the new update they changed some I2C stuff and added these error messages I guess. However it’s bad code behavior as there is no rate limit, flag or anything to limit the error messages. In the ESP IDF example it causes the device to boot/crash loop, which I can’t imagine is the preferred behavior if a simple I2C device becomes disconnected.

Your suggestion to not send any I2C if not connected seems absurd? So before every screen refresh or sensor read, I need to check that the actual device is present? That would add 100’s of lines of code to my project. This issue breaks 1000’s of example code found online that doesn’t involve those checks. EDIT: actually this is not possible, since initializing the sensor is what causes the issue.. and we don’t know if it’s present before we try to initialize. I have not been able to progress my own code because I have been trying to deal with this issue.

Unfortunately I feel like in trying initially determine and explain the issue I made things confusing. Now that I know exactly where the issue lies, can you please help me properly explain this to the ESP devs?

@HanksSaloon
Copy link

@me-no-dev

Ok, here goes:

Hardware
ESP-module DOIT ESP32 DEVKIT V1 (38 pin version)
I2C channel #0 on ports D21 (SDA) and D22 (SCL)
I2C channel #1 on ports D32 (SDA) and D33 (SCL)

I/O DEVICE ; Type ; address; I2C-ch; Library
MCP23008 ; 8-ports I/O ; 0x20 ; I2C#1 ; https://github.com/RobTillaart/MCP23008
PCF8574 ; 8-ports I/O ; 0x21 ; I2C#0 ; https://skyduino.wordpress.com/2011/06/07/librairie-arduino-i2c-pour-le-pcf8574/
ADS7830 ; ADC-8 ; 0x48 ; I2C#0 ; https://github.com/adafruit/Adafruit_ADS7830
24CSM01 ; EEPROM ; 0x50 ; I2C#0 ; https://github.com/WifWaf/AT24CM01
PCF8563T ; RealTimeClock; 0x51 ; I2C#0 ; https://github.com/orbitalair/Rtc_Pcf8563
47L16 ; RAM ; 0x52 ; I2C#0 ; https://github.com/jerry-magnin/47XXX_EERAM_Arduino_Library
ACS37800 ; Power Monitor; 0x65 ; I2C#0 ; https://github.com/sparkfun/SparkFun_ACS37800_Power_Monitor_Arduino_Library

All libraries have been slightly modified, but only to the extent of adding or removing some interface routines.

Physically, all circuits are on the same 100x100mm PCB, except for the ACS37800 which is located about 8 meters away.
Therefore, on I2C#0 there's a bus buffer P82B96 to extend the bus (https://www.nxp.com/docs/en/data-sheet/P82B96.pdf).
All pull-up resistors are 1k8 ohm, external pull ups on the extended bus are 1k1 ohm (relates to the remote cable type and length).

Standard #includes are
stdlib.h
Wire.h
Arduino.h

To explain the analyzer outputs:
The sketch is divided into two processes, let's call them "S" and "R", S being setup first in the first core. It then cranks up the other process in the second core.
I2C channel #0 is dedicated to the S-process, channel #1 to the R-process.
I2C-channels are initiated by a call to Wire.begin() and Wire1.begin(), respectively. (I have not tried TwoWire, as it seemed to require many more changes to the device libraries).
Both I2C channels run in fast mode (400k), although the problem occurs also @100k.

The RTC-module sends a 1Hz interrupt signal to pin D25. The interrupt handling routine couldn't be simpler, it just increases the value of a semaphore. Takes minimum of time. The semaphore is then processed elsewhere in the S process.

Both processes poll their I2C channel regularly, process S once every second, process R according to it's own internal logic.
This can be seen in the analyzer outputs attached.

Finally, the samples:
A_ESP32-3_1_3(.sr) everything works okay
A_ESP32-3_2_0(.sr) does not work.
(In these samples bus speeds are 400k, sampling rate is 1 Msps.)

At first, the two outputs seem very similar and there is no clear explanation to what the problem is in 3.2.0.
The only major difference can be noted at the end of each command, when the controller should send a Stop, i.e. release the bus.

In 3.2.0 SCL is released much later. Compare these examples:
In 3_1_3: timeline +1715776 -> +1715778 us (SCL is released appx 2 us from end of data)
In 3_2_0: timeline +2646044 -> +2646060 us (SCL release is appx 16 us)

I haven't had time to check the standard if there's a time limit when the SCL must be released after the data is sent, but as a delayed SCL release also delays the ACK/NACK response from the slave it seems that the ESP (ver 3.2.0) doesn't understand where the response comes from and therefore logs an error condition.

A_ESP32-3_.zip

@MarksWizard
Copy link

@HanksSaloon awesome work, thanks for helping to get this resolved. Can you post all of the above info in the issue opened on the ESP GitHub? Mythbuster5 has been asking for the logic analyzer stuff which I can’t provide.

espressif/esp-idf#15734 (comment)

@mythbuster5
Copy link

mythbuster5 commented Apr 17, 2025

@HanksSaloon How to open the DMS file in your zip. Or it's not dma, because I download from mac. So the question is how to open that file? Or what's the correct extention name?

@mythbuster5
Copy link

mythbuster5 commented Apr 17, 2025

Or just provide key picture is ok I think. Do you mean this part is suspicious?

Image

@HanksSaloon
Copy link

The .Zip contains two files, <A_ESP32-3_1_3.sr> and <A_ESP32-3_2_0.sr>. They can be opened in PulseView / Sigrok.
Here are two screenshots of the difference I mention earlier.

Image

Image

@HanksSaloon
Copy link

Here are two more screenshots, of I2C channel 2. Highlight the difference.

Image

Image

@mythbuster5
Copy link

Got it.

@mythbuster5
Copy link

0001-fix-i2c-optimization-performance-on-esp32.txt

@HanksSaloon I have generated patch for shorten the time between last byte and stop. If your every transaction data is smaller than 63 byte (include address byte), you can try this. However, data in one transaction is larger than 63 bytes still have some problem, I still need time for debugging. Thank you.

@me-no-dev PTAL, and please help to share a method how to patch idf code in ardiuno environment if needed. Thanks.

@HanksSaloon
Copy link

@mythbuster5 @me-no-dev
Ok, great. I could give the patch a try, if someone can tell how to implement it a patch. (I'm on Linux.)
Currently the longest transaction is net 48 bytes payload, I think. Stays well below that 63 byte limit.

@MarksWizard
Copy link

@mythbuster5 here is how the issue is manifesting for me in Arduino IDE

IMG_6624.mov

@me-no-dev
Copy link
Member

@enjoyneering @HanksSaloon patched libs can be downloaded from here: https://github.com/espressif/esp32-arduino-lib-builder/actions/runs/14531871574/artifacts/2968983657

You need to replace the ones in [sketches_folder]/hardware/espressif/esp32/tools with the extracted contents

@HanksSaloon
Copy link

@me-no-dev Sorry, but you need to explain a little more where the patches should go.
Using Arduino IDE i have all sketches in one folder called Arduino. Of course every sketch in it's own folder.
Do you mean create that path (as described) from that "Arduino"-folder?
You say "replace", but there is nothing to replace. That path doesn't exist from before.

@me-no-dev
Copy link
Member

@HanksSaloon please see this: espressif/esp-idf#15734 (comment)

@me-no-dev
Copy link
Member

@HanksSaloon also good idea to uninstall from BoardManager, so that you do not mistake which core you are compiling with

@MarksWizard
Copy link

MarksWizard commented Apr 18, 2025

@me-no-dev @mythbuster5

I am sorry.. but I feel like I am screaming into the void at this point. To me, it seems like both of you are failing to acknowledge that the error message spamming the serial on every I2C read/write is bad behavior and not at all how things were previously. Checking the I2C before every action would add 100’s of useless lines, that aren’t included in any example online.

Numerous users have reported even with serial debugging turned off, these messages still come though. Currently there is no way to turn them off. Again that’s not proper behavior, and if you’re going to force it on us at least rate limit it.

In my “production” code I have 2 I2C sensors and a screen. In ESP 5.4, when I upload this code to a bare dev board, the serial is completely unreadable because of the wall of error messages. Again this should not be the case, I have done everything I can possibly think of to explain and illustrate the issue and how I am affected by it. In the videos below, you can see that under ESP 5.3 the code runs fine, even though sensors are not present. The software actually picks up that the sensors are not present and report this in the output. On ESP 5.4 it causes a boot/crash loop for me. This will be my final comment on the issue, I’ll stay on ESP 5.3 and hope that it eventually gets resolved.

Arduino 2.3.4 w/ [v3.1.3 based on ESP-IDF v5.3]

IMG_6630.mov

Arduino 2.3.5 w/ [v3.2.0 based on ESP-IDF v5.4]

IMG_6633.mov

@me-no-dev
Copy link
Member

@MarksWizard here is what is happening:
You are trying to talk to device that you have disconnected, therefore you get an error that the device did not respond.
You refuse to check if the device is there at all and to take proper action (not talk to it), instead you treat it like it's there and continue to send data to it. Checking if the device is there is not hundreds of lines, it's two. This is considered bad coding approach and the fact that old code did not print an error, does not make it good even before.
Now the new ESP-IDF driver prints error messages when an error occurs. The one before did not. We can not stop the error messages just for the I2C driver. We can either have them on or off for everything (I remember there being a way before and I will try to see if it can be still used).

You are annoyed that you are doing something wrong and that the logs are telling you that. How is that a bad behavior of the driver? Wouldn't it be better to write proper code and not waste resources of the chip talking to device that you have yourself disconnected? If you are doing what you are supposed to: have the device connected and/or check if it's connected before trying to access it, then you will not be getting errors, unless something else goes wrong, at which point you will like having the logs tell you that and not just have a broken device.

@MarksWizard
Copy link

MarksWizard commented Apr 18, 2025

@me-no-dev

None of the examples online have this error check before every I2C read/write. Please post a very basic example of what that would look like.

I use the below code to initializes the SHT31 temp/humidity sensor. I do keep track of whether the sensor is connected or not, but this is only checked at initialization. This does not catch cases where the sensor becomes disconnected or misreads somehow. I would have to add a check to the SHT31_FLAG before every read from the sensor?

 Serial.print("SHT30 test: ");  //Configure Temp/Humidity monitor
  if (!sht31.begin(0x44)) {      // Set to 0x45 for alternate i2c addr
    Serial.println("No SHT31 temp sensor”);
    errorMSG = "Error: No SHT30 temp sensor”;
    LogError(errorMSG);
    SHT31_Flag = false;
    display.drawString(6, 32, "Air T/H: Fail”);
    display.display();
    delay(2000);
  } else {
    SHT31_Flag = true;  //turn flag to true, indicating no error
    Serial.println("Air T/H: Good”);
    display.drawString(6, 32, "Air T/H: Good”);
    display.display();
    delay(200);
  }

@me-no-dev
Copy link
Member

@MarksWizard that should be done in the library that you are using to talk to the device, not your user code. But here is a sample anyway:

#include <Arduino.h> //Library for using Arduinio IDE specific commands
#include <Adafruit_GFX.h> //https://github.com/adafruit/Adafruit-GFX-Library
#include <Adafruit_SSD1306.h> //https://github.com/adafruit/Adafruit_SSD1306
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

int timer = 0;
#define SDA 12 //variables for OLED display
#define SCL 13

bool displayConnected = false;

bool isDeviceConnected(uint8_t address) {
  Wire.beginTransmission(address);
  return Wire.endTransmission() == 0;
}

void setup() {
  delay(50);

  Serial.begin(115200); //Begin serial connection

  Serial.println("Initializing display”);
  delay(1000);

  Wire.begin(SDA, SCL);
  Serial.println("Wire started”);
  delay(1000);
  displayConnected = isDeviceConnected(0x3c);
  if(!displayConnected){
    Serial.println(F("SSD1306 not connected”));
    return;
  }
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed”));
  }

  display.clearDisplay();
  Serial.println("Display Ready”);
}

void loop() {

  while (displayConnected && timer < 10){
    display.clearDisplay();
    display.setTextColor(WHITE);
    display.setTextSize(3);
    display.setCursor(0,0);
    display.print(timer);
    display.display();
    timer = timer + 1;
    delay(1000);
  }
}

@MarksWizard
Copy link

MarksWizard commented Apr 18, 2025

@me-no-dev yeah in your example you are doing a check before printing to the screen. This means anytime I output anything to the screen, or read a sensor I need to do the check, which equals 100’s of lines for me. Your suggestion means that every library for the I2C devices is currently “broke”.

@me-no-dev
Copy link
Member

I'm not sure where you see that, but OK. Also getting a log that something is wrong is not equal to "broken". I offered you two approaches: check if the device is connected or just make sure that you have it connected in reality. You refuse both... you want to not connect the screen and to be able to write to it and not get an error message. This is not OK.

@me-no-dev
Copy link
Member

@enjoyneering @HanksSaloon looking forward to your results

@HanksSaloon
Copy link

@me-no-dev
Installation done according to the instructions and also uninstalled from BoardManager, but now Arduino IDE says no support for ESP32. Seems that it doesn't find the the installed packages (the new .../hardware/... path).
FYI: I'm running Arduino IDE from an AppImage. I also started up an ancient IDE version, 1.8.19 (which I still have installed for support purposes to some old projects). That IDE finds the path, but cannot compile the sketch, as it lacks a lot of other features and support.

Does espressif support require that the IDE is natively installed, i.e not running from an image?

@davidcliddell
Copy link

I think I have the same problem. I am using a feather ESP32S3 and a BNO085 via i2c. On esp32 core 3.1.3 everything worked fine. I updated to 3.2.0 and the BNO085 begin method returned i2c not found. I then ran a simple i2c scanner (WireScan in the examples) and it returned an error 5 (timeout) on the address of the BNO085. I then installed 3.1.3 and everything worked fine. So it looks like 3.2.0 has broken the i2c for BNO085, other i2c devices seem to work fine Here is the code from WireScan
#include "Wire.h"

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

loop() {
byte error, address;
int nDevices = 0;

delay(5000);

Serial.println("Scanning for I2C devices ...");
for (address = 0x01; address < 0x7f; address++) {
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0) {
Serial.printf("I2C device found at address 0x%02X\n", address);
nDevices++;
} else if (error != 2) {
Serial.printf("Error %d at address 0x%02X\n", error, address);
}
}
if (nDevices == 0) {
Serial.println("No I2C devices found");
}
}

@MarksWizard
Copy link

@me-no-dev I apologize for being reactionary, I recognize how much you do and you don’t deserve that.

In your example, you use displayConnected = isDeviceConnected(0x3c); as the flag to catch if the display is connected. That means before every display.display() or sensor.read() in my code I have to add if displayConnected{}, which happens 100’s of times. I agree having this handled in the library is the easiest, and I can do that for the libraries that I am using locally. But I am using all publicly available libraries, which I do not maintain and therefore doesn’t help the next person.

I know that the error messages are useful, but again this was not the behavior before the update, and breaks all current examples / libraries. So the real solution is that something in the way that error is handled/output should be changed. I know this issue doesn’t fall on Arduino, or is even possible to “patch” on your side. However, multiple users are reporting this. My frustration is that I feel like I am the only one actually trying to resolve it.

Running the OLED screen example I posted above on an Arduino Mega does not cause any such error messages either, which as a user is the currently expected “normal”.

@me-no-dev
Copy link
Member

@HanksSaloon I suspect you did not install in the correct location, forgot to run get.exe/get.py and then overwrite the libs that were installed with the ones in the link above.

Custom cores are installed in your Arduino sketches folder: Documents/Arduino for Max/Win and ~/Arduino for Linux. In that sketches folder you also install all libraries in it's libraries subfolder. Cores are installed in hardware/[vendor]/[core_name], which for esp32 and Mac/Win would expand to Documents/Arduino/hardware/espressif/esp32 if you have followed the instructions, then you would go into Documents/Arduino/hardware/espressif/esp32/tools and either run get.exe or get.py to download all necessary toolchains, tools and libsAfter that is all done you would download the patched libs above and replace the ones that get.exe/get.py installed inDocuments/Arduino/hardware/espressif/esp32/tools. Then you can restart the IDE and you should be able to see the boards in the menu under ESP32 Arduino (in Sketchbook)`

@me-no-dev
Copy link
Member

me-no-dev commented Apr 18, 2025

@davidcliddell you can try to install the custom core with the patched libs and see if that will help.
References: espressif/esp-idf#15734 (comment) and my message above to @HanksSaloon
Patched libs: https://github.com/espressif/esp32-arduino-lib-builder/actions/runs/14531871574/artifacts/2968983657

@me-no-dev
Copy link
Member

@MarksWizard if your display is properly connected, it will work and errors will not be displayed. That means that there is no bug in either the library or the I2C driver. Most libraries out there assume that you have a working screen connected properly to the board and that is working just fine. Yes, AVR core does not print logs or anythng, mostly because it can not afford the memory penalty to do so, but ESP32 chips have plenty of that and can actually tell you when something is wrong. For very custom cases like yours, we offer Arduino as IDF component (where you can turn off error logs in IDF) and also a way to compile your custom IDF libs with logs off. We can not blankly turn all errors off, because then we would not know when something goes wrong. It is obvious that writing to device that is not connected at all is not a valid case. Why write code for it if you are not going to connect to it anyway?

@me-no-dev
Copy link
Member

@mythbuster5 will your patch fix this issue: #11228 (comment)

@MarksWizard
Copy link

MarksWizard commented Apr 18, 2025

@me-no-dev thank you for taking the time to respond again. The issue occurs for me because my the device I’m writing code to is to simulate tidal changes in a grow bin for a research experiment. The device has 2 motors, 2 flow sensors, air temp/humidity, water temp, time of flight sensor and a screen. I also use your web server code to change parameters and such. These are all connected and working great, so I do deeply appreciate what you do because none of it would be possible without it. However, if I want to test some small piece of code on a “headless” board at home or my desk, I currently can’t under ESP-IDF 5.4. If one of the I2C devices becomes disconnected, the board will freak out. I don’t always care if I can’t read temp or see the screen, previously my code handled these scenarios just fine. This is why I am being stubborn, but I will keep my word to roll back to 5.3 and hope for the best. Thanks again, have a great weekend.

@me-no-dev
Copy link
Member

@MarksWizard here is my last option for you. Same number of lines, but you address the display as oled instead

#include "Wire.h"
#include <Adafruit_GFX.h> //https://github.com/adafruit/Adafruit-GFX-Library
#include <Adafruit_SSD1306.h> //https://github.com/adafruit/Adafruit_SSD1306
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

int timer = 0;
#define SDA 12 //variables for OLED display
#define SCL 13

bool displayConnected = false;
bool isDeviceConnected(uint8_t address) {
  Wire.beginTransmission(address);
  return Wire.endTransmission() == 0;
}

#define oled if(displayConnected) display

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

  displayConnected = isDeviceConnected(0x3c);
  if(!displayConnected){
    Serial.println(F("SSD1306 not connected"));
    return;
  }
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
  }

  oled.clearDisplay();
  Serial.println("Display Ready");
}

void loop(){
  while (timer < 10){
    oled.clearDisplay();
    oled.setTextColor(WHITE);
    oled.setTextSize(3);
    oled.setCursor(0,0);
    oled.print(timer);
    oled.display();
    timer = timer + 1;
    delay(1000);
  }
}

@MarksWizard
Copy link

@me-no-dev thank you. Is there a way for me to tip you or buy you lunch?

@MarksWizard
Copy link

MarksWizard commented Apr 18, 2025

@me-no-dev I uploaded your example code, and the issue persists. The only thing that you were missing in your code is Wire.begin(SDA,SCL);, which I included after Serial.begin(115200);

Edit: Nevermind, I realize that everything works properly on reboot, since It’s the initialization where we set the flag. This solution works for me, and I will work on making the appropriate changes in my code. It will be better for it in the end, so thank you again for all of your help. Please let me know if I can send a tip.

IMG_6643.mov

@HanksSaloon
Copy link

@me-no-dev
I really think I've done everything according to the instructions. BTW: I'm on OpenSUSE.

I ran the installation (a lot of stuff installed), all the way including the last "python3 get.py. (That script installed even more).
After that I replaced the folders as you instructed. However, you gave the path [sketches_folder]/hardware/espressif/esp32/tools, but in fact folders/files with the same names can be found one more step further, i.e. in a folder named "esp32-arduino-libs".
Which one is correct?

Anyway, I've tried both options.
First I replaced the folders & files in <[sketches_folder]/hardware/espressif/esp32/tools/esp32-arduino-libs/> with the ones downloaded earlier, that should include the patch.
Arduino IDE 2.3.6 do not find them.
Then I tried exactly as you said, i.e. copied the folders/files including the patch into path <[sketches_folder]/hardware/espressif/esp32/tools/>.
Still not found by Arduino IDE 2.3.6.

In both cases Arduino IDE starts with the following two messages. First one is an error msg, second is a suggestion to install the required board drivers:

  1. "Unknown FQBN: platform esp32:esp32 is not installed. Could not connect to /dev/tty/USB0 serial port.
  2. The " esp32[v 3.2.0]" core has to be installed for the currently selected "DOIT ESP32 DEVKIT V1" board. Do you want to install it now?
    And, as I said, the old Arduino IDE 1.8.19 does recognize the path, but compiling the sketch ends up in an error due to other incompabilities.

@HanksSaloon
Copy link

@me-no-dev
So I tried again, but reinstalled the ESP32 board package version 3.2.0
The issue has gone away. Both I2C channels work, no error messages.
I also took a new trace with the analyzer. The time between end of Data and the control releasing the SCL and slave to send an ACK has not changed, it is still in the range of 16 us (!)
This doesn't really make sense to me at all!
From my point of view, the only thing that has changed is that I installed a lot of new stuff in ~/Arduino/hardware/espressif/..., but as I said in my previous post, I'm not at all sure that the IDE even tries to use anything in that path.
However, something HAS changed, but I am VERY confused.

@HanksSaloon
Copy link

@me-no-dev @mythbuster5
Some progress here.
As I told before, for some reason Arduino IDE couldn't find the new espressif stuff installed into

[sketches_folder]/hardware/espressif/esp32/tools/...

I had to clean out (i.e renamed) all previous Arduino IDE settings from the hidden files and folders, by renaming them in order to hide them from Arduino IDE:
~/.arduino15/...
~/.arduinoIDE/...
~/.config/Arduino IDE/...
~/.config/arduino-ide/...
I then installed the "bare" Arduino IDE 2.3.6, not the flatpack.
All four hidden folders mentioned above were re-created, NOW the IDE is using the configuration files in that ../hardware/... folders.

So now, a clean start with the patch.
Compiler exits with the following error message:

~/Arduino/hardware/espressif/esp32/cores/esp32/esp32-hal-uart.c: In function '_uartDetachPins':
~/Arduino/hardware/espressif/esp32/cores/esp32/esp32-hal-uart.c:225:5: error: implicit declaration of function 'gpio_hal_iomux_func_sel'; did you mean 'gpio_hal_func_sel'? [-Wimplicit-function-declaration]
225 | gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[rxPin], PIN_FUNC_GPIO);
| ^~~~~~~~~~~~~~~~~~~~~~~
| gpio_hal_func_sel
exit status 1

Compilation error: exit status 1

@me-no-dev
Copy link
Member

@HanksSaloon when you cloned the Arduino repository in the hardware folder, did you make sure that you are using the idf-master branch?

@HanksSaloon
Copy link

I cannot answer that directly, as I did exactly according your instructions, except for two steps.

I am on OpenSUSE, so I did according to the instructions you pointed me to:
https://docs.espressif.com/projects/arduino-esp32/en/latest/installing.html#linux

However, at that point Arduino IDE 2.3.6 was already installed (AppImage) and I (user) already member of the dialout group.

So I went directly to: sudo zypper install git python3-pip python3-pyserial.
But I already had git installed, so it exited with "Nothing to do".

Continued with these commands:
mkdir -p ~/Arduino/hardware/espressif
cd ~/Arduino/hardware/espressif
git clone https://github.com/espressif/arduino-esp32.git esp32
cd esp32/tools
(all went well, no warnings, nor errors reported. A lot of stuff was installed into the hardware folder.)

Finally:
python3 get.py
(now even more stuff was installed, again without warnings/errors).

The last step, and this is where I did differently from your instructions: I replaced the files and folders in ~/Arduino/hardware/espressif/esp32/tools/esp32-arduino-libs with the ones that I had downloaded earlier from https://github.com/espressif/esp32-arduino-lib-builder/actions/runs/14531871574/artifacts/2968983657
As I described yesterday, I was a bit confused since I didn't find anything to "replace" in the folder you had given (i.e. the .../tools/...) but one more step down, in the .../tools/esp32-arduino-libs/... -folder I found files and folders with the same names as thos in the packet with patches.
So I have now replaced them with the patches.
After that Arduino IDE did not seem to recognize the hardware folder, nor the path below it.

And, as I explained earlier today, I decided to try one more thing and that was a fresh install of Arduino IDE, (not the Appimage).
When I the started up the IDE I did not install any ESP-support packages in BoardManager, but the board was immediately recognized anyway, so I thought now it looks better. However, trying to compile the sketch stops with the error message I reported, but from the error message you see, that now the hardware path is recognized.

Looking at the scripts the stuff has been cloned from the branch in https://github.com/espressif/arduino-esp32.
You tell me if this is the correct branch or not?
It is exactly according to the instructions, though.

@me-no-dev
Copy link
Member

me-no-dev commented Apr 19, 2025

You cloned the master branch. Proper command should have been git clone https://github.com/espressif/arduino-esp32.git -b idf-master esp32 Since you have already cloned it, you can go into the folder and git checkout idf-master then cd tools && python3 get.py after which you can again replace the esp32-arduino-libs with the ones that are patched. That should get you going. In the IDE the core in the boards menu does not show as esp32 but as ESP32 Arduino (in sketchbook) from which you should select the board that you want to compile for

@me-no-dev
Copy link
Member

@HanksSaloon there is another change that we need to make for UART to compile with current IDF master. Will make the change and let you know that is clear to update the repository and try to compile. The error we are currently getting is https://github.com/espressif/arduino-esp32/actions/runs/14535332246/job/40782515042#step:6:123

@HanksSaloon
Copy link

@me-no-dev Allright! I'll wait for the update. And thanks! I really appreciate your effort.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: Peripherals API Relates to peripheral's APIs. Status: Needs investigation We need to do some research before taking next steps on this issue
Projects
None yet
Development

No branches or pull requests

9 participants