Boo0ns / arduino

Automatically exported from code.google.com/p/arduino
0 stars 0 forks source link

Wire should have ability to not enable internal pull-ups #506

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Hi there,

currently Wire (through twi_init()) enables by default the internal pullups of 
the uC.

As all 16MHz runs at 5V this means that with pullups enabled signals will have 
a 5 volt on logic level. Unfortunately, as many I2C devices runs at 3 Volts and 
aren't 5Volts tolerant, sending 5V signals to them is clearly a very bad idea.

I would propose making the pullpus enabling optional and off by default. In my 
experience, people overlook the fact that Wire does enable the pullups causing 
possible problems on the I2C devices used.

Moreover, tests 
(http://www.dsscircuits.com/articles/effects-of-varying-i2c-pull-up-resistors.ht
ml) have shown that internal pullups performs extremely bad in terms of signal 
quality and bus speed. So, they shouldn't been used anyway.

In case this is accepted, I'll gladly submit a patch for this.

Thanks,

Fabio Varesano

Original issue reported on code.google.com by fabio.va...@gmail.com on 19 Mar 2011 at 5:41

GoogleCodeExporter commented 9 years ago
Hi 

I would agree to disable internal pullups in Arduino by default.

Enabling the pullups by default mean we have to use a level converter to 
communicate safely with 3.3V sensors. So basically we need to add an extra 
piece of hardware that is not really needed just because the internal pullups 
are enabled by default!

And as Fabio points out: Many tests have shown that the AVR Internal Pullups 
are not well suited, and most sensor breakouts and similar i2c devices will 
have hardware pullups anyway!

Thanks 

Jussi Hermansen

Original comment by jussi...@gmail.com on 1 Apr 2011 at 8:35

GoogleCodeExporter commented 9 years ago
If internal pull-ups are disabled by default (which seems like a good thing to 
do, based on opinions above), I think there should be a public method called 
something like Wire.enablePullups() that calls a new function in utility/twi.c 
called maybe twi_enblePullups(,) which is just the chunk of twi_init() that 
does the pull-up enabling.

Original comment by tod.k...@gmail.com on 23 Apr 2011 at 8:49

GoogleCodeExporter commented 9 years ago
I agree this is a very bad design. It should be

TwoWire::begin(bool useInternal5vPullups = false)

Or something like that.

Original comment by tdh...@gmail.com on 11 Jul 2011 at 2:35

GoogleCodeExporter commented 9 years ago
I'm not sure about the best way to handle this, but if are changing it, it 
would be good to do for Arduino 1.0, so I'm marking it for that release.

Original comment by dmel...@gmail.com on 29 Aug 2011 at 6:14

GoogleCodeExporter commented 9 years ago
Thank you David!

Original comment by fabio.va...@gmail.com on 29 Aug 2011 at 6:47

GoogleCodeExporter commented 9 years ago
Hi :)

I also found the default enabling of the internal 5V pullups is to be a 
problem.  The planned change suggested by Fabio and fleshed out in comments 2 & 
3 works fine - I've been happily using versions of Wire (& twi) modified along 
these lines for the past few months.  

I'm glad your planning to incorporate this into v1.0.  I would also happily 
help out with a patch submission or review if any help is required (I imagine 
it's not).

Andrew

Original comment by andrew.m...@bloater.org on 6 Sep 2011 at 9:42

GoogleCodeExporter commented 9 years ago
Silly question, but why, if it's a problem for the pull-ups to drive the line 
to 5V, isn't it a problem when the Arduino drives the data lines with data?  
Doesn't that take pins to 5V, too?  Or do the I2C devices only drive the bus 
low or tristate?

Original comment by dmel...@gmail.com on 9 Sep 2011 at 3:59

GoogleCodeExporter commented 9 years ago
I2C is open drain, meaning that master and slaves never actively drives the 
signal high. The line is pulled up high and the devices communicate only 
bringing it low. So, when you have to communicate with a 3V3 device, if you 
pullup to 3V3 and you disable the 5V pullups, as the ATMEGA will take any 
signal >= 2.6 as high, you'll be perfectly fine even without a logic level 
converter.

Original comment by fabio.va...@gmail.com on 9 Sep 2011 at 8:41

GoogleCodeExporter commented 9 years ago
Hey, sorry to keep bugging you guys, but there's some skepticism on the 
developers list (http://mail.arduino.cc/mailman/listinfo/developers_arduino.cc) 
that the pull-ups are really causing problems.  Can you give more details of 
the situations in which you've had trouble?  Did you try attaching external 
pull-ups (e.g. 4K7) to 3V3, which should overwhelm the internal pull-up 
resistors?

Original comment by dmel...@gmail.com on 9 Sep 2011 at 12:43

GoogleCodeExporter commented 9 years ago
Hi David :)

I must admit that Paul Stoffregen's analysis on the developers list 
(http://arduino.cc/pipermail/developers_arduino.cc/2011-September/005568.html) 
seems pretty thorough and convincing.  My own 'problem' with the automatic 
enabling of the 5V pullups was not wanting to use them with a 3V3 tolerant 
part.  Rather than actually having had a part fail I didn't want to be building 
a reliability issue into my hardware.  If Paul is correct then is seems 
unlikely that anyone will ever have an actual failure.

That said, however, (and ignoring the bizarre choice of hard-wired external 10K 
pullups on the Mega) it seems of little cost to everyone to add an 
'enablePullups' flag to the two versions of Wire.begin() that defaults to true 
(for backward compatibility).

Andrew ;)

Original comment by andrew.m...@bloater.org on 9 Sep 2011 at 1:15

GoogleCodeExporter commented 9 years ago

Original comment by dmel...@gmail.com on 16 Dec 2011 at 10:04

GoogleCodeExporter commented 9 years ago
Hi, I ran into this problem today.  I'm using an ATMega328 and a Raspberry Pi.

I had no external pull-up resistors connected to the Arduino because the 
Raspberry Pi runs at 3.3v and did not want 5.0v going to the SDA/SCK pins on 
the Pi.  My plan was to add appropriate resistors later after initial testing.

I found that slow communications worked fine, but if I sent/received lots of 
data continually the Arduino would actually either freeze (my cpu acticity 
light would stop) or the arduino (as a slave) would stop responding on the I2C 
bus.

I thought there was some issue with timing in my code but after commenting out 
pretty much all of it and making it return just 1 instead of real data the 
problem persisted.

After digging around I came across a blog post which mentioned this bug.  I 
disabled the internal pull-up resistors using the code provided in the blog 
post and lo-and-behold communication was then reliable!  Phew!

So yes, IMHO, the Wire and/or TWI code definately needs to be updated as does 
the documentation on the Arduino web site  (Wire.begin() and Wire library 
tutorials).

If someone wants to test Raspberry Pi to/from Arduino then my i2c slave code 
(with the fix mentioned) can be found here: https://github.com/hydra/i2cslave

Original comment by dominicc...@gmail.com on 11 Feb 2013 at 11:53