-
Notifications
You must be signed in to change notification settings - Fork 7.6k
I2C not working on ESP32 #741
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
Comments
@muktillc , in issue #90 I commented a possible solution. My system:5v segment0x20,0x21 (MCP23008) I/O expanders connected to 4x4 matrix and 20x4 LCD 3.3v segment0x51,0x55,0x56 24LC512 Scanner Code
Debug Output
Chuck. |
hello @muktillc |
I thought the designated ports are pins 21 and 22. Are they 22 and 23??
…On Oct 18, 2017 6:58 AM, "EBZ-Krisemendt" ***@***.***> wrote:
hello @muktillc <https://github.com/muktillc>
any particullar reason your not using designated wire ports (22/23) or is
it just a typo in your code?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#741 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/Aetc8NKnzoqcb76-H5OEGBDso5P7oPmrks5stdnSgaJpZM4P854w>
.
|
shame on me, it's 22/23 on adafruit huzzah32. it's indeed 21/22 on official dev-board, sorry |
one quick question regarding the SPI. I am trying to get the SPI work and my
sensor is responding but for some reason the MISO pin (pin #19) is not
accepting
any input. I tested the output of the sensor and it gives the expected
output for the WHO_AM_I register but as soon as I connect the SDO of the
sensor to MISO, the output goes down to zero and I don't see anything
oscilloscope. Wondering if you have seen anything like this.
…On Wed, Oct 18, 2017 at 7:07 AM, EBZ-Krisemendt ***@***.***> wrote:
shame on me, it's 22/23 on adafruit huzzah32. it's indeed 21/22 on
official dev-board, sorry
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#741 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/Aetc8F32vTnT-El7hVBV2kiPItKpFq3bks5stdvcgaJpZM4P854w>
.
|
pin 19 is working fine here :) bad soldering? something else pulling the pin? |
Sorry for the late reply. I was able to get this part working and the SPI works as desired. I had to change the pin 19 to pin 22 for my code and it seems to be working. However, I ran into another issue, which was my original problem. I have a AT30TS75 temperature sensor which only has I2C. I could not get I2C working on pin 21 and 22 using Arduino IDE, which I believe are the default pins. I was wondering if there is a way to change the pins from 21 and 22 to 32 and 33. How do i do it? |
@muktillc / 0x20 is the address of a pcf8574 GPIO expander
Serial.println("Try to contact 0x20");
uint8_t data = 0;
// Wire.beginTransmission(0x3A);
// error = Wire.endTransmission();
Wire.beginTransmission(0x3B); // Initialize the Tx buffer
Wire.write(0x0F); // Put WHO_AM_I address in Tx buffer
Wire.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive
Wire.requestFrom(0x3B, 1); // Read two bytes from slave PROM address
while (Wire.available()) {
data = Wire.read(); } // Put read results in the Rx buffer
Serial.print("Error code is:");
Serial.println(data);
delay(1000);
} Is that Restart( If you want to test my theory out I'll write a function that you can insert into your ESP source files uint8_t Wire.transact(const uint8_t ID,uint8_t* writeBytes,const uint8_t writeLen, const uint8_t readLen); to use it with your example: uint8_t writeBuf[10];
uint8_t writeLen=0;
writeBuf[writeLen++] = 0x0f; //build command buffer
uint8_t err=Wire.transact(0x3B,writeBuf,writeLen,1);
if(err!=1){ // bogus, Bad stuff
Serial.print("error during transact");
}
else{
while (Wire.available()) {
Serial.printf("%d ",Wire.read();
} Chuck. |
I believe I'm seeing this also, through the https://github.com/adafruit/Adafruit_BME280_Library library which uses |
I am seeing this as well. Tryed several weird pin-defs - with no luck. Still not sure which is the official I2C pins on my "LOLIN32 Lite" board. My last attempt, not working, was the following (only snippet).
|
@njbuch try one of my branches, either Main or Wire-Destructor. My latest Releaset V0.2.0 has a zip file that contains only the required files. These required files are just copied over the files from this repo. Also, you are specifying the i2c Bus to operate at 1MHz? I2C has two recognized speeds 100KHz and 400KHz. As the speed increases the Pullup resistor values need to decrease. Check out my Wiki page on resistor value considerations: Pullup Considerations At 1MHz I doubt you have low enough values of resistors for the bus to return to HIGH between bits, also if you do have low enough value, you are approaching the limits of the output drivers. Chuck. |
@stickbreaker thanks for getting back, and putting in the effort to fix this. I am on PlatformIO and your repository is quite a few commits behind on the platformio configuration, and I am too much a beginner to be able to partialle merge two fundamental repositories, but I am still interested in helping, if I can get a few more details on building/testing. You describe a Release-Set zipfile? Which I cannot find. Thanks again :) |
@njbuch I don't use platformIO I have no Idea how it is different than using the Arduino environment. My main repo is only one merge behind espressif/arduino-esp32 merge 1208, Does platformIO download the repo every compile? if not just swap in the files from the lastest release zip arduino-esp32-stickbreaker-v0.2.0.zip past that I don't know how to support platformIO. Chuck. |
Superb, I just did what this suggest, with your file and the input from:stickbreaker#16. And it compiles. The output has changed from "Busy timeout errors" to simply no readings. I am on the LOLIN32-Lite board, and I have connected SCL->22 and SDA->23 with a revised Wire.begin(23,22) (with no frequency ;) ) and the sensor is a BME280. |
@njbuch post your I2c reading code: chuck. |
I have just realized that Pin22 is actually also the built-in led. Wat!? I am looking at https://wiki.wemos.cc/_media/products:lolin32:sch_lolin32_lite_v1.0.0.pdf right now, to find out what pins might make most sense...
|
look through your BME280_t library for any Inside wire.cpp at TwoWire::begin() replace the two if(pin) with if(sdaPin < 0) { // default param passed
if(num == 0) {
if(sda==-1) sdaPin = SDA; //use Default Pin
else sdaPin = sda; // reuse prior pin
}
else {
if(sda==-1) {
log_e("no Default SDA Pin for Second Peripheral");
return; //no Default pin for Second Peripheral
}
else sdaPin = sda; // reuse prior pin
}
}
if(sclPin < 0) { // default param passed
if(num == 0) {
if(scl==-1) sclPin = SCL; // use Default pin
else sclPin = scl; // reuse prior pin
}
else {
if(scl==-1){
log_e("no Default SCL Pin for Second Peripheral");
return; //no Default pin for Second Peripheral
}
else sclPin = scl; // reuse prior pin
}
}
Try that. |
@stickbreaker you are the hero of day - right there! Its working like a charm. 👍 |
@njbuch Chuck. |
@stickbreaker, you are indeed a hero! I have one BME280 and two SSD1306 LED displays on I2C and a ESP32. I also ran into this issue where the ESP32 would consistently freeze after ~10 minutes, looping forever on esp32-hal-i2c timeout errors (or something like that). Replacing those five files from your link above seems to have fix it right up. The ESP32 has been reporting humidity/temps now all day with no issues! \libraries\Wire\scr\Wire.h |
How do I update to use the fixed version? |
@xaque208 Chuck |
I've checked out the git repo with from the stickbreaker-i2c branch. I think github swallowed the link above. |
I put a link to @stickbreaker releases and a small explanation how to use it into the Wiki |
Will this code make it into the mainline master branch at some point, or will this remain a fork? |
@xaque208 me-no-dev created a staging branch stickbreaker-i2c in this repo, we are just testing it before merging. Hopefully the need for my fork will disappear in the next couple of week. Then we can have a stable and reliable i2c subsystem. Chuck. |
@stickbreaker I'm sorry for the short reply earlier, i was on a rush. I'm using platformio and thus in order to use your i2c fix i replaced : Thing is, I'm able to read the RTC and set it's alarms for a couple of times but sometimes when ESP boots it gives that message "[E][esp32-hal-i2c.c:1113] i2cCheckLineState(): Bus Invalid State, TwoWire() Can't init).", previously (before replacing those i2c related files) I would get that "i2cWrite(): Busy Timeout! Addr: 68" message.
EDIT:
no errors for now, but will have to run it for a couple of times because the error doesn't show always. |
Ok, after approx. an hour of my sketch running I got the problem again: I compiled with build_flags = -DCORE_DEBUG_LEVEL=1 (ERROR) Went back to your sketch and get same thing (with DEBUG_LEVEL=5 (DEBUG)): Don't think that's a hardware problem. |
@maribeiro static bool i2cCheckLineState(int8_t sda, int8_t scl){
if(sda < 0 || scl < 0){
return true;//return true since there is nothing to do
}
// if the bus is not 'clear' try the recommended recovery sequence, START, 9 Clocks, STOP
digitalWrite(sda, HIGH);
digitalWrite(scl, HIGH);
pinMode(sda, PULLUP|OPEN_DRAIN|OUTPUT|INPUT);
pinMode(scl, PULLUP|OPEN_DRAIN|OUTPUT|INPUT);
if(!digitalRead(sda) || !digitalRead(scl)) { // bus in busy state
log_w("invalid state sda=%d, scl=%d\n", digitalRead(sda), digitalRead(scl));
digitalWrite(sda, HIGH);
digitalWrite(scl, HIGH);
delayMicroseconds(5);
digitalWrite(sda, LOW);
for(uint8_t a=0; a<9; a++) {
delayMicroseconds(5);
digitalWrite(scl, LOW);
delayMicroseconds(5);
digitalWrite(scl, HIGH);
}
delayMicroseconds(5);
digitalWrite(sda, HIGH);
}
if(!digitalRead(sda) || !digitalRead(scl)) { // bus in busy state
log_e("Bus Invalid State, TwoWire() Can't init");
return false; // bus is busy
}
return true;
} That error is telling you that the i2c bus, either SCL or SDA is held low. the ESP32 tried to manually stimulated an i2c recovery operation, but some device is holding the bus low. Since the ESP32 is running, it is not at fault, that only leaves the DS3231. From your circuit description, I suspect it is a power issue, can you post a schematic / link that I can look at. If you are truly using a coin cell battery, you only have milli amps of power available. Try adding a 100uf cap in parallel with the coin cell. That will increase the instantaneous current available on power up. Specs on CR2032 Coin cell Energizer CR2032 As you can see they only rate the battery for 6.8ma max pulse. Chuck. |
@stickbreaker first, let me thank you for your time and help. Simple test sketch i'm using: PS: I also have two temperature sensors (DS18B20) using by OneWire.. could this somehow cause this issue ? |
@maribeiro on pg 11 of Maxim's DS3231 data sheet, it states the i2c interface is live if Vcc In your
:Note, capitalization is screwed up, my phone is assuming i am writing english! Chuck. |
Thanks, will try that and report. |
@maribeiro Can you add a capacitor to the base of Even a 100nf cap should give you a few milliseconds after the rtcc clears it's alarm output. Chuck. |
The I2C core was changed to @stickbreaker code officially after 13dcfe5 (thanks @stickbreaker), Let's close issues with old code and if have problems with the new code, open new issues =) |
Great, thank you for the work here. Looking forward to testing. |
how can i read or write in i2c? i am new in esp32 plz help me |
@qazi24 Use the same commands as you use for the Arduino Uno. //setup
Wire.begin();
//write
Wire.beginTransmission(i2cAddress);
Wire.write(byteValue);
Wire.endTransmission();
//read
Wire.requestFrom(i2cAddress,count);
while(Wire.available()){
uint8_t b=Wire.read();
} You must have pullup resistors on both SDA and SCL, the builtin pullups of the chip are too weak to function correctly. Chuck. |
void setup() { |
@ytemelli Chuck. |
I know this issue is closed but I'm experiencing the same issues as @maribeiro. I have application using the ESP32 connected to an MCP23008. I am reading the inputs on the MCP23008 in the main loop really fast. If I power cycle just the ESP32 module it is very easy to get the MCP23008 stuck in I2C read state where it has the SDA line held low. I can verify this with a meter on the SDA line. I am not able to complete Wire.begin until the MCP23008 is power cycled. It seems there is no way to get it out of it's stuck I2C Slave Read state. I see you are pulsing the SCL line high then low 9 times, I tried increasing that cycle count but to no avail. I don't think this is an issue with your library but rather an issue with the i2c protocol in general or possibly just the way the MCP23008 behaves. Any advice would be greatly appreciated. |
@telliottosceola what version are you using? I would recommend updating to the latest dev level. I2c is just 4 files #1962 describes them. I use MCP23008 as keypad drivers (4x4 matrix) without any problems.
Set your debug level to Chuck. |
Works flawlessly now. I can't thank you enough. I have been banging my head on my desk for a couple of days now trying to fix the issue. That said I just quickly looked over i2cCheckLineState and I don't see any changes. What have you changed since the files you referenced in arduino-esp32-stickbreaker-v0.2.0.zip above that would have fixed this issue? P.S. I'm a developer at ncd.io. I'd like to offer you some free hardware for your kind efforts here. We make an enormous line of I2C peripherals for almost any application which sounds like you might be interested in ;). If you are interested in some free hardware shoot me an email travis at ncd.io and I'll get you fixed up. Thanks Chuck, |
People, There is a fix on Release 1.0.1 January 2019 (https://github.com/espressif/arduino-esp32/releases) with regard to: That was the issue for me. I2C working flawlessly now. Regards, Luciano |
@stickbreaker |
@Bryanbaring Open up a new issue, don't hijack this closed thread. If you can't upload code to the esp32, I can't help you with i2c issues. Chuck. |
Is this always requrired when using esp32 for i2c or something specific to a usecase? |
@thehellmaker The ESP32's pullups are very weak, 50k to 100k ohm. Unless you want to run the i2c interface at 10khz you will need lower value resistors as pullups. With a 3.3v bus( the operating voltage of the ESP32) you should use a 3.3k ohm, at 100khz and a 2.4k ohm at 400khz. Chuck. |
@stickbreaker thank you so much.. This solved my intermittent failures with i2c on esp32. Much appreciated |
Hello everyone I have did your program about the test of i2c and with my esp32 it's a mini wemos ttgo esp32 and the program give always the same answer same when I reset my esp32 . Do you have a solution because I search during one month and I not find solutions |
Her answer of program is : |
Please do not hijack issues. Open a new issue and follow the issue template |
I'm sorry, I'm a new in the forum so i don't know how it works |
Hello, sorry for opening this again, but I think I do have this problem occuring. I have Sparkfun's ESp32 Thing plus with multiple QWIIC boards connected to it (accelerometer, two buttons, mp3 trigger, port expander, WS2812 leds and current meter). It works for random amount of time (sometimes few minutes sometimes few hours) and then this happens:
Sometimes it is sda(23)=1, scl(22)=0 and sometimes sda(23)=0, scl(22)=0 All those boards have pullups and I have cut them on all except one as recommended so now it should have 2.2k on both lines. Is there anything I could do more to make it work? Thank you. |
Hardware:
Board: ESP32 Dev Module
Core Installation/update date: 11/jul/2017
IDE name: Arduino IDE
Flash Frequency: 40Mhz
Upload Speed: 115200
Description:
I am not able to generate the I2C clock. I have an ST microelectronics accelerator that I am using which has an I2C interface. So just wanted to see if I2C is working.
I have seen many people running into the same problem but could not find a solution for this issue. No errors generated when compiling the code.
Please find my code below.
Sketch:
//Change the code below by your sketch
#include "Wire.h"
void setup() {
Wire.begin(21,22);
Serial.begin(115200);
Wire.setClock(400000); // choose 400 kHz I2C rate
Serial.println("Start i2c-test");
}
void loop() {
byte error;
// 0x20 is the address of a pcf8574 GPIO expander
Serial.println("Try to contact 0x20");
uint8_t data = 0;
// Wire.beginTransmission(0x3A);
// error = Wire.endTransmission();
Wire.beginTransmission(0x3B); // Initialize the Tx buffer
Wire.write(0x0F); // Put WHO_AM_I address in Tx buffer
Wire.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive
Wire.requestFrom(0x3B, 1); // Read two bytes from slave PROM address
while (Wire.available()) {
data = Wire.read(); } // Put read results in the Rx buffer
Serial.print("Error code is:");
Serial.println(data);
delay(1000);
}
The text was updated successfully, but these errors were encountered: