I'm building a hobby 6-DOF robotic arm and am wondering what the best way is to communicate between the processors (3-4 AVRs, 18 inches max separation). I'd like to have the control loop run on the computer, which sends commands to the microprocessors via an Atmega32u4 USB-to-??? bridge.

Some ideas I'm considering:

  1. RS485
    • Pros: all processors on same wire, differential signal more robust
    • Cons: requires additional chips, need to write (or find?) protocol to prevent processors from transmitting at the same time
  2. UART loop (ie, TX of one processor is connected to RX of next)
    • Pros: simple firmware, processors have UART built in
    • Cons: last connection has to travel length of robot, each processor has to spend cycles retransmitting messages
  3. CANbus (I know very little about this)

My main considerations are hardware and firmware complexity, performance, and price (I can't buy an expensive out-of-box system).


3 Answers 3


You want to use USB for communications with the computer. If you have a number of microcontrollers, you will probably only connect one of the microcontrollers directly to the computer. The other microcontrollers will need to get their commands from the main microcontroller.

The communication you choose will depend on a number of factors:

  • required bandwidth (we will assume you are running them at 16MHz)
  • complexity (wiring and coding)
  • bi-directional, or master-slave

Almost all options have built-in support on the AVR microcontroller. There is no option you might reasonably prefer over the built-in options which would require additional hardware. Because they have built-in support, the software complexity is all similar, in that you just configure the port (using registers), put the data to transmit in another register, then trigger the transmission by setting a bit in another register. Any data received is found in another register, and an interrupt is triggered so you can handle it. Whichever option you choose, the only difference is the change in register locations, and some changes to the configuration registers.

A USART loop has the following features:

  • Maximum baud rate of CLK/16 = 1MHz (at 16MHz clock) which is a transfer rate of around 90KB/s
  • fully bi-directional communications (no master or slave designation)
  • requires separate wires between each pair of microcontrollers - the Atmega32u4 supports two USART ports natively, limiting the number of microcontrollers you can connect in a network in practice (or else you end up with a long string of microcontrollers - ie. connected in a linked list manner)

Note: this is also what you would use to get RS232 communication, except that because RS232 requires 10V, it requires a driver to get those voltage levels. For communication between microcontrollers, this is not useful (only voltage levels are changed).


  • Essentially, you use the USART port in a different mode - there is no advantage in bandwidth, and it may only simplify the wiring slightly, but it also complicates it. This is not recommended.

Two-wire interface:

  • This is also referred to as I2C. This means that all devices share the same two wires.

  • You need a pull-up resistor on both wires

  • It is slow (because the pull-up resistors are limited in value, and there is increasing capacitance as the number of devices increases, and the wire length increases). For this AVR microcontroller, the speed is up to 400 kHz - slower than USART (but this speed depends on limiting your capacitance). The reason is that although a device drives the data wire low, the opposite transition is accomplished by letting the wire float high again (the pull-up resistor).

  • It is even slower when you consider that ALL communication shares the same limited bandwidth. Because all communication shares the same limited bandwidth, there may be delays in communication where data must wait until the network is idle before it can be sent. If other data is constantly being sent, it may also block the data from ever being sent.

  • It does rely on a master-slave protocol, where a master addresses a slave, then sends a command/request, and the slave replies afterwards. Only one device can communicate at a time, so the slave must wait for the master to finish.

  • Any device can act as both a master and/or a slave, making it quite flexible.


  • This is what I would recommend/use for general communication between microcontrollers.

  • It is high speed - up to CLK/2 = 8MHz (for CLK at 16MHz), making it the fastest method. This is achievable because of its separate wire solely for the clock.

  • The MOSI, MISO data, and SCK clock wires are shared across the whole network, which means it has simpler wiring.

  • It is a master-slave format, but any device can be a master and/or slave. However, because of the slave select complications, for shared wiring (within the network), you should only use it in a hierarchical manner (unlike the two-wire interface). IE. if you organise all devices into a tree, a device should only be master to its children, and only a slave to its parent. That means that in slave mode, a device will always have the same master. Also, to do this correctly, you need to add resistors to MISO/MOSI/SCK to the upstream master, so that if the device is communicating downstream (when not selected as a slave), the communications will not affect communications in other parts of the network (note the number of levels you can do this using resistors is limited, see below for better solution using both SPI ports).

    The AVR microcontroller can automatically tri-state the MOSI signal when it is slave-selected, and switch to slave mode (if in master).

    Even though it might require a hierarchical network, most networks can be organised in a tree-like manner, so it is usually not an important limitation

  • The above can be relaxed slightly, because each AVR microcontroller supports two separate SPI ports, so each device can have different positions in two different networks.

    Having said this, if you need many levels in your tree/hierarchy (more than 2), the above solution using resistors gets too fiddly to work. In this case, you should change the SPI network between each layer of the tree. This means each device will connect to its children on one SPI network, and its parent on the other SPI network. Although it means you only have a single tree of connections, the advantage is that a device can communicate with both one of its children and its parent at the same time and you don't have fiddly resistors (always hard to choose the right values).

  • Because it has separate MOSI and MISO wires, both the master and slave can communicate at the same time, giving it a potential factor of two increase in speed. A extra pin is required for the slave-select for each additional slave, but this is not a big burden, even 10 different slaves requires only 10 extra pins, which can be easily accommodated on a typical AVR microcontroller.

CAN is not supported by the AVR microcontroller you have specified. As there are other good options, it is probably not important in this case anyways.

The recommendation is SPI, because it is fast, the wiring isn't too complex, and doesn't require fiddly pull-up resistors. In the rare case where SPI doesn't fully meet your needs (probably in more complicated networks), you can use multiple options (eg. use both SPI ports, along with the two-wire interface, as well as pairing some of the microcontrollers using a USART loop!)

In your case, using SPI means that naturally, the microcontroller with the USB connection to the computer can be the master, and it can just forward the relevant commands from the computer to each slave device. It can also read the updates/measurements from each slave and send these to the computer.

At 8MHz, and 0.5m wire length, I don't think it will become a problem. But if it is, try be more careful of capacitance (keep ground and signal wires getting too close, and also be careful of connections between different conductors), and also signal termination. In the unlikely event that it remains a problem, you can reduce the clock rate, but I don't think it is necessary.

  • $\begingroup$ Thumbs up for SPI from me $\endgroup$ Commented Dec 29, 2012 at 23:50
  • 2
    $\begingroup$ I'm a fan of SPI too, although perhaps I2C is also worth considering (avoids the need of seperate CS lines to each device). But CAN should not be so easily dismissed - after all, it is the automotive bus of choice, so I'd not rule it out for hobby robotics! $\endgroup$
    – Andrew
    Commented Dec 30, 2012 at 10:24
  • $\begingroup$ Does the SPI bus really require separate CS lines from the master to each slave? If so, what would you call that other bus that requires exactly 4 connections to the master, no matter how many slaves are connected, that is mentioned in the Wikipedia article on SPI bus? $\endgroup$
    – David Cary
    Commented Dec 30, 2012 at 13:15
  • 1
    $\begingroup$ +1 For the huge response, I'm old school and I love the 485 and generally buses with software address, but in this case, speed and resource consumption components, I would choose the SPI. Although you would have much attention to distance and electrical noise, especially if your bus coesisten other IC, with different transmission speed: memories, NIC, etc., which could suffer brownouts and clock loss amplitude $\endgroup$
    – RTOSkit
    Commented Dec 30, 2012 at 23:20
  • 3
    $\begingroup$ Your comments on CAN are not accurate. CAN is not just any 2-wire bus. I think you are confusing it with I2C, which has a top speed of 400kbps. CAN's top speed is 1Mbps. $\endgroup$ Commented Jan 2, 2013 at 12:50

I can highly recommend CAN for inter processor communications. We use it in our robots, with up to 22 processors on the same bus. With good protocol design, you can use up about 90% of the available bandwidth (about 640kbps when you take into account all of the error checking and inter frame spacing). We're able to servo 10 motors at 1000Hz on one CAN bus. This is approaching the limit. You could probably squeeze it to 20 motors if you pack the data very carefully.

Generally CAN needs to have one transceiver chip for each processor (it's just a little 8-pin device). The transceiver gives you the nice differential signal which emits very little interference, and also makes it immune to interference if you're working in an electrically noisy environment (motors, solenoids, and radio transmitters).

CAN Bus connections

However, in limited circumstances, it's actually possible to use CAN with no transceivers.


If you ever feel like implementing a bus with serious bandwidth, I suggest you try EtherCAT. It's a 100Mb bus, which can be connected to your PC's Ethernet port. There are two important parts to the bus:

  • The Bridge. This converts the Ethernet physical layer to a simpler, lower cost LVDS physical layer, which doesn't require the large connectors, Phy chip, and many components that Ethernet itself does.
  • The nodes. Each node just needs one ET1200 chip and a microcontroller.

The PC can transmit and receive large chunks of data to and from the nodes at 1kHz or faster. You can control quite a lot of stuff on a single EtherCAT bus.


Shadow Robot Company now sell a useful EtherCAT Bus system called Ronex. It lets you add quite a lot of I/O, and they're going to be introducing lots of other types of board soon, like motor controllers, and high quality ADCs.

  • $\begingroup$ What's the source for that image? It has CAN High for both red and blue wires. $\endgroup$
    – Ian
    Commented Oct 31, 2013 at 16:31

I know I'm digging up an old thread and this is sort of off topic, but I don't think you can just get hold of ET1200 chips from Beckhoff. I emailed them a little while back and was advised that I need to join the Ethercat group. To do this I had to demonstrate that I was going to contribute back to the group - ie, by building and selling devices that used the Ethercat stuff. At that (and this) point in time, I am still prototyping my device (a brushless motor controller for robot applications - currently using CAN) so I could not offer anything (I cannot give a solid time for completion - Im still working on my undergrad). I expressed to them my disappointment. They said not to be disappointed!! Pretty funny stuff! I would really like to get into Ethercat, but the ASICs seem to be untouchable to hobbyists or those without a company. Also, this is my first post, so apologies if I have angered the gods by digging up an old post!

  • $\begingroup$ Welcome. Resurrecting an old post is fine, if the answer is relevant. And your comment seems relevant to me... $\endgroup$
    – Andrew
    Commented Nov 11, 2013 at 19:40
  • $\begingroup$ Thanks mate. This is a great forum! Out of interest, do you have any experience with Ethercat? Do you happen to know any other methods of getting a slave device suitable for prototyping on PCBs? I am willing to pay, but at the moment I simply don't meet the requirements to join the group to buy the Bechoff ASICs. Frustrating! $\endgroup$
    – law
    Commented Nov 13, 2013 at 6:32
  • $\begingroup$ Not EtherCat, no. I use CAN (a good option), LIN (not so good IMHO) and can certainly recommend SPI or I2C $\endgroup$
    – Andrew
    Commented Nov 13, 2013 at 7:05
  • $\begingroup$ Did you manage to get a hold to the ET1100 or ET1200 chip? If you didnt there is another option available now: microchip LAN9252, it is compatible with the ET1100 and works pretty well. Use the SOES library regards $\endgroup$
    – user14818
    Commented Sep 23, 2016 at 22:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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