SPI switcher

I’ve been working on a little project involving multiple SPI devices; an RFID scanner, 1 SD card slot and a Datalogger(and possible more).

So I want to switch the devices without losing any unnecessary time.

This is the test code and SPI switcher. It makes 1 select pin LOW and the another HIGH

int N_SS = 4; //number of SPI devices
int SS_Pin[] = {5, 8, 26, 52};
int i;
void setup() {
  for (i = 0; i < N_SS; i++)
  {
    pinMode(SS_Pin[i], OUTPUT);
  }
  for (i = 0; i < N_SS; i++)
  {
    digitalWrite(SS_Pin[i], true);
  }
}

void loop() {
  Switch(1);
  delay(1000);
  Switch(2);
  delay(1000);
  Switch(3);
  delay(1000);
  Switch(4);
  delay(1000);
}

void Switch(int a) {
  for (i = 0; i < N_SS; i++)
  {
    digitalWrite(SS_Pin[i], true);
    }
  digitalWrite(SS_Pin[a], false);
}

But now I’ve tested it with hardware(only LED’s so far). It skips the SS_Pin[5], the first one. (doesn’t matter what pin I change it to)wiring isn’t the problem. and I can’t seem to find the problem in the code.

and my second question. Can this be done easier? or is this as easy as it comes?

Derek_F: ...and my second question. Can this be done easier? or is this as easy as it comes?

if all the devices are connected to the same SPI pins (except the SS pin of course), ONLY the SS pin of the device you are communicating can be LOW(false).

so I think more simply all you need to do is:

- initialise all the SS pins HIGH(true) - have a variable (var_a) that will remember the SS_pin you set LOW (false) - whenever you switch device, de-select current device (held var_a) ie set its SS_pin HIGH, then set the next device SS_pin LOW and update var_a

alternatively you could do this as well for any device you choose to communicate with:

SS_Pin_A LOW (all spi.transfers with deviceA) SS_Pin_A HIGH . . . SS_Pin_B LOW (all spi.transfers with deviceB) SS_Pin_B HIGH . . . ...you get the trend (can even do a for loop here! :) )

void switch (int a){
digitalWrite(SS_Pin[b], true);
digitalWrite(SS_Pin[a], false);
Int b=a;
}

Dang, that I didn't think of that.. This should work. Cannot test it, just powered everything off...

And I could probably get pinMode and digitalWrite in the same 'for' loop.

Derek_F: void switch (int a){ digitalWrite(SS_Pin[b], true); digitalWrite(SS_Pin[a], false); Int b=a; }

"Int b;" need to be "static" or a global variable else its value will NOT be retained once you exit the routine. something like that maybe:

void switch (int a){
static Int b=SS_Pin[1]; //initial value when first called
digitalWrite(SS_Pin[b], true);
digitalWrite(SS_Pin[a], false);
b=a;
}
void loop() {
  Switch(1);
  delay(1000);
  Switch(2);
  delay(1000);
  Switch(3);
  delay(1000);
  Switch(4);
  delay(1000);
}

In C(++) you start counting at 0, so your code must read:

void loop() {
  Switch(0);
  delay(1000);
  Switch(1);
  delay(1000);
  Switch(2);
  delay(1000);
  Switch(3);
  delay(1000);
}