SPI - Arduino UNO - 2 Slave Shields

Hello everybody,

Probably this question is raised before, but I am not finding the solution for my setup. I have an Arduino UNO R3 (IDE 1.0.5) which I want to connect to 2 shields (a CAN-bus shield and the Arduino WiFi Shield). Both shields use the SPI pins 10, 11, 12 and 13 to talk with the UNO. I want to stack them all together now. I found out already that it is possible to connect more than one device in parallel next to the MASTER_SPI on an SPI-bus. But every Slave needs a separate SS-pin. About this:

  • Which pin should I take for this?
  • What do I need to change in software to configure this pin? Do I need to do this in my main Sketch, or do I have to change the LIBs from the Shield which needs to use a different pin for its SS? Or do I need to change something in the SPI Library?

Any help here would be great :slight_smile:

Pieter

===========
== Solution ==

Which Library: SeeedStudio CAN-bus Shield Library (in attachment).
If you want to put the SS/CS to another Pin than the standard number 10 you have to do 3 thing:

  • Put a jumper from Pin10 of the CAN-bus shield to the Pin number of the UNO you want to use. Do not forget to bend the pin from the CAN-shield so you do not also connect it with the shield below which is using Pin 10 for its SS/CS.
  • In the Library file “mcp_can_dfs.h” you have to change the line “#define SPICS 10”. Change the 10 into the pin number you want to use for the SS/CS.
  • In your sketch “Setup()” function you have to put following code (with x the pin number you want to use) before you call the “CAN.begin()” function:
pinMode(x, OUTPUT);    
digitalWrite(x, HIGH);

Good luck! Pieter

mcp_can.rar (11.9 KB)

Both shields use the SPI pins 10, 11, 12 and 13 to talk with the UNO.

The SPI pins are 11, 12, and 13. On the WiFi shield, pin 10 is hardwired to be the slave select/chip select pin, and can't be changed. If the CAN-bus shield also has pin 10 hardwired as the slave select/chip select pin, you can not stack the shields.

If the CAN-bus shield can use a different slave select/chip select pin, then you can stack them. Change the slave select pin in the code, too.

Hello Paul,

Thanks for answering. Yeah both shields have the PIN10 hardwired. But I want to cut pin 10 and also the pin I want to use for SS of the top shield (CAN-bus). After that I connect pin 10 of the top shield with the input pin of the shield below I want to use. Can I choose freely which Pin I use for this? When I look at the schematics of the WiFi shield, it looks like Pin 9 is not used by the shield. Can I configure pin 9 as SS for the CAN-shield?

In which code do I have to change the pin? I only have to change the pin number? Or should I do more? For example enabling something that the system knows there are more slaves on the bus?

Thanks.

I would guess the answer is yes. At least one model CAN bus shield offer the option of using D9 or D10 as the slave select. The shield on this link for example. Note the solder pads next to D9 and D10 used for the selection.
http://www.seeedstudio.com/wiki/CAN-BUS_Shield

Hello Tim,

Thanks for your reply. But I am using the following CAN-bus shield:

Here there is not an option to change the SS pin on the shield. But hopefully my solution described above will work. But I do not know where to change the pin number and/or other setting in which software code,...

SurferTim:
I would guess the answer is yes. At least one model CAN bus shield offer the option of using D9 or D10 as the slave select. The shield on this link for example. Note the solder pads next to D9 and D10 used for the selection.
http://www.seeedstudio.com/wiki/CAN-BUS_Shield

Then you will need to experiment. I would try bending pin D10 on the CAN bus shield so it does not insert into D10 on the Uno, and jumper it to D9 on the shield. I would try it without the wifi shield connected first.

edit: When you connect both shields, insure the wifi shield is connected to the Uno, and the CAN bus shield is connected to the wifi shield. The wifi shield needs the ICSP connector connected to the Uno's ICSP pins.

Hello Tim,

Great, I will try this tonight. But what about SW changes? I have to make clear to the UNO that there is an SS coming in at a different pin. Where should I change/add something? Is this in the SPI library or in the CAN-bus library?

SurferTim:
Then you will need to experiment. I would try bending pin D10 on the CAN bus shield so it does not insert into D10 on the Uno, and jumper it to D9 on the shield. I would try it without the wifi shield connected first.

I don't know about the CAN bus library, so that is part of your experiment. Maybe somebody familiar with that library can help you with that part. If it is like the wifi shield library, it may be difficult to change. If it is like the SD library, it will be easy.

Hallo Tim,

I had a look in the the CAN library i am using but cannot locate the SS settings. My library files (headers and ccp) are in the attachment. Maybe someone can have a look to help me out where to do what :slight_smile:

Thanks

SurferTim:
I don’t know about the CAN bus library, so that is part of your experiment. Maybe somebody familiar with that library can help you with that part. If it is like the wifi shield library, it may be difficult to change. If it is like the SD library, it will be easy.

mcp_can.cpp (26.9 KB)

mcp_can.h (5.45 KB)

mcp_can_dfs.h (9.22 KB)

This is in mcp_can_dfs.h. You must change the SPICS define to pin 9. Open that file with a text editor, then:

// change this
#define SPICS 10
// to this
#define SPICS 9

That should change the slave select to D9 for the CAN shield. No guarantees tho.

edit: You will find that define about 3/4 down the page. These are the defines that enable and disable the CAN SPI. They are just below the SPICS define.

#define MCP2515_SELECT()   digitalWrite(SPICS, LOW)
#define MCP2515_UNSELECT() digitalWrite(SPICS, HIGH)

SurferTim:
This is in mcp_can_dfs.h. You must change the SPICS define to pin 9. Open that file with a text editor, then:

// change this

#define SPICS 10
// to this
#define SPICS 9



That should change the slave select to D9 for the CAN shield. No guarantees tho.

edit: You will find that define about 3/4 down the page. These are the defines that enable and disable the CAN SPI. They are just below the SPICS define.


#define MCP2515_SELECT()   digitalWrite(SPICS, LOW)
#define MCP2515_UNSELECT() digitalWrite(SPICS, HIGH)

Hello Tim,

Thanks for your effort in helping me. I already tried changing that line like you told up here. But for some reason it is not working. After putting pin 10 from the shield back on pin 10 of the UNO it also is not working anymore, so the change has some effect on the system, I just do not get why it is not working when putting pin 10 from the shield on pin 9 from the UNO. Can it be that the Arduino SPI driver needs a change to? Or the pins_arduino.h file?

Getting a bit desperate here :slight_smile:

Do not change the pins_arduino.h file. That will certainly cause a fail. If you have changed that, you must change it back to its original settings.

edit: Don't change anything in the SPI library either.

If all you changed was that one change in the mpc_can_dfs.h file, then bending and jumpering D10 to D9, you should be able to unjumper and unbend D10, and change the SPICS setting back to 10, and it should work like it did. There is no "system" on the arduino to mess up.

You can damage the Arduino if you jumpered D10 to D9 without bending the D10 pin so it would not insert into the Arduino. Both would be set to OUTPUT, and would fight for control, and one would lose.

The only other thing that would be a cause for the D9 pin to not work correctly as the slave select is if the CAN library does not set the slave select to OUTPUT. It may have counted on SPI.begin() to do that, but that would set D10 to OUTPUT, not D9. If you want to try again, set D9 to OUTPUT and HIGH before using the CAN shield.

pinMode(9, OUTPUT);
digitalWrite(9, HIGH);

edit2: I just checked the CAN shield library, and it does count on SPI.begin() to set the slave select. If you want to use another pin for the slave select, you must set that pin as OUTPUT and HIGH in your setup code before initializing the CAN shield.

Thanks a lot Tim, it is working now :slight_smile: :slight_smile: :slight_smile:

I currently have the same problem, only difference is that I am using LCD shield on top of the CAN shield. Do I really have to bend the CAN pin 10 in order to get it working? I don't quite understand what Tim means by being able to unbend the Pin 10 and that it might damage the Arduino...