Electronic – Low cost simple communication between two microcontrollers

communicationmicrocontrollerserialserial-bus

What tradeoffs and connection options are there in low cost bidirectional communication between just two microcontrollers?

In this case:

  • Master/Slave relationship, bidirectional data flow
  • Distance under an inch
  • Slave plugs into the master (so ESD protection on the connections is a must).
  • The slave micro is pretty dumb, but medium speed data is needed for block I/O from a SD card. Other than the SD card, there is a bit of low speed I/O on the slave unit where speed is not an issue.
  • Cheap cheap cheap.
  • Pin count is restricted.
  • Prefer minimum protocol stack overhead.

Obvious options include SPI, CAN, USB, TTL Level Serial. I2C and 1-Wire are probably too slow. Because of the pin count issue modulating the power supply for data would be ideal, if there were a consumer level chipset that did it, saving two pins over the serial methods.

Best Answer

Given your available options, it appears that you do have some pins available:

  • SPI is full-duplex and requires 1 clock + 1 data each direction + 1 optional chip select = 3 pins
  • CAN is half-duplex and requires 2 data for bidirectional comms = 2 pins
  • USB is half-duplex and requires 2 data for bidirectional comms = 2 pins
  • TTL Serial is anything you want, but most people use a UART for it, requires 1 data each direction = 2 pins full duplex or 1 pin with some trickery
  • UART is full-duplex and requires 1 data each direction = 2 pins or 1 pin with some trickery
  • I2C is half-duplex and requires 1 clock + 1 data = 2 pins

So it looks like the consensus is 2 pins if you want bidirectional communication, or possibly 3 for SPI. Given equal pin counts, I'd go for the UART if there's one available on both chips. Assuming a 1:1 connection, you can just toss data across without regard for timing or collisions, and the hardware is really easy.

As for the stack overhead, there are many different protocols that can operate from a UART, but it's probably best in this case to define your own. From the comms' perspective, you're just spewing out bytes and receiving them at the other end. The hardware will sync itself to each byte automatically, but you still have to know which byte is what. You'll have that problem regardless of which option you choose.

If you're clever with a UART (and I'm about to give you the answer), you can connect the two TX pins together with two resistors in series, then have a comparator on each end that drives the RX pin based on the local TX and the center tap of the two resistors. This allows full-duplex on one wire. See below for a schematic.

For ESD, add a series resistor inside both cases for each pin and put some clamping diodes on the outboard side of the resistor. There are diodes specially made for this.


schematic

simulate this circuit – Schematic created using CircuitLab

  • The "low" resistors are to protect the ESD diodes. Datasheets may or may not claim that they're unnecessary, but I'd use them anyway. Make them just big enough to do their job; they need to look like a short compared to the "high" resistors.
  • The "high" resistors are to mix the two TX signals on the common wire.
  • The 10k and 5k resistors are to take the full-supply-range TX signal and provide the appropriate threshold for the comparators.
  • If the two devices are powered independently, you probably shouldn't have the "Optional Connection", leaving you with 2 wires instead of 3. I don't see how you can communicate at all with fewer pins than this, unless you go wireless.

Here's how it works:

  • If both TX's are high, the common line will be high and both comparators will output high.
  • If both TX's are low, the common line will be low and both comparators will output low.
  • If one TX is high and the other low, the common line will be mid-range and each comparator will have a different threshold based on its local TX. So the one with a high TX will have a higher threshold than the mid-range common and will output low, and the one with a low TX will have a lower threshold than the mid-range common and will output high.

So in all cases, the receiving comparator output equals the sending TX.

If you don't like the hardware complexity inside the box, then you can use a discrete pin for each direction and keep only the "high" and "low" resistors and ESD diodes - a separate copy for each pin.