What is the general protocol to send information from one system to another? For example, let's say we have some information collected from microcontroller over a length of time that we want to send to another microcontroller. I've heard of SPI and I2C interfaces, but I am unclear when you use one method over another and how you implement it. Are there other methods besides SPI and I2C that are common? Is the implementation process similar for different microcontrollers? Is it basically parsing bytes of data that I am doing on the receiving microcontroller?
SPI and I2C are kind of similar, in that they're really used more for attaching peripheral devices to a controller or cpu, than for actually transferring data between systems. USB is another interface that people seem to want to treat as a communication system, which is in fact a peripheral attachment bus.
Communication between systems isn't exactly like attaching a device to a bus. Bus attachment allows the processor to directly bang on registers in a device, whereas a communication interface allows you to send/receive streams of data. A device connected on a bus generally needs a device driver, whereas with communications, it really doesn't matter what is connected on the other end, as far as the host computer is concerned.
Of course, this is getting to be a hazier boundary all the time. Things like PCI and ISA are indisputably buses; I2C, SPI, USB are arguably buses; whereas RS232, RS485, and ethernet are definitely communications interfaces. But then there are things like CAN bus and 1553, which are definitely about moving data around, but in a very involved kind of way.
There is no one way to send data, there are many different ways to communicate depending on the distance, the data rate, the environment, the application ...
The lowest layer is the physical layer, which actually moves the bits around.
SPI and I²C are for short distances inside a device, where there is not much noise that could disturb the transmission.
For not too fast communication over distances up to some tens of meters serial communication via RS-232 is a good choice.
If there is more noise or longer distance differential signals are used, for example in RS-485. For faster data transmission there is Ethernet, which is becoming more and more popular.
Then there are also various wireless standards.
On top of the physical layer there are more layers organizing how the data is sent, for detecting and correcting errors in transmission, routing in a network, and many other things. For example, the internet protocol is a rather complex stack of several layers, typically on top of the Ethernet protocol.
A simple serial UART can be used (one Tx and one Rx line with no discrete clock) and can be easily adapted to cross between different potentials (even primary and secondary circuits) with optoisolators or magnetic isolators.
As far as protocols go, anything with defined command bytes and some sort of checksum scheme will work well. There really isn't a cover-all standard protocol that suits all types of communications. I2C has a signalling standards (defining addressing, stops, starts, etc.) but the protocol of what's actually being communicated is solely up to the developer.
PMBus, for example, is a power supply communication protocol that uses I2C as its physical medium.
There really isn't a "general" protocol, what you end up using depends highly on the application. In order for us to give you a better answer, we need to understand your requirements a little better. You mention that you would like to have separate micro-controllers talking to each other as subsystems.
Some questions about this application:
- Will there be more than 2 micro-controllers in this project?
- What are your speed and throughput requirements? How fast does the information need get there and how often are you sending/receiving data?
If you answered NO to question 1:
If there are only 2 micrco-controllers in this project, you can definitely use UART between them. If they both need to initiate communication, use flow control, otherwise it should be trivial to send data in one direction. For the most part it should be "fast enough" given that you select one of the higher baud rates. I2C and SPI are typically only good for master/slave architecture.
If you answered YES (more than 2 controllers) to question 1:
- If there are more than 2 micro-controllers in your project, which one initiates communications? Will it only be one master controller (ie master-slave architecture)? Or would any of the subsystems be able to speak at any time?
- Is there a need for any of the subsystems to talk to each other? eg: for devices A, B and C: A can send to B and C, and B can send to both A and C, etc.
So now you need something more scalable where you can drop addressable devices onto a common bus. The answer to these follow up questions will help you decide between I2C and SPI (master-slave) or something like CAN (multi-master).
Your micro-controller most likely has a UART peripheral, the others (especially CAN) may only be available on more higher end chips. In either case, there should be plenty of documentation on how to use these peripherals to move bytes around.
As @Jon noted, one issue in selecting a communications interface is whether one entity will always be responsible for initiating communications, or whether more than one entity may be so responsible. A related matter is whether one entity will always be ready to receive unsolicited communications. SPI is frequently used in applications where one side will always be ready to receive communication. Something like a 74HC595 shift register, for example, is never "busy". While SPI is good for communication between a microcontroller and hardware which the micro is supposed to control, it is really not good for communication between two microcontrollers. When two processors with I2C hardware are using it to communicate, software can take as long as it wants (within very generous constraints) to deal with what's going on, without causing data loss. If a processor were to take a 100 microseconds to process each incoming byte, that would severely limit throughput, but the sender would slow down enough for the receiver to keep up. The only way that can generally happen with SPI is if one has a separate wire for handshaking.
I2C is really a wonderful protocol. The biggest limitations that stop it from being the most perfect protocol imaginable are
- Its speed is somewhat limited; SPI can go much faster, and even UARTs can sometimes go a little faster
- (2) While it's very convenient that I2C only needs two wires, both wires must be capable of bidirectional open-collector communication. This makes it difficult to send I2C via repeaters.
Personally, I'd like to see controller venders support a three-wire variant of SPI which included handshaking. I'm unaware of any controller that does so, though.
In no particular order, the most popular physical-layer instances for 2 CPUs in the same box seem to be:
- daisy-chain SPI (such as used by JTAG)
- select-wire-per-slave SPI
- "TTL-level RS-232" aka "asynchronous start-stop serial communication"(directly connecting the UART TX pin of one CPU to the UART RX pin of another CPU)
- 8-bit data + strobe (such as the IEEE 1284 printer port parallel port)
- shared-memory (only one CPU drives the address/data/control bus at a time)
These physical layer instances (as well as other physical-layer instances for 2 CPUs in separate boxes) typically provide a stream of bytes to the software that implements the higher levels of the communication system.
Smart programmers write the software in such a way that when the hardware guy decides to tear out one physical-layer instance and replace it with a completely different physical-layer instance, they only need to rewrite a few functions to feed their output stream of bytes to the hardware and read back a stream of bytes from the hardware, and all the higher-level protocol stuff continues to work unchanged.
The protocol to send information from one CPU to another CPU almost always involves interpreting the stream of bytes as a series of packets:
- (possibly escaped) serialized data
Some people seem to enjoy making up entirely new, custom, incompatible protocols by mixing-and-matching (2) one of many kinds of header structure with (3a) one of many kinds of serializing data with (3b) one of many kinds of escaping that serialized data with (4) one of many kinds of trailer.
Some of the simplest protocols for encapsulating data into a packet include:
Slightly more complicated protocols for encapsulating data into a packet include:
There is a long list of protocols at
You may enjoy reading "Protocol Design Folklore" by Radia Perlman which describes how protocol design can go wrong.
No single 'general' protocol. Choice can (for instance) depend on:
- required throughput
- availability of special peripherals
- noise level
- need for optical isolation
- criticality (tolerable failure rate)
- avialable CPU power at both ends
- available I/O pins at both ends
In a lot of cases you must disitinguish the physical layer (signal levels) from the data link layer (+/- the way data is encoded)(check OSI model, lower 2 ..4 layers). Possible phyiscal layers are for instance:
- simple 5V or 3.3V or even 1.8V TTL
- any of the above but open-collector instead of push-pull
- balanced lov voltage signaling (often used with FPGA's)
- balanced higer volatge (RS485, RS432)
- single ended higher voltage (RS232)
- balanced trafo-coupled (various ethernet versions, PDIF audio)
- optical (optical ethernet, toslink)
You can use one line to carry data and clock info, or split this into multiple lines. The latter used to be popular, but nowadays most new / fast protocols tend to use one line (or a pair of lines acting as one).
Ther are alot of ways to encode data and clock on a line. RS232 traditionally uses NRZ, there is Machester encoding, adn the various format uses on harddisks with curious names line 2.7 RLL.
To sum it up: there are a gazillion ways to do communication between systeems. And I haven't even mentioned connectors or higher-level aspects like error detection and recovery, data encoding, compression, and encryption...