Basically I have two microcontrollers that I need to communicate with each other.

Both controllers send and receive data.

Basic idea that I have:

  1. I2C, SPI - What I think we can NOT use these protocols in this case. Because both are master slave based protocols. So if one controller is configured as master and other as slave, then in that case if the slave uC wants to transmit data then it can not initiate the transmission and it is also not allowed to generate the clock.

  2. UART - I guess this should work as it's asynchronous. So nobody is bound to be slave or master.

My question is, if the above made assumptions are right? If no then please correct me.

  • \$\begingroup\$ What microcontroller are you using, and what are you using to program it with? If it's arduino based, you can use the SoftwareSerial library to use any of the 'digital' pins as fake UARTs if you have the normal hardware UARTs doing other things \$\endgroup\$ – KyranF Oct 12 '14 at 19:24

Your assumptions are correct, yes. SPI and I2C are both normally master/slave protocols, though there are ways of "bending" them to be able to work either way around.

But for simplicity, yes, UART is probably the easiest and most sensible.

  • \$\begingroup\$ UART for the win! His microcontroller may not have many/any spare UART though, sometimes it's not easy to have as many of those as you want. \$\endgroup\$ – KyranF Oct 12 '14 at 19:24
  • \$\begingroup\$ So you choose microcontrollers that fit the design, not design around an Arduino ;) That's why I love the concept of the Cypress PSoC where it's up to you to decide how many UARTs (for example) you have in your chip. Shame it's not got any software support for anything other than windows :( \$\endgroup\$ – Majenko Oct 12 '14 at 19:26
  • \$\begingroup\$ I looked into the Cypress PSOC stuff, it's design program is really cool. There are new Atmel Cortex M0, the D20 series, which now have reconfigurable interface blocks that can act as any of the main comms peripherals. Means you have have alllllllllllll the UARTs you want! \$\endgroup\$ – KyranF Oct 12 '14 at 19:28

If this is for your own setup, then the only thing that matters is consistency. You control everything, so it's up to you. You can go with a standard protocol, or make your own, or modify one to suit your needs. If you already have a bus like I2C or SPI in use, you might as well continue to use it.

That said, while I2C and SPI are master-slave protocols, this can easily be worked around through the use of an interrupt/signal pin. If the slave wants to talk to the master, it toggles the interrupt pin, and the master initiates a I2C/SPI session. Or polling.

As for generating the clock, unless you have a specific need for both microcontrollers to do that, why bother? Do you need to run one at a different speed? Choose a clock speed ahead of time and stick to it in your implementation.

  • 3
    \$\begingroup\$ Also for SPI, etc, you can have both devices normally in slave mode, then when one wants to talk to the other it switches into master mode for the duration of the transfer. Only really works well on a direct 1:1 link rather than a shared bus. \$\endgroup\$ – Majenko Oct 12 '14 at 19:47
  • \$\begingroup\$ This is a very good approach ,, I never got this idea. However in this way only one controller will be able to send data at a time, if other controller wants to send data then, that has to become master. Is this right? \$\endgroup\$ – Virendra Kumar Oct 13 '14 at 16:57
  • 1
    \$\begingroup\$ @virendrakumar "sending" data is subjective. Both spi and i2c are bidirectional buses. Sending data from slave to master simply means master asks for data and slave responds. With multiple devices, you can have multiple interrupt pins, or a single shared open drain interrupt, and then have the master poll each device to find out which is ready to send data. Or if you have many, a gpio port expander serving as a middleman would work too. \$\endgroup\$ – Passerby Oct 13 '14 at 18:50
  • \$\begingroup\$ Then there is the multimaster setups in i2c, where any device can become a master if needed. Or smbus, an "enhanced i2c" that also has multicast global addressing where it signals to all devices to respond if they have an alert etc etc. Many ways to do this. \$\endgroup\$ – Passerby Oct 13 '14 at 18:50

The devices on a I²C bus are not given predetermined roles of master and slave: A device is a master if it is currently controlling a transaction with a slave, or is actively trying to do so. A device is a slave if it has a slave address and is either communicating with a master or listening for masters. Other devices on the bus are simply inactive.

I²C supports multiple masters and multiple slaves. If you have multiple devices that need to be able to send or receive data at will, you assign a slave address to each of them, and program them to assume the role of master when they need to transmit or request data.

If multiple masters are present the masters take turns: Before starting a trasaction masters wait for the current transaction to finish, if there is one. If multiple masters begin a transaction at the same time, the first one to notice that the bus is not at the state it wants to backs down (this is known as arbitration).

In short, what you want certainly isn't impossible with I²C. However,implementing I²C is a bit of a pain and likely overkill for just two microcontrollers trying to talk to each other. I would choose UART in your case, thanks to its simple and flexible nature.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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