I'm currently working on a personal project for which I need to allow multiple Arduinos to communicate together.
The though point being that I need the communications to work both ways : from the Master to (one of) the slaves and from (one of) the slaves to the master.
I already studied few protocols that could fit my needs, but without any success :
- I2C : my first guess, but slave to master needs to be done by polling from the master ... not possible in my case : some of the slaves need immediate attention from the master
- SPI : both ways, but slave must be selected by a dedicated line
- UART : not enough serial ports on my Arduino Uno
- RS-485 : it seems that, although communication can be done both ways, it must be initiated by master that sends data, and then waits for an answer ; the use of RS-485 also implies buying additional hardware (transcievers)
I2C seemed an easy way to accomplish my goal : is this a good idea to handle slave to master with slave sending an interrupt to the master via dedicated lines ?
Are there some other options I didn't think of ?
Thanks in advance for your help :-)
UART and RS-485 are the same thing (sort of), RS-485 is not a protocol, it's just a physical layer you often use for UART comms.
How about CAN, that's multi-master, everyone just says what they want when they want and the hardware sorts the clashes out.
The Due has two CAN ports as well.
But how about some more details, speed and distance for example. Do they have to be AVR processors?
Thanks Graynomad for your reply. :)
I did not mention any speed and distance requirements, as these shouldn't be an issue : µCs will be very close (few centimeters) and few data will be exchanged, so few kb/s will be enough.
Regarding CAN, I also read about it (and just read more) : it seems perfect for my usage, but requires additional hardware : 1 CAN controller + 1 CAN transciever per node (but these seem to be quite affordable).
The Due could actually be the main controller of my project, however, it seems that although CAN is present, there is no (official, at least) Arduino API to use it.
I initially planned to go for AVR µC exclusively, but I'm still open to other options that would help me.
it seems that although CAN is present, there is no (official, at least) Arduino API to use it.
True, but there are a few people working on that and I even think it's sanctioned by the powers that be so it may wind up as official.
but I'm still open to other options that would help me.
I plan to use a Due for the "master" and the LPC11C24 for simple nodes, it has the controller and transceiver built in. Atmel have a CPU with the controller built in as well but no transceiver.
If your chips are just a few cm apart though I think I2C is probably the best option, I don't know it very well but it can do multi-master and that usually does NOT mean polling by a master because then it isn't multi-master :)
Thanks again for your help.
Multi-master I2C looks really interesting, I just gave it a try connecting 2 Arduinos together as masters : works great ...
but I2C Arduino's Wire library is blocking : in consequence, if a (master) receiver is not available, sender (also master) is blocked ...
Edit : actually it was a wiring problem (SDA & SCL lines weren't pulled up anymore as the second Arduino was disconnected)
After some more testing, multi-master I2C is definitely what I was looking for, thanks a lot Graynomad !
By the way, CAN looks also really nice, I may not use it this time but I'll eventually use it for another project :)
You could use the SoftwareSerial library for the Uno to create extra serial ports.
But I2C is the way to go, even if the library is blocking when something is wrong.
Do you know the two ways to do this ?
(1) The Master is always the Master. The Slave gets the attention of the Master by an interrupt. After that the Master requests data from the Slave. Works very well, but the Master waits for the I2C session to be ended with the Wire.requestfrom() function.
(2) Multi-Master. Normally the Master gets an interrupt from the Slave, it tells the Slave (with I2C or a digital pin) to send its data, and the Slave turns into a Master and transmits its data. This works even better, since the whole communication is handled in interrupt service routines.
In some rare situations, it is possible that the Slave turns itself into a Master at its own choice, if it knows that the 'real' Master is not occupying the bus.
Why is polling a problem ?
If you use a single Master I2C bus, the Master could poll 100 times a second.
Polling is (in my opinion) a problem for 2 main reasons :
- I don't want my master to be continuously polling slaves, it should be doing some more useful tasks
- My slaves will be doing time sensitve operations (i.e. reading almost continuous serial input), and shouldn't therefore be constantly interrupt-ed
Normally, hundreds of interrupts per second should be no problem.
In the "Wire" and "Serial" libraries, a lot is handled with interrupts and buffers. I know the "Wire" library has 3 buffers.
If you have incoming data of 115200 baud, that is 11kbyte per second.
I can get about 8kbyte per second between Master and Slave via I2C at its normal speed (100kHz).
But the I2C bus speed can be changed with the TWBR register.