Go Down

Topic: I2C pullup issue (Read 2798 times) previous topic - next topic

mattallen37

Apr 19, 2012, 06:32 am Last Edit: Apr 19, 2012, 06:35 am by mattallen37 Reason: 1
I am trying to interface the Lego NXT with an Arduino Mega 2560. Due to the design of the NXT, the 10k pullups on the Arduino are far too strong. The recommended pullup strength for the NXT I2C bus(es) is 82k.

I am looking for a simple solution. I was thinking about the SparkFun logic level converter, but both sides already have 10k pullups installed.

It looks like a PCA9517A would fix the issue, because each side needs it's own pullups. However, the largest package is an SO-8 (and I'm not all that good with a soldering iron).

What would you recommend I do? I don't need voltage level shifting, but minimal shifting would be okay.

Removing/replacing the pullups on the Arduino would be the obvious answer, but it's out of the question. Jumping the "protection" resistors in the NXT is also out of the question.

Nick Gammon

What 10k pullups, first?
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

CrossRoads

82K pullup, the I2C signals will take fooooreeeeeveeeer to transition from low to high.
Be ready to really lower the bus speed with  that.

Got a spec on the NXT?

There is no 10K resistor internally or on the board. See the schematic for the A4/SDA & A5/SCL lines.
http://arduino.cc/en/uploads/Main/Arduino_Uno_Rev3-schematic.pdf

From the ATMega32 spec with a couple of things >> emphasized <<.

The 2-wire Serial Interface (TWI) is ideally suited for typical microcontroller applications. The
TWI protocol allows the systems designer to interconnect up to 128 different devices using only
two bi-directional bus lines, one for clock (SCL) and one for data (SDA).
>>The only external hardwareneeded to implement the bus is a single pull-up resistor for each of the TWI bus lines. <<
All devices connected to the bus have individual addresses, and mechanisms for resolving bus
contention are inherent in the TWI protocol.

As depicted in Figure 22-1,
>>both bus lines are connected to the positive supply voltage through pull-up resistors. <<
>> The bus drivers of all TWI-compliant devices are open-drain or open-collector.<<
This implements a wired-AND function which is essential to the operation of the interface. A low
level on a TWI bus line is generated when one or more TWI devices output a zero. A high level
is output when all TWI devices tri-state their outputs,
>>allowing the pull-up resistors to pull the line high. <<
Note that all AVR devices connected to the TWI bus must be powered in order to allow any
bus operation.
The number of devices that can be connected to the bus is only limited by the bus capacitance
limit of 400 pF and the 7-bit slave address space. A detailed specification of the electrical characteristics
of the TWI is given in "Two-wire Serial Interface Characteristics" on page 327. Two
different sets of specifications are presented there, one relevant for bus speeds below 100kHz,
and one valid for bus speeds up to 400kHz.

4.7K is usually spec'ed for pullups. 2.2K for long wires.  You can see the rising signal really degrade with a 10K pullup.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

mattallen37

@Nick Gammon look at the mega 2560 schematic to see the 10k pullups (top middle of schematic image).

@CrossRoads I know. The NXT uses bit-banged I2C that runs at 9600 bps (default). The NXT has 4k7 resistors in line on the I2C lines, so if you use 10k pullups, when the NXT pulls the line low (assuming exactly 0v on the I2C pin) it will only pull down the bus to about 1.5v (based on a 4.7v supply). If you use 82k, it will pull down to around 0.25v.

If you want to see the schematic, you can download the Hardware Developer Kit. The "protection" 4k7 resistors are on page 3, bottom left, of "Appendix 1-LEGO MINDSTORMS NXT hardware schematic.pdf".

You will note that I said I am using a Mega 2560, not an Uno. See above link for schematic showing the pullups.



I don't want to debate the requirements; I just want help finding a solution.

Grumpy_Mike

Quote
I just want help finding a solution.

Then just unsolder them.

mattallen37

As I said in my first post, that's not an option.

BTW, I don't mean to be rude at all, but is it common practice on these forums to ignore clearly stated, project specific requirements? This is at least the third or fourth time where people have tried to change my project's requirements, or make suggestions that are completely contrary to what I said possible. I'm used to forums where people either take you at your word, or ask questions to better understand the situation (so that they can help you). Like I said, I don't mean to be rude at all, I just want to understand why the attitude on these forums is sometimes significantly different than on forums I'm used to using.

What I want from this thread, is a solution to having an I2C bus split so that I can use different strength pullups on the different sides.

Nick Gammon

Quote
... or ask questions to better understand the situation ...


Well that's what I am trying to do. I honestly didn't know about those resistors on the Mega board - the Uno doesn't have them.


The recommended pullup strength for the NXT I2C bus(es) is 82k.


Can you give a link to that please?

I've done some investigation into I2C pull-up resistors in the past:

http://www.gammon.com.au/i2c

On that page you can see that even 10K is a bit low for a nice square signal, and 4.7K tends to give a better result, and is what is recommended as a rule of thumb.

Now you say that the NXT already has the 4.7 K resistors, fair enough. Put that in parallel with 10K and you get 3.2K which isn't ridiculously low, especially looking at the scope outputs.

What you might try is simply disabling the internal pull-ups. That is adding even more to the line. You haven't posted any code, so I can't see if you have done that yet or not.

In twi_init are these lines:

Code: [Select]
  // activate internal pullups for twi.
  digitalWrite(SDA, 1);
  digitalWrite(SCL, 1);


You could undo that by simply writing those back to LOW again (after Wire.begin).

Let us know how that goes. The other option is surely an I2C extender, that would isolate both sides from each other.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

mattallen37

The recommended 82k for the NXT is common knowledge among anyone who builds NXT digital sensors. I don't know of a specific place I can point you to, other than the schematic of the ultrasonic sensor (included in the HDK I gave a download link to earlier). It's quite obvious by that, that the specific value of 82k originated with TLG (The Lego Group, the ones who designed the NXT).

You mis-read what I said about the 4.7k resistors. They are "protection" resistors, in series, between the ARM7 and the sensor ports (please refer to the NXT schematic to see what I mean).

Quote from: Myself
The NXT uses bit-banged I2C that runs at 9600 bps (default).

The NXT has 4k7 resistors in line on the I2C lines, so if you use 10k pullups, when the NXT pulls the line low (assuming exactly 0v on the I2C pin) it will only pull down the bus to about 1.5v (based on a 4.7v supply). If you use 82k, it will pull down to around 0.25v.




So now that it's all clear, how do you suggest I solve the problem? Is soldering a tiny PCA9517A IC the only answer? It seems there should be a rather simple solution, maybe using transistors.

CrossRoads

Sorry mattallen37, I totally missed that you had a Mega - I was also unaware of the 10K resistors there.
Looks like they are part of a very little 8-pin package as well, so not removable.
On page 3, which signals are being used for I2C? The DIGIAI0 and DIGIAI1 type signals?

http://www.atmel.com/Images/doc6175.pdf
Okay, looks like TWCK  & TWD pins.
I can't even tell going from the data sheet which pins are actually used for I2C.

However, that series 4.7K resistor is a killer.
This  doc desribes the I2C pins:
LEGO MINDSTORMS NXT Hardware Developer Kit.pdf
Not real I2C tho. No open drain pins, the NXT must be master, you have to control the direction of the lines in software.

I was thinking a buffer chip like this one:

http://www.ti.com/lit/ds/sces640d/sces640d.pdf

"The TXS0102 can be used to bridge the digital-switching compatibility gap between two voltage nodes to
successfully interface logic threshold levels found in electronic systems. It should be used in a point-to-point
topology for interfacing devices or systems operating at different interface voltages with one another. Its primary
target application use is for interfacing with open-drain drivers on the data I/Os such as I2C or 1-wire, where the
data is bidirectional and no control signal is available. The TXS0102 can also be used in applications where a
push-pull driver is connected to the data I/Os, but the TXB0102 might be a better option for such push-pull
applications."

Not sure if the 3V source driving thru a 4.7K  will be enough still.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Nick Gammon


So now that it's all clear, how do you suggest I solve the problem? Is soldering a tiny PCA9517A IC the only answer? It seems there should be a rather simple solution, maybe using transistors.


I see what you mean, now I read the datasheet. Well, a simple solution would be to set up a Atmega328 as a buffer chip (cost, around $5). A couple of decoupling capacitors, and a couple of resistors and you are done. Use the internal 8 MHz oscillator. Hook up the NXT to the I2C pins with your required resistors and disable the pull-ups. Then send / receive data to your Mega using SPI (or async serial).
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

mattallen37

Yes, DIGIAI0 and DIGIAI1 are the I2C lines. The reason they aren't labeled as I2C pins by the datasheet, is that they aren't. All four sensor ports use bit-banged I2C, which is part of the reason why it's so slow.

Indeed you're right about those 4.7k resistors. However, the ARM7 is running at 3.3v (IIRC), and the I2C bus is 5v (actually more like 4.3-4.7). Those resistors are actually semi-necessary, due to the fact that NXT sensors are 5v, not 3.3v. Okay... enough on that.

Yes, the NXT is always master.

I didn't read through the entire datasheet, but it would probably work (using 3.3v on the NXT side, since the ARM7 is already running 3.3v), but again, it's a matter of the package size (I think that one is even smaller than the PCA9517A).

What do you think about the PCA9517A? It is rated up to 5.5v on both sides.

So is my only reasonable option to solder and use one of those ICs? If so, I guess I need to order some, as well as some SO-8 > DIP adapters and solder wick.

mattallen37


I see what you mean, now I read the datasheet. Well, a simple solution would be to set up a Atmega328 as a buffer chip (cost, around $5). A couple of decoupling capacitors, and a couple of resistors and you are done. Use the internal 8 MHz oscillator. Hook up the NXT to the I2C pins with your required resistors and disable the pull-ups. Then send / receive data to your Mega using SPI (or async serial).
Great idea, but it's a bit more complicated than that. There are other I2C devices on the Arduino I2C bus (a large shield) that the NXT needs to communicate with as well.

That does provide an interesting option though; bit-bang an I2C master on the "middle" Atmega 328, and use the HW bus for slave communication with the NXT. That's something I will consider if I can't get and solder an I2C expander.

Nick Gammon

Would this do what you want?

http://www.openelectrons.com/index.php?module=pagemaster&PAGE_user_op=view_page&PAGE_id=8

Or are you wanting to develop your own?
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

mattallen37

That's exactly what I'm using. I have already written lots of Arduino SW for it (drivers for additional sensors etc.). What I want to do is use it as a large expander for the NXT, and the Arduino is needed to control some of the stuff (buttons, RGB LED, and three of the I2C busses). So altogether there would be 3 devices on the I2C bus (minimum); the Arduino Mega, Bank A, and Bank B of the NXShield.

Go Up