Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

I2C buss works on Arduino, not on Netduino


  • Please log in to reply
22 replies to this topic

#1 anthrolume

anthrolume

    Member

  • Members
  • PipPip
  • 15 posts

Posted 20 April 2011 - 11:03 PM

I'm working on a project with a pretty long I2C buss, containing 50 slave devices.

The buss works great when controlled by an Arduino Uno.

When I hook the same buss up to my Netduino Plus, the bus won't work at all. If I remove about 15 slaves, it starts working.

I was using 2.2K pull-up resistors on the I2C clock and data lines. I also tried using 820 ohms, but there was no change in behavior. I also tried supplementing the Netduino's power through the barrel jack, and powering the I2C buss separately from the Netduino. Neither of those ideas helped.

Can anyone think of a reason why the same physical I2C setup would work on an Arduino, but no on a Netduino?

Here's the buss in question:
Posted Image

Thanks,
Bryan
aka anthrolume

#2 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 20 April 2011 - 11:18 PM

Hi Bryan, Cool project! Are you tieing the pullups on your I2C SDA/SCL lines to the 5V header or the 3V3 header on your Arduino? Netduino? In theory, the two should wire exactly the same (power supply, pullups, everything). I2C is an open drain protocol--so all the I2C lines on the Netduino are doing is switching between driving logic level 0 and going into a high-impedence state. Have you tried measuring the signal on the line with an oscilloscope or logic analyzer? Perhaps the pulled from the the SAM7X chip is not strong enough to create a strong enough signal drop for that many devices... But we'd need some real-world measurements to know for sure. [Also, just for fun...try creating OutputPorts for pins A4/A5 and then disposing them right before you open up the I2C connection. If that fixes the issue, then there's a glitch in the firmware.] Chris

#3 anthrolume

anthrolume

    Member

  • Members
  • PipPip
  • 15 posts

Posted 20 April 2011 - 11:30 PM

Cool project!


Thanks! I'm obsessed. And I'd love to be doing this on a Netduino, so I can have a real animation thread. :-)

Are you tieing the pullups on your I2C SDA/SCL lines to the 5V header or the 3V3 header on your Arduino? Netduino?


5V on both.

In theory, the two should wire exactly the same (power supply, pullups, everything). I2C is an open drain protocol--so all the I2C lines on the Netduino are doing is switching between driving logic level 0 and going into a high-impedence state.


Yeah I'm literally moving the four wires from one board to the other.

Have you tried measuring the signal on the line with an oscilloscope or logic analyzer? Perhaps the pulled from the the SAM7X chip is not strong enough to create a strong enough signal drop for that many devices... But we'd need some real-world measurements to know for sure.


I haven't. I do have a (crappy) scope here - a BK 2120B, so I'll take a look. What am I supposed to measure? Just look at the shape of the waveform? (BTW FWIW I'm running the buss at 100KHz.)

[Also, just for fun...try creating OutputPorts for pins A4/A5 and then disposing them right before you open up the I2C connection. If that fixes the issue, then there's a glitch in the firmware.]


Tried it - no change.

    OutputPort a4 = new OutputPort(Pins.GPIO_PIN_A4, false);
    OutputPort a5 = new OutputPort(Pins.GPIO_PIN_A5, false);
    a4.Dispose();
    a5.Dispose();

Thanks,
Bryan

#4 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 20 April 2011 - 11:41 PM

Hi Bryan,

I haven't. I do have a (crappy) scope here - a BK 2120B, so I'll take a look. What am I supposed to measure? Just look at the shape of the waveform? (BTW FWIW I'm running the buss at 100KHz.)

What I'm interesting in seeing is what the signal looks like when you only have 1-15 devices on the bus and what it looks like when you have all the devices on the bus.

Have you tried running I2C at an even slower speed--as a test?

Also, I2C pullup resistors should be "sized" based on voltage and the length of (# of devices on) your I2C bus. It's possible that the pullup resistor value should be dramatically different from where it's at now--but "works" on the Arduino's AVR chip anyway.

Chris

#5 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 20 April 2011 - 11:47 PM

Also, completely silly question but...when you say you are moving the 4 wires...are you also connecting the GND of the I2C circuit to one of the GND headers on the Netduino? You should have 4 wires: 5V GND A4 (TWD -- I2C data) A5 (TWCK -- I2C clock) Chris

#6 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 21 April 2011 - 12:06 AM

Here's a good writeup on the value of I2C pullup resistors and their effect on the waveform: http://www.dsscircui...-resistors.html Hint: you want a square-ish wave :) But you also need to stay within I2C guidelines. They can be found in section 16.1 (page 39-40) of the official I2C spec: http://www.nxp.com/a...98/39340011.pdf For your calculations, the I2C pins on the Netduino are limited to 8mA. [This may be the factor which is different between your Netduino and your Arduino: varying strength to output a low voltage level on the I2C lines requires a different resistor value, although it may be possible to use one value for both. With shorter I2C bus lengths, it's usually not an issue.] Chris

#7 anthrolume

anthrolume

    Member

  • Members
  • PipPip
  • 15 posts

Posted 21 April 2011 - 08:31 AM

Thanks Chris. Consolidating my responses.

What I'm interesting in seeing is what the signal looks like when you only have 1-15 devices on the bus and what it looks like when you have all the devices on the bus.
...
Hint: you want a square-ish wave :)


This is TWCK, measured at the "end" of the buss (kinda), running off the Netduino, with 21 MinM slaves installed. This actually works (the Netduino is talking to all the LEDs fine with this setup). I'm using 1K pullup resistors ((3.3V - 0.4V) / 3ma).

Posted Image

The rise time looks pretty good. But it looks to me like the clock lows aren't hitting 0V. The picture is 1microsecond/div & 2V/div. So maybe the Netduino can't pull the data and clock lines to 0V when there are more devices? :-S I'm a CS guy :-P

Have you tried running I2C at an even slower speed--as a test?


I did, all the way down to 10KHz, and it didn't make any difference.

Also, completely silly question but...when you say you are moving the 4 wires...are you also connecting the GND of the I2C circuit to one of the GND headers on the Netduino?


Of course. I move all four (Gnd/5V/TWCK/TWD) from one board to the other.

Here's a good writeup on the value of I2C pullup resistors and their effect on the waveform:
http://www.dsscircui...-resistors.html

But you also need to stay within I2C guidelines. They can be found in section 16.1 (page 39-40) of the official I2C spec:
http://www.nxp.com/a...98/39340011.pdf


I don't know the capacitance of these ThingM MinM smart LEDs I'm using. They have an ATtiny45 on the back, so maybe 10pF like the Arduino? Not sure. So I used the (Vcc-0.4)/3mA calculation with Vcc = 3.3V because I remember reading the ports on the Netduino were "3.3V but 5V tolerant". Anyway that gave me 960 ohms, so I used 1K. That value works on the Arduino too. And looking at the scope, the clock looks reasonably square, by the standards set forth in the first article you linked.

For your calculations, the I2C pins on the Netduino are limited to 8mA. [This may be the factor which is different between your Netduino and your Arduino: varying strength to output a low voltage level on the I2C lines requires a different resistor value, although it may be possible to use one value for both. With shorter I2C bus lengths, it's usually not an issue.]


:-( You lost me. Are you saying the Netduino only has 8mA of current available to drive the buss? In that case, should I add a buss driver of some kind?

Thanks again for all your help. I really want to make this work! :-)

-Bryan

#8 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 21 April 2011 - 10:23 AM

Hi Bryan, If you reduce the # of devices on your I2C bus to 10, does the oscilloscope show the line going all the way down to 0V (GND)? Try using a set of weaker I2C resistors, and see if that helps. Also, the I2C lines on the Netduino will be 5V (not 3.3V) if you tie them to the 5V header. The Netduino won't drive any voltage on I2C...the line will be 5V due to the pull-up resistors, and the Netduino will "pull down" the voltage to 0V to communicate. Chris P.S. If you want, you could also use an external open-drain driver chip between TWD/TWCK and your I2C bus. I don't have any specific recommendations for that however.

#9 anthrolume

anthrolume

    Member

  • Members
  • PipPip
  • 15 posts

Posted 21 April 2011 - 08:52 PM

Hi Chris,

If you reduce the # of devices on your I2C bus to 10, does the oscilloscope show the line going all the way down to 0V (GND)?


When I hooked everything up this morning, I was seeing it right at ground. Now it has crept up to about half a volt over 0, so I am starting to suspect my old and crappy scope acts different when it's warm.

Try using a set of weaker I2C resistors, and see if that helps.


I have tried 10K, 2.2K, 1K, 680 ohms, and currently running at 560 ohms. All those resistances work fine with the Arduino and all 50 LEDs on the buss. Lowering the pullup resistance doesn't seem to have any effect on who many slaves the Netduino can handle - it still tops out around 30.

FWIW, here's TWCK, measured on the buss, from the Arduino, with 49 LEDs installed, 560 ohm pullups.

Posted Image

Also, the I2C lines on the Netduino will be 5V (not 3.3V) if you tie them to the 5V header. The Netduino won't drive any voltage on I2C...the line will be 5V due to the pull-up resistors, and the Netduino will "pull down" the voltage to 0V to communicate.


Ok that makes sense. But then I'm not sure what the 8mA part that you posted before means.

P.S. If you want, you could also use an external open-drain driver chip between TWD/TWCK and your I2C bus. I don't have any specific recommendations for that however.


I'm interested in trying this, since nothing else I've done is getting me anywhere. What specific chip type should I search for?

Thanks,
Bryan

#10 CodeRage

CodeRage

    New Member

  • Members
  • Pip
  • 8 posts

Posted 21 April 2011 - 11:15 PM

Hi Chris,



When I hooked everything up this morning, I was seeing it right at ground. Now it has crept up to about half a volt over 0, so I am starting to suspect my old and crappy scope acts different when it's warm.



I have tried 10K, 2.2K, 1K, 680 ohms, and currently running at 560 ohms. All those resistances work fine with the Arduino and all 50 LEDs on the buss. Lowering the pullup resistance doesn't seem to have any effect on who many slaves the Netduino can handle - it still tops out around 30.

FWIW, here's TWCK, measured on the buss, from the Arduino, with 49 LEDs installed, 560 ohm pullups.

Posted Image



Ok that makes sense. But then I'm not sure what the 8mA part that you posted before means.



I'm interested in trying this, since nothing else I've done is getting me anywhere. What specific chip type should I search for?

Thanks,
Bryan


I=V/R, so for each i2c device on the bus you need to calculate the I, so if they all have 2k pull up resistors and there are 10 of them, not including the netduino. So thats (5Volts/2000ohms)*10 = 0.0025A or 2.5mA. Then add the V/R from the netduino's pullup and you have your final number. if that number is greater than 8mA (0.008A) the netduino can not pull the signal to ground.

ULN2004s work pretty well but they invert the signal. So you would need to run each signal through a driver twice. each output of the ULN needs a pull up resistor as well.

#11 anthrolume

anthrolume

    Member

  • Members
  • PipPip
  • 15 posts

Posted 22 April 2011 - 03:27 PM

I=V/R, so for each i2c device on the bus you need to calculate the I, so if they all have 2k pull up resistors and there are 10 of them, not including the netduino.


I only have 1 pullup resistor (for each of TWCK and TWD) for the entire buss. The devices on the buss (ThingM MinM smart LEDs) don't have their own pullup resistors - I checked the schematics for those devices.

So I think for me it's 5V/2K = 0.0025A = 2.5mA.

In the calculation you posted I think it's (5V/2K)*10 = 0.025A = 25mA, right?

ULN2004s work pretty well but they invert the signal. So you would need to run each signal through a driver twice. each output of the ULN needs a pull up resistor as well.


Thanks for the reference - will check that those out. When you say "run each signal through a driver twice" do you mean literally serialize two of them, feeding the output of one into a second ULN2004? Or should I just use an inverter before the ULN2004?

Thanks,
Bryan

#12 anthrolume

anthrolume

    Member

  • Members
  • PipPip
  • 15 posts

Posted 23 April 2011 - 04:03 PM

And those Darlington chips...they want 30V in, and 50V out?!? Maybe I'm looking at the wrong chip...

#13 CodeRage

CodeRage

    New Member

  • Members
  • Pip
  • 8 posts

Posted 23 April 2011 - 04:38 PM

And those Darlington chips...they want 30V in, and 50V out?!? Maybe I'm looking at the wrong chip...


5/2,000 = 0.0025 ;)

The 50V/30V is their maximum voltage rating on the inputs/outputs, they work in the 0-5V and 0-3.3V range.

When one of the drivers gets a +V signal on the input it will connect the output to ground. Once the input goes to an off state the driver disconnects the output from ground. Putting a pull up resistor on the output will bring the voltage up to +5 or 3V when the output is 'off'.

It's like this, if the input = on the output = off. So if you connect two drivers in series it will work like this. on->off->on, the final output will match your on signal.

I think there is an easier solution though. There is probably too much impedance on the TDW and TCK lines. Find the last led module in the i2c chain and put your scope on the TDW/TCW signals. Id bet dollars to donuts they signal has rounded edges compared to the signal right off the netduino. Put a 2.2k pull up resistor on the TDW and the TCK signals there and it should help clean things up.

#14 anthrolume

anthrolume

    Member

  • Members
  • PipPip
  • 15 posts

Posted 24 April 2011 - 02:19 AM

5/2,000 = 0.0025 ;)

The 50V/30V is their maximum voltage rating on the inputs/outputs, they work in the 0-5V and 0-3.3V range.

When one of the drivers gets a +V signal on the input it will connect the output to ground. Once the input goes to an off state the driver disconnects the output from ground. Putting a pull up resistor on the output will bring the voltage up to +5 or 3V when the output is 'off'.

It's like this, if the input = on the output = off. So if you connect two drivers in series it will work like this. on->off->on, the final output will match your on signal.


Cool. That's what I meant when I said "serialize" two of them.

I think there is an easier solution though. There is probably too much impedance on the TDW and TCK lines. Find the last led module in the i2c chain and put your scope on the TDW/TCW signals. Id bet dollars to donuts they signal has rounded edges compared to the signal right off the netduino. Put a 2.2k pull up resistor on the TDW and the TCK signals there and it should help clean things up.


This is kinda what Chris and I were trying to figure out. I have a crap scope (will be getting a better one soon), but this image from one of my previous posts showed the signal I was seeing with the Netduino and 21 LEDs on the chain, with 2.2K pullup resistors:

Posted Image

For comparison, here's the image from the Arduino, with 49 LEDs on the chain, with a 680 ohm pullup resistors:

Posted Image

For what it's worth, to me the Netduino with 21 looks at least as good as the Arduino with 49. But if I put more than 35 LEDs on the buss with the Netduino, nothing works. But the Arduino works great with all 50 LEDs on the buss, and with any pull resistance from 680 ohms all the way up to 10K.

#15 anthrolume

anthrolume

    Member

  • Members
  • PipPip
  • 15 posts

Posted 28 April 2011 - 02:48 PM

I'm still puzzled about why the same buss would work fine on the Arduino, but not on the Netduino. For what it's worth, I've ordered a new oscilloscope - the old BK was driving me nuts. I'll get better measurements of TWCK and post them when it gets here. -Bryan

#16 anthrolume

anthrolume

    Member

  • Members
  • PipPip
  • 15 posts

Posted 07 May 2011 - 04:58 AM

Hi everyone,

I got a better scope, and now I'm going to take another shot at figuring out why I can't talk to all my LEDs.

Here I've got the Netduino talking to 28 out of 50 LEDs. You can see the (not bad looking) I2C clock on the screen of the scope.

Observations: (using 820Ω pullup resistors):

  • If I attach more LEDs, the scope shows a clock on the scope for a fraction of second, then SCL goes high and stays there.
  • Even with just 28 LEDs connected, after a while (say, two minutes), the same thing happens – SCL goes high and stays there.
  • I’ve seen it get stuck low instead of getting stuck high.
  • My scope says that when the signal's low, it's not quite at ground. Not sure if that really matters.

So, given those observations (and the helpful fact that I've got a good scope at my disposal), what would be the suggested next step?

Thanks a ton,
Bryan
anthrolume

Posted Image

#17 anthrolume

anthrolume

    Member

  • Members
  • PipPip
  • 15 posts

Posted 10 May 2011 - 07:47 AM

Well nothing I've tried seems to be helping, and my meager knowledge of fundamental electronics is failing me. The biggest difference I can find between the Arduino (which works perfectly with 50 I2C devices on my buss) and the Netduino (which works with up to about 35 I2C devices on the same physical buss, but fails after that), is that an Arduino can deliver 40mA to its I2C port, and the Netduino can only do 8mA. I don't know if that's salient, but that's the biggest magnitude difference I can find.

So I ordered a couple UN2004As. I'm going to try to rig up those as external drivers and see how it goes.

I really hope I can get this to work, otherwise I'll have to abandon the Netduino for this project, and I really much prefer it.

-Bryan

#18 aalmada

aalmada

    Advanced Member

  • Members
  • PipPipPip
  • 44 posts
  • LocationPortugal

Posted 10 May 2011 - 09:24 AM

I also have been struggling with Arduino vs Netduino I2C issues. My setup is a lot simpler but check the forum thread at http://forums.netdui...ii-motion-plus/ Good luck, aalmada

#19 Dbrown

Dbrown

    New Member

  • Members
  • Pip
  • 3 posts

Posted 12 May 2011 - 02:46 PM

Hi Had a read of the thread. Not sure if this is the answer but maybe it is. You can get I2C buffer ic's like the on in this link, only £2 or £3 for the IC. Farnell stock them. http://www.nxp.com/d...heet/P82B96.pdf It might be the low drive from the netduino thats the problem. Darren

#20 anthrolume

anthrolume

    Member

  • Members
  • PipPip
  • 15 posts

Posted 16 May 2011 - 05:05 AM

Had a read of the thread. Not sure if this is the answer but maybe it is.

You can get I2C buffer ic's like the on in this link, only £2 or £3 for the IC. Farnell stock them.

http://www.nxp.com/d...heet/P82B96.pdf

It might be the low drive from the netduino thats the problem.


Thanks Darren! Those seem to have Tx and Rx outs, rather than just being straight up drivers, so I'm not sure that's what I'm looking for, but I'll go look at the application notes for that part. Thanks a ton for the pointer.

-Bryan




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.