41
\$\begingroup\$

I'm contemplating a project that would require several AVRs talking to each other over a bus. They'd be separated by as much as 6 feet.

It seems like both I2C and SPI can let a series of micros communicate over a bus, but I haven't seen anything talking about how long that would be. Has anyone tried connecting these protocols over distances of several feet?

\$\endgroup\$
1

10 Answers 10

21
\$\begingroup\$

As others have said, SPI and I2C can be used over long distances as long as the pull-up resistors, clock frequencies and so on.

The main alternatives (which will give better noise immunity) are RS485 and CAN. Both of these use differential lines in order to minimise noise issues and are better suited to this length of data transmission than I2C or SPI. However, I don't think many (any?) AVRs come with built-in CAN peripherals, which make CAN use much easier.

I would say that the most important thing to consider when picking a bus is to ensure that the protocol you use for communicating between devices includes a CRC or equivalent so that you can determine whether a message has been received correctly (CAN has this as part of the packet). Considering this, it's also useful to have an ACK/NACK type response as part of the protocol so that a corrupted message can be re-transmitted.

\$\endgroup\$
6
  • \$\begingroup\$ It sounds like either one will work. I'm mainly thinking of these two particular protocols because most of the AVRs support them natively, without adding extra components. Otherwise, RS485 or CAN would be a good choice. \$\endgroup\$
    – edebill
    Dec 28, 2009 at 20:17
  • 1
    \$\begingroup\$ If you're not restricted to through-hole packages, then ST has their cost-effective and powerful STM32 and STM8 microcontrollers with CAN, NXP have a range of LPC17xx microcontroller and there are a few others out there as well. CAN is becoming increasingly common (and affordable) on a lot of microcontrollers. \$\endgroup\$
    – DrAl
    Jan 4, 2010 at 14:48
  • 1
    \$\begingroup\$ There are indeed some AVR's with CAN receivers built in, but just like the other vendors, it's only in a limited subset of their chips. \$\endgroup\$
    – davr
    Jan 5, 2010 at 18:55
  • 2
    \$\begingroup\$ Microchip has a few PICs with CAN. microchip.com/wwwproducts/Devices.aspx?dDocName=en010302. I will admit though, they are a bit "funky" to program, especially in Microchip's C18/C30 libraries. In code review, we've observed some library code that was very difficult to read due to particulars of implementation - a transmit buffer that's used as a receive buffer, flag names that are actually the opposite of what they represent. Certainly not something I'd recommend for someone new to microcontroller development. \$\endgroup\$
    – J. Polfer
    May 18, 2010 at 12:42
  • 3
    \$\begingroup\$ CAN and RS-485 are really apples and oranges. CAN defines the bit level protocol as well as the physical electrical layer (PHY). RS-485 is just a physical layer specification, it specifies nothing about the protocol. It would be completely up to you to find or implement an actual protocol on top of the RS-485 PHY. CAN was designed for high noise environments, its mostly used in the automobile and manufacturing industries. Its protocol is a rather complex message passing system and has very high overhead (low actual data rate) but has high data integrity. \$\endgroup\$
    – Mark
    May 21, 2010 at 22:20
10
\$\begingroup\$

Several feet shouldn't be problematic, just use twisted wires if you can. SPI is much easier to buffer (if you need to) than I2C since SPI signals are all unidirectional, whereas I2C's signals are on shared lines.

can the AVR microcontrollers handle I2C and SPI slave modes as well as master modes? (you'd need both)

\$\endgroup\$
5
  • 3
    \$\begingroup\$ twisted wires?? NEVER twist the I2C data and clock lines! With SPI this is probably less of a problem, but I would never twist signal lines unless it is a balanced pair, in which case twisting is a very good idea. \$\endgroup\$ Sep 11, 2011 at 9:35
  • \$\begingroup\$ never say never; I'd take minor capacitive coupling (because of twisting) between data + clock anyday instead of minor inductive coupling to noisy power electronics (because of not twisting) \$\endgroup\$
    – Jason S
    Sep 12, 2011 at 19:17
  • 4
    \$\begingroup\$ Sorry, I most definitely disagree. In the 1 state the lines have a rather high impedance. Seen it done, seen it fail. Best option is to have low-current ground lines between or even better on both sides of the I2C lines. \$\endgroup\$ Sep 12, 2011 at 20:15
  • 1
    \$\begingroup\$ @JasonS -- For a twisted pair to work, the signal being sent has to be mirrored in the return wire so the magnetic fields cancel each other, rendering the pair non-inductive. And that is also what cancels out the EMI, the fact that it is a differential pair, probably pictured well as being directly connected to an Op-Amp to receive the signal. I agree with Wouter van Ooijen, that you should NEVER twist the I2C data and clock lines! \$\endgroup\$ Aug 2, 2021 at 2:00
  • \$\begingroup\$ not sure I agree; I'd twist the entire set (SCL + SDA + GND) together. \$\endgroup\$
    – Jason S
    Aug 4, 2021 at 18:26
10
\$\begingroup\$

For I2C over long distances you might want to seek out some "I2C bus repeater" solutions. Keep in mind that any maximum distance you might find for I2C or SPI communication is mostly referring to the total bus distance and not the to distance between two nodes in a bus.

You might want to look into RS485 for these kinds of problems. It's a serial bus protocol which communicates over differential lines, so when using twisted wires, the chances of noise are minimized. Very long distances can be reached this way. The downside would be that you would need an extra RS485 encoder IC (like a MAX485 ,not very expensive) in your circuit.

\$\endgroup\$
3
  • \$\begingroup\$ RS485 is definitely a good way to go for such a thing. \$\endgroup\$ Dec 28, 2009 at 3:42
  • \$\begingroup\$ keep in mind that RS485 has two aspects different than RS232 that are somewhat independent: the physical differential logic levels, and the multimaster aspect. You can pick + choose these, we've used both LVDS and RS485 translators with UART (RS232) for point-to-point w/o getting into the multidrop parts of RS485. \$\endgroup\$
    – Jason S
    Dec 29, 2009 at 1:07
  • 2
    \$\begingroup\$ btw RS485 is not a protocol! it defines the physical layer only. Having said that, you can definitely use SPI over RS485!!! It would be a neat solution to keep the communications in SPI mode if needed ( I am assuming it is, might be connected to a remote ADC or similar). Using SPI over RS485 you will need to check the transceiver slew rates are compatible with the proposed SPI datarates \$\endgroup\$ Nov 27, 2010 at 20:13
9
\$\begingroup\$

Just an FYI, the interface between the wireless Nintendo Wii remote and its Nunchuck companion uses I2C over a cable that is about 3 feet long. There are also 3-foot extensions cables that extend the total length to about 6 feet. Not exactly the same as your setup (only two devices connected together), but it is an example of I2C over a cable in a widely-used consumer product.

\$\endgroup\$
8
\$\begingroup\$

One advantage not yet mentioned of SPI over I2C is that all SPI wires are unidirectional and are always driven high or low. This allows much faster communication than is possible with I2C, reduces susceptibility to noise, and allows simple gates to be used as repeaters. Another useful option is simple async communication (one wire each direction). The only downside I can see to async communication is that it generally requires both sides to be "awake", with a stable clock, to exchange data.

For a project of my own, I used a 3-wire slightly-modified SPI protocol and have found the results satisfactory. I send display bitmap data (where occasional data corruption would be no big deal) at 10mbps and other data at 2.5mbps without difficulty.

\$\endgroup\$
2
  • \$\begingroup\$ This is a very old answer, but would you say over what distance you were sending your modified SPI protocol? (That's the point of the question...) \$\endgroup\$ Apr 5, 2019 at 12:39
  • 1
    \$\begingroup\$ @DanielGriscom: About 3 feet typically, over not-terribly-impressive cabling, but sometimes longer. \$\endgroup\$
    – supercat
    Apr 5, 2019 at 16:55
6
\$\begingroup\$

While both I2C and SPI are designed for short-distance hauls (a few inches), both can be utilized on longer hauls with proper cable and attention to overall bus capacitance.

While I have little experience with SPI, I2C isn't terribly difficult given that you always need to calculate the proper size for your pull-up resistor. Additionally, there are dedicated, and inexpensive I2C buffers that are quite easy to use. However, you will still have to use a properly-sized pull-up resistor for your network.

I have used I2C to network between two AVRs at a distance of 8 feet, using only pull-up resistors and high-quality, well-shielded, twisted cable.

\$\endgroup\$
1
  • \$\begingroup\$ you have to watch out w/ I2C with multiconductor cables, the capacitance can cause the bus to slow down significantly. \$\endgroup\$
    – Jason S
    Dec 27, 2009 at 23:49
6
\$\begingroup\$

As many have suggested, I2C and SPI are best used for short distances. While it may be possible to implement a solution with these interfaces, I would higly recommend that you look for a different, "more standard" solution (e.g. Ethernet, RS485, CAN, etc). -- Especially if you're planning to use cables to reach the 6ft distance between microcontrollers.

\$\endgroup\$
4
\$\begingroup\$

I worked on a project involving about 80 AVR-based nodes in a star network communicating over I2C. It was a total mess and didn't work in the end. Getting updates to all the nodes took seconds and one faulty connection would throw off the whole network. Last I spoke to the guy who made the nodes, he said he's stopped using I2C for projects like this. Unfortunately I don't know why specifically I2C was inadequate here.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ I2C is much slower than SPI... it could also have been in how your project managed arbitration in case of collisions... or the capacitance may have been high enough with all those nodes that you just had to use a slow clock rate. \$\endgroup\$
    – Jason S
    Dec 29, 2009 at 1:04
2
\$\begingroup\$

It should be easy with that short distances. What you could do is figure out what those distances and your cabling means in terms of capacitance and line impedance and see what kind of frequencies (rise/fall times) you can get through them. Beyond certain point, it's best to treat them as transmission lines. If it looks bad, you could indeed switch to some other serial line like EIA-232 or 422. That might mean an extra chip at both ends but will stretch far. If you really need to go fast and far, you'll need something more (ethernet, don't count out radio or laser :).

\$\endgroup\$
2
\$\begingroup\$

If you can control the clock speed and you don't need high-speed data transfer, you should try to slow the clock down. This will make it less susceptible to noise.

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.