Sharing SPI (WAV Shield + MEGA +WiFly) - WiFly/WAV cable select pins

I have a question about getting the Adafruit WAV shield, WiFly shield and Arduino MEGA to work together.

Problem:

The WAV shield has to be jumpered in exactly the same way as the WiFly shield to work with the Mega since they both share the SPI.

Mega pin 53 to shield pin 10
Mega pin 51 to shield pin 11
Mega pin 50 to shield pin 12
Mega pin 52 to shield pin 13

I need to set the cable select of the WiFly shield to pin 10, so I can toggle between two shields using the cable select pins. In my setup the WAV shield would be using pin 53 and the WiFly shield would be using pin 10.

Is this possible? I've been looking at github at the different forks of the WiFly library that support Arduino 1.0, but am having a hard time finding where the cable select pin is is being set in any of them.

If I understand it, you want to connect 2 devices to SPI and the board only has one chip select (CS) pin.

You can usually use another digital output as a chip select. When you need to send a message set the pin to the active state, send the SPI message and then set the pin to the inactive state.

You can also use another digital output to control a digital switch or multiplexer and route the CS to the desired shield.
http://www.onsemi.com/PowerSolutions/product.do?id=NL7SZ19
http://www.fairchildsemi.com/ds/NC/NC7SB3157.pdf

I hope that helps,
Steve Turner

I don't know about those libraries personally, but it is possibly up to you to flip the chip select pins before sending/receiving data. If you don't define the CS pin in begin(), or the equivalent call, you will likely be expected to make the device active any time you call a class member function dealing with that device.

The docs should tell you for sure, although (unfortunately) I find a lot of documentation is more of a how-to, with very little info to guide you along if you step outside the example configuration.

Thanks for the suggestions Steve + SirNickity.

The digital switch sounds promising, but I want to see if there's a software based solution first.

While I can't seem to find in the library where the cable selection pin is for the WiFly shield...

I was ABLE to find where the cable selection pin is on the WAVHC library in this class "ArduinoPins.h".

I will mod this pin to a unused pin and see if I can toggle between the two shields.

// SPI port
#define SS_PIN 53

Will report back with my findings!

Almost there...I have the WAV shield working with the new pin reassignment...But I'm having issues switching between shields.

I edited "ArduinoPins.h" in the WAVHC library to change the SS_PIN from 53 to 33

// SPI port
// **SJ #define SS_PIN 53
#define SS_PIN 33 //<---changing this from 53 to 33 so I can use the WiFly shield
#define MOSI_PIN 51
#define MISO_PIN 50
#define SCK_PIN 52

Snippet from my app to toggle between shields:

#define SSWAV 33 //cable select pin for WAV shield
#define SSWIFLY 53 //cable select pin for WIFLY shield


//this enables the cable selection pin for WiFly shield
void enableWiFlyShield()
{
  digitalWrite(SSWIFLY, LOW);
  digitalWrite(SSWAV, HIGH);
}

//this enables the cable selection pin for WAV shield
void enableWAVShield()
{
  digitalWrite(SSWIFLY, HIGH);
  digitalWrite(SSWAV, LOW);
}

On init of my app I can call either enableWiFlyShield() or enableWAVShield() and run the respective shield fine....

BUT if I run the WiFly shield first, then at run time toggle the WAV shield....I get read errs from the WAV shield's SD card: "Couldn't open file mytestsound.wav" The SD card reader on the WAV shield used the SPI...So I'm thinking it a cable select issue? Either the WiFly css pin isn't being disabled properly and hogging the SPI or the WAV css pin isn't being enable properly?

Here's a picture of my board setup and specs to give you a better idea what I'm working with:

  • Arduino MEGA 2560
  • WiFly Shield
  • SpeakJet Shield
  • Adafruit WAV Shield

Anyone have suggestions on how to debug this? My pins modifications to the WAVHC library seem to be fine, because all the WAV shield examples work and I can run my app with just the WAV shield alone. The problem seems to be initializing the WiFly shield first....

The wave shield plays audio under interrupt. That's going to mean that it will need to select the correct chip (shield) repeatedly, many times each second.

I'm not sure I have a solution but that might be your issue.

One thing to consider is finding the interrupt service routine for the wave shield and making it restore the correct CS before it quits. Means messing with the library but it's all I can think of.

Edit - of course theWiFly shield may be resetting the CS under interrupt too so you may need to modify that too.

After some more trouble shooting I've discovered this:

If I change the order of initialization...and run the WAV shield FIRST I can toggle to the WiFly shield later at runtime...But if I try to toggle back to the WAV shield, I run into the same SD card read errors...

So it appears my WiFly shield is not releasing the cable select pin or SPI resources gracefully?

It sounds to me like the WiFly shield isn't releasing control of it's cable select PIN for the SPI bus, just as you suspect. Given your setup, you should be able to toggle back and forth between them (just as I do with RiderScan between the Wav, RFID, Ethernet and SD cards).

A couple things I would try;

  1. Re-initialize the SPI bus when your ready to switch back to the Wav shield, maybe the reset will force the WiFly shield to release it's cable select PIN.

  2. Compare the WiFly and Wav shield libraries where SPI is concerned, and see if you can modify the WiFly library to act more like the Wav shield in terms of releasing the cable select PIN.

If you can't get the WiFly to release it's cable select PIN, then I think your only option is to use another WiFi shield. :expressionless:

Kris

How do you re-initialize the SPI bus?

Would this work?

void resetSPI()
{
  SPI.end();
  SPI.begin();
}

I tried setting pins 10, 11, 12, 13 to inputs too...

void setupWAVANDWIFLY()
{
  pinMode(SSWAV, OUTPUT);
  pinMode(SSWIFLY, OUTPUT);

  digitalWrite(SSWAV, HIGH);
  digitalWrite(SSWIFLY, HIGH);
  
  pinMode(10, INPUT);
  pinMode(11, INPUT);
  pinMode(12, INPUT);
  pinMode(13, INPUT);
}

Hi,

I had the same problem with the data logging shield + RFM12B + Ethernet Shield + mega 2560. I think your problem is the same I had and it's about the CS PIN that control the SD on your Wave Shield.

Mainly, as I wanted to have an easy access to my SDCard, I chose not to use the Ethernet Shield SDCard reader.

Edit you Sd2Card.h and replace => uint8_t const SD_CHIP_SELECT_PIN = 10; by uint8_t const SD_CHIP_SELECT_PIN = 33;
Bend or cut your pin N°10 on your Wave Shield (this shield must be on the top of your stack) and add a jumper between Pin 33 and 10.
Add 4 jumpers between 11,12,13 on the Wave Shield and 51,50,52 on the mega2560.

Code:

int CS = 33; //chipselect for SDcard
int SS = 53; //standard hardware chipselect for mega2560

void setup() {

pinMode(SS, OUTPUT);
digitalWrite(SS,HIGH);
...
if (!SD.begin(CS)) {
....
}
....
digitalWrite(SS,LOW);
digitalWrite(CS,HIGH);
Ethernet.begin(mac, ip); // WiFly.begin(); in your case
...
digitalWrite(SS,HIGH);
}

I tested this solution with the Ethernet Shield V5 (Rev 2) with Success 8) but with the V6 (Rev 3) it fails :~

Let me know about the result with your WiFly Shield.

Cheers.