Skip to content

Multiply Wire.begin(int sda, int scl) call from different libraries #2607

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

Closed
enjoyneering opened this issue Oct 14, 2016 · 13 comments
Closed

Comments

@enjoyneering
Copy link

Hardware: NodeMCU1.0
Core Version: 2.3.0

Description
NodeMCU1.0 reboots or acting weird after second Wire.begin(int sda, int scl) call.

Settings in IDE
IDE: 1.6.11
Module: NodeMCU1.0

Good day everyone,

I have a couple of i2c sensors connected to the same pins (D1, D2) . The first sensor is HTU21D and the second is BH1750FVI. Also tried combination of i2c LCD screen and HTU21D. The same story every time - NodeMCU1.0 reboots or acting weird.

I'm using the libraries to interact with sensors and screen. Each library has its own Wire.begin(int sda, int scl) call during the initialization. Most of the time after the second Wire.begin(int sda, int scl) call NodeMCU1.0 reboots.

I've tested the code on Arduino Nano with hardware i2c bus and it works fine. I guess it happens because esp8266 uses software i2c and the second Wire.begin(int sda, int scl) call to the same pins breaks the logic.

Dose anybody know how to fix it?

Thank you.

@WereCatf
Copy link
Contributor

Modify the other library to not call Wire.begin().

@vlast3k
Copy link

vlast3k commented Oct 14, 2016

i had the same scenario, and indeed - modified all the libs i needed, and
call Wire.begin(...) on a central place
though you may have another issue as wire.begin does almost nothing more
than wrapping a call to
void twi_init(unsigned char sda, unsigned char scl){
twi_sda = sda;
twi_scl = scl;
pinMode(twi_sda, INPUT_PULLUP);
pinMode(twi_scl, INPUT_PULLUP);
twi_setClock(100000);
twi_setClockStretchLimit(230); // default value is 230 uS
}

maybe if you use the sensors too quickly one after the other, the Wire lib
somehow resets itself while the bus is in some unclear state
try to add some delays and calling Wire.status() before the invocation of a
sensor, which does some magic to recover the bus or wait until it's free.

On Fri, Oct 14, 2016 at 10:21 PM, WereCatf [email protected] wrote:

Modify the other library to not call Wire.begin().


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#2607 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAeDp8xHJ_Pn8uBRpQJ804Db42chjkSjks5qz9ZLgaJpZM4KXNBw
.

@supersjimmie
Copy link

I use an i2c display and an i2c ADC together without any issues.
I do an Wire.begin(..,..) first and then start the display and the ADC.
Perhaps (one of) your libraries has the wire pins hardcoded to other pins, or one of the library re-inits it with other different settings.

@enjoyneering
Copy link
Author

enjoyneering commented Oct 21, 2016

Modify the other library to not call Wire.begin().

I have to modified all standard & custom libs and it's going create a mess and frustration for people in the future. I still believe that the modification should be done in ESP core.

maybe if you use the sensors too quickly one after the other, the Wire lib
somehow resets itself while the bus is in some unclear state
try to add some delays and calling Wire.status() before the invocation of a
sensor, which does some magic to recover the bus or wait until it's free.

This is interesting idea I'll check it.

@miky2k
Copy link

miky2k commented Oct 24, 2016

It duplicate of #2162 , Wire.begin call should be rewritten to take account of multiple calls.

@enjoyneering
Copy link
Author

enjoyneering commented Oct 28, 2016

Looks like I found the solution. In each lib after Wire.begin(int sda, int scl) I added Wire.setClockStretchLimit(1500); and everything work fine.

@miky2k
Copy link

miky2k commented Oct 30, 2016

You make a workaround not a solution to this problem!!

@bperrybap
Copy link

This was not fixed. It can't be handled through a custom core work around.
3rd party code that uses Wire expects a portable interface and you can not expect users to have to go in modify other 3rd party libraries because of this deficiency.
The Wire library needs to handle this.
This was also an issue in the Wire library in the pic32 core. Their solution was to put reference counts in the Wire code so that after the first call, subsequent calls do nothing.
In their core they also added Wire.end() which clears the counter and releases all the h/w.

@enjoyneering
Copy link
Author

I've rewrote the Wire library. Works good - https://github.com/enjoyneering/ESP8266-I2C-Driver

@bperrybap
Copy link

Is is fully working and tested? If so, Why not do a pull request and see if they accept it.

@enjoyneering
Copy link
Author

Hi,
I've tested only with my github libraries - HTU21D, BH1750FVI, BMP085_BMP180, LiquidCrystal_I2C
If you can try it with other and let me know?

@Terdulator
Copy link

Hi,
Could you please show a code example for 8266 as a slave?
I just want to be discovered by I2C scanner on master Arduino Uno.
Unfortunately I got error on Wire.begin(address), even I installed the files posted on https://github.com/enjoyneering/ESP8266-I2C-Driver.
Thanks

@Finside
Copy link

Finside commented Aug 8, 2019

Also noticed problems with ESP8266 (NodeMCU)
after Gesture sensor (APDS-9960 from RobotDyn) was added
with RTC (DS3231SN).

Started to examine the problem and found a page in Russian:
https://elchupanibrei.livejournal.com/34751.html - Description in Russian
Post by 2017-11-06 21:35:00

The author fixed libraries:

twi.h
core_esp8266_si2c.cpp

Wire.h
Wire.cpp

https://github.com/enjoyneering/ESP8266-I2C-Driver

Copy and replace "twi.h", "core_esp8266_si2c.cpp" in folder %USERPROFILE%\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\cores\esp8266

Copy and replace "Wire.h", "Wire.cpp" in folder %USERPROFILE%\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\Wire


I think it can be useful to others.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants