Electronic – arduino – Problem stacking accelerometer and SD card shields on Arduino UNO

arduinohardwarepins

I have an ADXL345 accelerometer on a Makershield stacked on top of a Seeed SD card shield. Both of those are stacked on an Arduino UNO R2.

I've got each working individually, but when stacked they share pin 12. The SD Card shield uses 12 for MISO of SPI and the ADXL345 uses it for SDO/Alt address.

I'm new to Arduino and have not stacked shields like this before. I'm not sure what the best course of action is here to get them both working, Ultimately, I want to log the data from the accelerometer to the SD card, but first things first!

I'd be grateful for any help. I've linked the data sheets for the ADXL345 and the SD shield above.

Best Answer

It shouldn't be a problem. The Chipselect of the accelerometer is pin 10, and that of the SD card shield is 7.

Which means that you can use one board at a time, as long as you set its chipselect to HIGH once you're done with it.

Basically, the usual code for accessing the accelerometer is like this (from here, just the relevant parts):

int CSa=10; //Chipselect for accelerometer
void writeRegister(char registerAddress, char value){
  //Set Chip Select pin low to signal the beginning of an SPI packet.
  digitalWrite(CSa, LOW);
  //Transfer the register address over SPI.
  SPI.transfer(registerAddress);
  //Transfer the desired register value over SPI.
  SPI.transfer(value);
  //Set the Chip Select pin high to signal the end of an SPI packet.
  digitalWrite(CSa, HIGH);
}

//This function will read a certain number of registers starting from a specified address and store their values in a buffer.
//Parameters:
//  char registerAddress - The register addresse to start the read sequence from.
//  int numBytes - The number of registers that should be read.
//  char * values - A pointer to a buffer where the results of the operation should be stored.
void readRegister(char registerAddress, int numBytes, char * values){
  //Since we're performing a read operation, the most significant bit of the register address should be set.
  char address = 0x80 | registerAddress;
  //If we're doing a multi-byte read, bit 6 needs to be set as well.
  if(numBytes > 1)address = address | 0x40;

  //Set the Chip select pin low to start an SPI packet.
  digitalWrite(CSa, LOW);
  //Transfer the starting register address that needs to be read.
  SPI.transfer(address);
  //Continue to read registers until we've read the number specified, storing the results to the input buffer.
  for(int  SPI.transfer(0x00);
  }
  //Set the Chips Select pin high to end the SPI packet.
  digitalWrite(CSa, HIGH);
}

Note that the CSa pin is made LOW before reading/writing, and it is set to HIGH once you're done with it.

Make sure that you do the same for the chipselect for the SD card shield -- keep its chipselect on HIGH when not in use, and on LOW only for the duration of time when you want to communicate with it.