Serial communication between 3 Arduino UNOs

I would like to connect 3 Arduino UNOs with each other. One would be master, which would be checking both slave Arduino if they have any new data (different value from before).

The Arduino UNO slave 1 will read all 6 Analog In ports for changes of the 10k potentiometers.

Ardunio UNO slave 2 will send PWM values to 6 digital servos.

Master Ardunio UNO takes values from slave 1 and sends them to slave 2 while also writes the values to an SD card (and other things)

now a general question:
-would you connect all DATA-OUT (MOSI) together, all DATA-IN (MISO), all SPI-CLOCK (SCK) and all SLAVE-SELECT (SS) together?
-or would you cross out DATA-OUT from master with DATA-IN of the slave units?

do you need to have a separate input on your Master for each device’ SLAVE-SELECT ?

how do you go about enabling and disabling a specific Slave Arduino UNO?

I have attached a system diagram to this question

would you connect all DATA-OUT (MOSI) together, all DATA-IN (MISO), all SPI-CLOCK (SCK) and all SLAVE-SELECT (SS) together?

All MOSI, SCK and MISO pins connected together. Then you need two SS signals, one for each slave.

So your drawing is nearly right, just needs another SS.


Rob

cool thanks .. so in the code i basically define the two different SlaveSelects..

at the Master i would define:

define DATAOUT 13 //MOSI

define DATAIN 12 //MISO

define SPICLOCK 8 //sck

define SLAVESELECT 7 //ss for Slave1

define SLAVESELECT 6 //ss for Slave2

would that do the trick? so every time i set SLAVESELECT 7 to low and as long as the other one set to high - it communicates with the Master i assume.

Don't put these in

define DATAOUT 13 //MOSI

define DATAIN 12 //MISO

define SPICLOCK 8 //sck

When you call SPI.begin(); it will take over those pins.

You will do two transfers to talk to slave. The first tells the slave to send data, the 2nd reads it.

Here is an example where I read 2 bytes back from an ADC - the first transfer gives the ADC a command, the next read the data back. Every time a byte is transferred out, one is read back in.

// read ADC with 3 byte transfer digitalWrite (ADC_SS, LOW); // ADCaddress = 0x0600, 640, 680, 6C0, 700, 740, 780, 7C0 dummyADC = SPI.transfer (highByte(ADCaddress)); // 0x06, 0x07 out, read in dummy data highADC = SPI.transfer (lowByte(ADCaddress)); // 0x00, 0x40, 0x80, 0xC0, read in upper 4 bits lowADC = SPI.transfer (0); // dummy 0 byte out , read in lower 8 bits digitalWrite (ADC_SS, HIGH);

define SLAVESELECT 7 //ss for Slave1

define SLAVESELECT 6 //ss for Slave2

Can't have two defines with the same name, maybe

define SLAVESELECT1 7 //ss for Slave1

define SLAVESELECT2 6 //ss for Slave2


Rob

I was wondering if there is a way to reduce all those data lines – i need to have more ports available… is there no other way or protocol to let’s say just have one connection going from Slave1 to Master just always sending data in series from slave1 to master; and only one connection from Master to Slave 2 always sending data from master to slave2 ? – and with all clocks connected (see attachment)

  • how would the program code look like?

there is really no need to have 2 directional communication between the two slaves and enabling and disabling one at a time… or?

My suggestion: while what you suggests would work, why not get a mega and save yourself the trouble. Try Seeeduino Mega (extra pins exposed compared to arduino mega), it will give you more DIO and analog pins than 3 Duos put together, and cost less at the same time. 16ADC + ~54DIO with 11 available for pwm, plus the SPI port is still available for the SD card.

Yes, if you are only reading from one and writing to the other that will work.

how would the program code look like?

x = SPI.transfer(y);

Will get a byte from slave1 and put it in x and send y to slave2.

This will have to be done in a loop to transfer N bytes, we can call this a “transaction”.

byte dataIn[10];
byte dataOut[10];
...
// prepare values in dataOut
...
for (int i = 0; i < 10; i++) {
     dataIn[i] = SPI.transfer(dataOut[i]);

Now if the number of bytes read from S1 is not the same as that written to S2 you have to use the largest number for your transaction loop counter and ignore any extra bytes either on the master or S2.

Also slave2 will always be getting data calculated based on the previous transaction.

All this said though, why not just use a larger Arduino?


Rob

Whoa what happened, a post was removed and I lost my reply as well. It's too long to retype.


Rob

That just happened to me too, on a different thread. Clicked preview, and the post I was replying to disappeared.