Electronic – Communication between multiple microcontrollers


I'd like to start implementing a system consisting of N microcontrollers (N >= 2 MCUs), but I would like to know the possibilities to let them communicate one with the other.

Ideally, (N-1) microcontrollers are placed inside the house acting as clients, while the last (the "server") one is connected to a PC via USB. The problems I have right now is how to connect these (N-1) microcontrollers to the "server". The clients MCUs perform very simple tasks, so it may not be a good solution to use ARMs to do such simple jobs just because they provide CAN / PHY-MAC.

The communication will not happen more than once every few minutes for most of the devices and on demand for others. The speed is not very critical (message is short): 1 Mbit/s I think is WAY overkill for my purposes.

The MCUs I plan on using are the following.

  • Atmel AVR Tiny / Mega
  • TI MSP430
  • ARM Cortex M3/M4
  • (Possibly Atmel AVR UC3 – 32-bit)

I'd like to avoid PICs if possible (personal choice), simply because there are less possibilities to program them (all the above have more or less open source tools as well as some official tools).

I know some ARMs provide CAN functionality and am not so sure about the others.

Right now I came up with these possibilities:

  1. Simple GPIO to send data (say > 16 bits at HIGH to indicate start of message, > 16 bits at LOW to indicate end of message). However it has to be at a standard frequency << (frequency_client, frequency_server) to be able to detect all bits. Only need one cable per client MCU.
  2. RS-232: I think this is by far the most commonly used communication protocol, but I don't know how well it scales. I'm considering up to 64 client MCUs right now (probably more later)
  3. USB: AFAIK this is mostly like RS-232, but I don't think it scales very well in this case (though USB supports lots of devices – 255 if I remember correctly – it may be overly complicated for this application)
  4. RJ45 / Ethernet: this is what I'd really love to use, because it allows transmission over long distances without a problem (at least with shielded >Cat 6 cable). The problem is the cost (PHY, MAC, transformer, …). I don't know if you can actually solder it well at home though. This way I wouldn't need a client MCU
  5. Wireless / ZigBee: modules are very expensive, though it may be the way to go in order to avoid "spaghetti" behind the desk
  6. RF modules / transceivers: I'm speaking of those in the 300 MHz – 1 GHz band, so they should be difficult to solder at home. The modules are all built-in, but they are quite as expensive as the ZigBee (at least the RF's modules at Mouser, at Sparkfun there seem to be cheaper ones).
  7. CAN? It seems to be very robust. Even though I don't plan to use it in automotive applications, it may still be a good alternative.
  8. I²C / SPI / UART? Again – better avoid "spaghetti" with the cables if possible
  9. PLCs are not really an option. Performance degrade pretty fast as the length increases and depends on the capacitance load of the power network. I think price-wise is about the same as Ethernet.

Furthermore, which protocol would be "better" in case of simultaneous transmissions (let's assume the rare case that at the very same instant two devices begin transmitting: which protocol provides the best "conflict management system" / "collision management system"?

To sum it up: I'd like to hear what may be the best solution for a distributed client system that do very light data communication, considering both flexibility (max number of devices, conflict / collision management system, …), price, easy to make at home (soldering), … I'd like to avoid spending 20$ on just the communication module, but at the same time having 30 wires behind the desk would suck.

The solution I'm imaging right now would be to do basic communication between near MCUs by GPIO or RS-232 (cheap!) and use Ethernet / ZigBee / Wi-Fi on one MCU per "zone" to communicate with the server (expensive, but it is still a lot cheaper than one Ethernet module per each client MCU).

Instead of cables it may as well be possible to use fiber optic / optical fibers. Though additional conversions are necessary, and I'm not sure if it'd be the best solution in this case. I'd like to hear additional details on them.

Best Answer

CAN sounds the most applicable in this case. The distances inside a house can be handled by CAN at 500 kbits/s, which sounds like plenty of bandwidth for your needs. The last node can be a off the shelf USB to CAN interface. That allows software in the computer to send CAN messages and see all the messages on the bus. The rest is software if you want to present this to the outside world as a TCP server or something.

CAN is the only communications means you mentioned that is actually a bus, except for rolling your own with I/O lines. All the others are point to point, including ethernet. Ethernet can be made to logically look like a bus with switches, but individual connections are still point to point and getting the logical bus topology will be expensive. The firmware overhead on each processor is also considerably more than CAN.

The nice part about CAN is that the lowest few protocol layers are handled in the hardware. For example, multiple nodes can try to transmit at the same time, but the hardware takes care of detecting and dealing with collisions. The hardware takes care of sending and receiving whole packets, including CRC checksum generation and validation.

Your reasons for avoiding PICs don't make any sense. There are many designs for programmers out there for building your own. One is my LProg, with the schematic available from the bottom of that page. However, building your own won't be cost effective unless you value your time at pennies/hour. It's also about more than just the programmer. You'll need something that aids with debugging. The Microchip PicKit 2 or 3 are very low cost programmers and debuggers. Although I have no personal experience with them, I hear of others using them routinely.


I see some recommendations for RS-485, but that is not a good idea compared to CAN. RS-485 is a electrical-only standard. It is a differential bus, so does allow for multiple nodes and has good noise immunity. However, CAN has all that too, plus a lot more. CAN is also usually implemented as a differential bus. Some argue that RS-485 is simple to interface to electrically. This is true, but so is CAN. Either way a single chip does it. In the case of CAN, the MCP2551 is a good example.

So CAN and RS-485 have pretty much the same advantages electrically. The big advantage of CAN is above that layer. With RS-485 there is nothing above that layer. You are on your own. It is possible to design a protocol that deals with bus arbitration, packet verification, timeouts, retries, etc, but to actually get this right is a lot more tricky than most people realize.

The CAN protocol defines packets, checksums, collision handling, retries, etc. Not only is it already there and thought out and tested, but the really big advantage is that it is implemented directly in silicon on many microcontrollers. The firmware interfaces to the CAN peripheral at the level of sending and receiving packets. For sending, the hardware does the colllision detection, backoff, retry, and CRC checksum generation. For receiving, it does the packet detection, clock skew adjusting, and CRC checksum validation. Yes the CAN peripheral will take more firmware to drive than a UART such as is often used with RS-485, but it takes a lot less code overall since the silicon handles so much of the low level protocol details.

In short, RS-485 is from a bygone era and makes little sense for new systems today. The main issue seems to be people who used RS-485 in the past clinging to it and thinking CAN is "complicated" somehow. The low levels of CAN are complicated, but so is any competent RS-485 implementation. Note that several well known protocols based on RS-485 have been replaced by newer versions based on CAN. NMEA2000 is one example of such a newer CAN-based standard. There is another automotive standard J-J1708 (based on RS-485) that is pretty much obsolete now with the CAN-based OBD-II and J-1939.