Jump to content

Does anyone here have experience using I2C with Arduino?


G+_John Sullivan
 Share

Recommended Posts

Does anyone here have experience using I2C with Arduino? I can get it to work between two Arduino UNOs, but not between on UNO and anything else (NANO clone, MIcro clone, etc.)

Have even bought a genuine Arduino Micro from an approved Arduino distributor, but it also does not work.

Link to comment
Share on other sites

Jim Hofmann Hello Jim. Yes, I read that tutorial back when I was researching this stuff. I already have it working (as I mentioned), it's just that I can only get it working with two UNOs, not one UNO and something else.

Wiring is correct according to the pinout diagrams I have found at arduino.cc and other places. Address is the same whether a UNO as slave sender or something else.

Am using the two examples provided with the Arduino IDE (Master Reader and Slave Sender).

Thanks

Link to comment
Share on other sites

You haven't specified what "doesn't work" is, so all we can do is give some general advice.

 

Lots of places for things to fail. I2C is a relatively complicated protocol compared to the other simple protocols like UART or SPI.

 

For example, does the slave ACK its address? Does the slave respond with valid data (instead of 0xff's)? Have you accounted for the bus idle time BEFORE starting a transaction, and between each subsequent transaction? Are you getting communication errors? Are you losing bus arbitration? When you look at the bus with an oscilloscope, are any of the bits weird and mis-shapen?

 

For I2C there are a quite few concerns:

 

1. Bus master: One is a master and one is a slave. Master controls the bus and whether the transaction is read or write. I'm going to assume you have this right since you said you read the tutorials.

 

2. Speed: You need to pick a speed that both can talk at. Typical speeds are 100 Kbps, 400 Kbps, 1 Mbps and up. You should double check timing configuration using an oscilloscope.

 

3. Slave address: The slave address obviously has to be correct for the slave to recognize its address and respond. This might seem obvious, but there doesn't seem to be an industry standard on how to designate the address. Some include the read/write bit when specifying the address, some do not. If the slave doesn't ACK, you can try doing a left or right shift to what you think the address is to see if it gets better.

 

4. Setup and Hold times: Both the master and slave need to have their setup/hold times met for the transaction. You should refer to the datasheets and double check with an oscilloscope. If you aren't meeting timing, then the bus capacitance is too large. You can compensate by making the pullups stiffer (lower resistance) at the cost of power. However, there is a limit to how far you can go. Both parties need to be able to sink the current based on the pullups you choose. Make the resistors too low, and you will damage the pins. Of course, the safer route would be to just slow down!

 

5. Bus idle time: After configuring the peripheral for I2C, you need to wait for the bus idle time (its based on your comm speed, see the datasheet). This is a common oversight. You also need to wait for the bus idle time in between transactions. Otherwise, either master or slave might not properly identify a start bit, and could get desynchronized.

 

6. Desynchronization: It is possible that the master and slave might become desynchronized (they disagree on what clock they are on). You will observe this if the slave asserts the data pin when you are trying to use it. In this case, the master should keep toggling the clock until the slave releases the data pin.

 

That's all I could think of off the top of my head.

 

In summary, check the address is getting acknowledged, try slowing down, and check the bus with an oscilloscope.

 

Good luck! :)

Link to comment
Share on other sites

Jeff Gros Hi Jeff. Thanks for trying to help, but most of what you said is beyond my ability.

As for what "doesn't work", I guess that was aimed at persons who use I2C with Arduino, as they would know that the Arduino IDE has "examples" which include a Master Reader and a Slave Sender. Uploading one to one UNO and the other to the other UNO "works" (meaning that the Slave sends "hello " repeatedly and the Master reads it and prints it to the Serial Monitor.

Loading the Slave Sender code to any of the other devices that I have tried ( a few clone Arduino Micros, and lately, to a genuine Arduino Micro) does not print anything to the Serial Monitor.

Things you mentioned like proper Address, bus speed, etc. are all handled by the two code examples.

One thing I have found from searching is that the Slave may not be assembling it's response quickly enough before the Master times-out. I will look into that some more. Also, it occurred to me this morning that, although I have wired the SDA and SCL pins as shown in the pinout diagrams, some of the devices I'm using may still need that defined in code.

ps. I do have an oscilloscope (a Rigol 100 Mhz), but don't know enough about how to use it yet.

Link to comment
Share on other sites

"Also, it occurred to me this morning that, although I have wired the SDA and SCL pins as shown in the pinout diagrams, some of the devices I'm using may still need that defined in code."

 

That sounds like the hot ticket. Cannot tell you how many times I've written code to talk some protocol, and forgot to change the pins to peripheral mode.

 

If not, then spend some time learning how to use your scope. I have a Rigol DS1204B, and I'm pretty sure it came with a manual (somewhere around here!). Yours should too. I'd prefer the trusty Techtronix I use at work, but at the time I bought the Rigol a used Techtronix cost double what a new Rigol did!

 

I'm not much help as afar as Arduino is concerned. I've never used it. However, I know microcontrollers. And I know enough about Arduino to know that it's just a fancy library on an Atmel architecture (now owned by Microchip) microcontrollers.

Link to comment
Share on other sites

Jeff Gros Powered it up today and it runs fine. Replaced the genuine Arduino Micro with a clone Micro and it also works just fine. (meaning it sends "hello " to the UNO over the I2C bus, and the UNO prints it in the Serial Monitor, as per the sample Examples.

Have no idea why it didn't work for three days, but now it does.

Magic I guess.

Link to comment
Share on other sites

Might be desynchronization. Once you get it in that state, you either have to fix it in software. Or power down everything and power back up. Not sure what else it could be. All the other issues I mentioned are either there or not. Not intermittent.

 

Unless your system setup is different and you are now meeting setup/hold times that you were failing before, it's probably desynchronization. Which means the code isn't exactly robust.

 

Only a guess though. Glad you got it working! :)

Link to comment
Share on other sites

Final piece of the puzzle: the clones that I bought are labeled "Nano" but are actually Pro Minis. Took a lot of Googling to find that tip!

Once I changed the Arduino IDE to communicate with them as Pro Minis the code uploaded and worked correctly.

Next step is to see how to make them communicate over 50' of cable. There are tutorials on using transistor-based amplifiers and shielded cable, so will be trying that out.

Link to comment
Share on other sites

 Share

×
×
  • Create New...