How to do code for multiple SPI device ?

I am doing a project that involves 3 ADXL345, Arduino Uno, Arduino Wifi Shield and I need help on getting all of them together. I am trying very hard to connect all of them using SPI protocol.

My first challenge is to connect Uno + SD + 1 ADXL345. Below is the code that I tried using it, but due to my low level in programming skills and understanding, it doesnt work, the values are showing 0,0,0 on the serial monitor and it doesnt log after 15~ readings. I have tried using the ADXL345 tutorial sample codes and SD card logging individually and they were ok. I really have no idea, where or which part went wrong.

My second challenge is to link 2 more ADXL345 into UNO + SD logging the data.

My third challenge is to send the data collect to a cloudserver(thingspeak)

// Include the relevant libraries provided with the Arduino
#include <SPI.h>
#include <SD.h>

// place holder for a large number
unsigned long time; // called it "time"

//Factors to change the data output by the accelerometer from raw data to G forces
double g=0.0039; //+/- 2g Make sure this matches the writeRegister Data Format on line 91!
//double g=0.0078; //+/- 4g
//double g=0.016;  //+/- 8g
//double g=0.031; //+/- 16g

#define SYNC_INTERVAL 10000 // mills between calls to flush() - to write data to the card
uint32_t syncTime = 0; // time of last sync()

// Assign the ADXL345 CS pin to Pin 10 ** make this whatever digital pin you chose to use**
int CS=10;

//This is a list of some of the registers available on the ADXL345.
//To learn more about these and the rest of the registers on the ADXL345, read the datasheet!
char POWER_CTL = 0x2D;    //Power Control Register
char DATA_FORMAT = 0x31;
char DATAX0 = 0x32;    //X-Axis Data 0
char DATAX1 = 0x33;    //X-Axis Data 1
char DATAY0 = 0x34;    //Y-Axis Data 0
char DATAY1 = 0x35;    //Y-Axis Data 1
char DATAZ0 = 0x36;    //Z-Axis Data 0
char DATAZ1 = 0x37;    //Z-Axis Data 1
char BW_RATE = 0x2C;    //Sampling Rate

//This buffer will hold values read from the ADXL345 registers.
char values[10];
//Initalize variables
int x,y,z;
int i;
double xg,yg,zg;
double totals[3];
File myFile;

void setup(){
  //Initiate an SPI communication instance.
  SPI.begin();
  Serial.begin(38400);   
 
  //Set up the Chip Select pin for the SD card to be an output from the Arduino.
  pinMode(8, OUTPUT);
  //Set chip select for ADXL345 to be output from Arduino.
  pinMode(CS, OUTPUT);

  //Set the CS Pin for the accelerometer high so that the ADXL345 and SD card won't be trying to talk at same time.
  digitalWrite(CS, HIGH);

  //Initialize the SD card
  if (!SD.begin(8)) { // the (8) is the CS pin you chose to use, on my sheild that pin is hardwired to "8"
    return;
  }
  // create a new file
  // starts with Crash00, and next one would be Crash01
  char filename[] = "Crash.txt";
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';
    if (! SD.exists(filename)) {
      // only open a new file if it doesn't exist
      myFile = SD.open(filename, FILE_WRITE);
      break;  // leave the loop!
    }
  }
   
  //Print header to file
  myFile.println("Time in MilliSeconds,X_Axis,Y_Axis,Z_Axis, X_G's,Y_G's,Z_G's");

  //Configure the SPI connection for the ADXL345.
  SPI.setDataMode(SPI_MODE3);
  //Before communication starts, the Chip Select pin needs to be set high.
  digitalWrite(CS, HIGH);

  //Put the ADXL345 into +/- 4G range by writing the value 0x01 to the DATA_FORMAT register.
  writeRegister(DATA_FORMAT, 0x00);//0x00 +/- 2G, 0x01 +/- 4G. 0x10 +/- 8G,0x11 +/-16G
  //Put the ADXL345 into Measurement Mode by writing 0x08 to the POWER_CTL register.
  writeRegister(POWER_CTL, 0x08);  //Measurement mode
  //Try and change sampling rate
  writeRegister(BW_RATE, 0x0D);
}

void loop(){

  //Count Milliseconds from time Arduino powered on
  time = millis();
 
  //Reading 6 bytes of data starting at register DATAX0 will retrieve the x,y and z acceleration values from the ADXL345.
  //The results of the read operation will get stored to the values[] buffer.
  readRegister(DATAX0, 6, values);

  //The ADXL345 gives 10-bit acceleration values, but they are stored as bytes (8-bits). To get the full value, two bytes must be combined for each axis.
  //The X value is stored in values[0] and values[1].
  x = ((int)values[1]<<8)|(int)values[0];
  //The Y value is stored in values[2] and values[3].
  y = ((int)values[3]<<8)|(int)values[2];
  //The Z value is stored in values[4] and values[5].
  z = ((int)values[5]<<8)|(int)values[4];

  //Convert raw data to g values
  xg=x*g;
  yg=y*g;
  zg=z*g;

  //Store g values in an array
  totals[0] = xg;
  totals[1] = yg;
  totals[2] = zg;

   // log time
    myFile.print(time);
    myFile.print(',');
   
  //Log accelerations
    myFile.print(x);
    myFile.print(',');
    myFile.print(y);
    myFile.print(',');
    myFile.print(z);
    myFile.print(',');
  for (i = 0; i < 3; i = i + 1) {
    myFile.print(totals[i]);
    myFile.print(',');
    // Open the serial monitor to see if it's working, select a baud rate of 38400, only displays milliseconds and G's
    Serial.print(time);
    Serial.print(',');
    Serial.print(totals[i]);
    Serial.print(',');
  }
  myFile.println();
  Serial.println();

  // Now we write data to disk! Don't sync too often - requires 2048 bytes of I/O to SD card
  // which uses a bunch of power and takes time
  if ((millis() - syncTime) < SYNC_INTERVAL) return;
  syncTime = millis();

  // flush the system
  myFile.flush();
// delay to help clear some of the noise
// delayMicroseconds(2);

}   //END OF LOOP!!!!!

//This function will write a value to a register on the ADXL345.
//Parameters:
//  char registerAddress - The register to write a value to
//  char value - The value to be written to the specified register.
void writeRegister(char registerAddress, char value){
  //Set Chip Select pin low to signal the beginning of an SPI packet.
  digitalWrite(CS, 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(CS, 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(CS, 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 i=0; i<numBytes; i++){
    values[i] = SPI.transfer(0x00);
  }
  //Set the Chips Select pin high to end the SPI packet.
  digitalWrite(CS, HIGH);
}

I think you have a SPI mode problem. The SD likes mode0 and the ADXL345 is mode3. You will probably call the SPI.setDataMode function when using the ADL345s.

SPI.setDataMode(SPI_MODE3);
// do your ADXL345 comm here
SPI.setDataMode(SPI_MODE0);

Are the writeRegister and readRegister functions the only time you communicate with the ADXL345s?

Each SPI device will require its own SPI slave select (CS) pin on the Arduino. Do you have the spare pins available?

SurferTim:
I think you have a SPI mode problem. The SD likes mode0 and the ADXL345 is mode3. You will probably call the SPI.setDataMode function when using the ADL345s.

SPI.setDataMode(SPI_MODE3);

// do your ADXL345 comm here
SPI.setDataMode(SPI_MODE0);

Erm, I just need to add in this line ?

Are the writeRegister and readRegister functions the only time you communicate with the ADXL345s?

For now yes, but later I will need to add in two more ADXL345 and sent result to cloudsever.

Each SPI device will require its own SPI slave select (CS) pin on the Arduino. Do you have the spare pins available?

I have! Other than 4/7/10/11/12/13 are free to use.

You might want to modify your functions to accept a slave select parameter. Note the additional byte in the parameters.

Here is your code modified for these changes.

void readRegister(byte tcs, char registerAddress, int numBytes, char * values){

  SPI.setDataMode(SPI_MODE3);

  char address = 0x80 | registerAddress;

  if(numBytes > 1)address = address | 0x40;

  digitalWrite(tcs, LOW);

  SPI.transfer(address);

  for(int i=0; i<numBytes; i++){
    values[i] = SPI.transfer(0x00);
  }

  digitalWrite(tcs, HIGH);

  SPI.setDataMode(SPI_MODE0);
}

void writeRegister(byte tcs, char registerAddress, char value){

  SPI.setDataMode(SPI_MODE3);
 
  digitalWrite(tcs, LOW);
 
  SPI.transfer(registerAddress);
  SPI.transfer(value);

  digitalWrite(tcs, HIGH);

  SPI.setDataMode(SPI_MODE0);
}

Then call the functions with the CS included.

#define ad0 2 // D2 as slave select
#define ad1 3 // D3 as slave select
#define ad2 5 // D5 as slave select

// write to ad0
  writeRegister(ad0, BW_RATE, 0x0D);

// write to ad1
  writeRegister(ad1, BW_RATE, 0x0D);

// write to ad2
  writeRegister(ad2, BW_RATE, 0x0D);
[color=red]// write to ad0
  writeRegister(ad0, BW_RATE, 0x0D);

// write to ad1
  writeRegister(ad1, BW_RATE, 0x0D);

// write to ad2
  writeRegister(ad2, BW_RATE, 0x0D);[/color]

where do i these code? Is it inside the setup function?

It can be in setup or loop. Change the register/value to the appropriate values.

Hi guys, I have managed to add into two more ADXL345 via SPI… Thanks SurferTim!

Now I would need to add in a proper SD datalogging function and then I will add in other sensors and finally I will send them to a cloud server…

I will try the SD logging part later… Hopefully, I can somehow to get them to log properly. IF anyone have advice please share them! Cheers!

If you are using the code I posted in reply#3, you should not have a problem. It keeps the SPI set to mode0 while not communicating with the ADXL345s.

edit: Be sure to set all SPI slave selects to OUTPUT and HIGH in setup before initializing any of the SPI devices.

SurferTim:
If you are using the code I posted in reply#3, you should not have a problem. It keeps the SPI set to mode0 while not communicating with the ADXL345s.

edit: Be sure to set all SPI slave selects to OUTPUT and HIGH in setup before initializing any of the SPI devices.

If I am not using the same code, how should can I do it?

//Add the SPI library so we can communicate with the ADXL345 sensor
#include <SPI.h>

//Assign the Chip Select signal to pin 10.
int CS1=1;
int CS2=2;
int CS3=3;

//This is a list of some of the registers available on the ADXL345.
//To learn more about these and the rest of the registers on the ADXL345, read the datasheet!
char POWER_CTL = 0x2D;  //Power Control Register
char DATA_FORMAT = 0x31;
char DATAX0 = 0x32; //X-Axis Data 0
char DATAX1 = 0x33; //X-Axis Data 1
char DATAY0 = 0x34; //Y-Axis Data 0
char DATAY1 = 0x35; //Y-Axis Data 1
char DATAZ0 = 0x36; //Z-Axis Data 0
char DATAZ1 = 0x37; //Z-Axis Data 1

//This buffer will hold values read from the ADXL345 registers.
char values[10];
//These variables will be used to hold the x,y and z axis accelerometer values.
int x,y,z;
float xg, yg, zg;

int i,j,k;
float ig,jg,kg;

int a,b,c;
float ag,bg,cg;


void setup(){ 
  //Initiate an SPI communication instance.
  SPI.begin();
  //Configure the SPI connection for the ADXL345.
  SPI.setDataMode(SPI_MODE3);
  //Create a serial connection to display the data on the terminal.
  Serial.begin(9600);
  
  //Set up the Chip Select pin to be an output from the Arduino.
  pinMode(CS1, OUTPUT);
  //Before communication starts, the Chip Select pin needs to be set high.
  digitalWrite(CS1, HIGH);
    //Set up the Chip Select pin to be an output from the Arduino.
  pinMode(CS2, OUTPUT);
  //Before communication starts, the Chip Select pin needs to be set high.
  digitalWrite(CS2, HIGH);

   pinMode(CS3, OUTPUT);
  //Before communication starts, the Chip Select pin needs to be set high.
  digitalWrite(CS3, HIGH);
  
  

}

void loop(){
    //Put the ADXL345 into +/- 4G range by writing the value 0x01 to the DATA_FORMAT register.
  writeRegister(DATA_FORMAT, 0x01,CS1);
  //Put the ADXL345 into Measurement Mode by writing 0x08 to the POWER_CTL register.
  writeRegister(POWER_CTL, 0x08,CS1);  //Measurement mode  
  //Reading 6 bytes of data starting at register DATAX0 will retrieve the x,y and z acceleration values from the ADXL345.
  //The results of the read operation will get stored to the values[] buffer.
  readRegister(DATAX0, 6, values,CS1);

  //The ADXL345 gives 10-bit acceleration values, but they are stored as bytes (8-bits). To get the full value, two bytes must be combined for each axis.
  //The X value is stored in values[0] and values[1].
  x = ((int)values[1]<<8)|(int)values[0];
  //The Y value is stored in values[2] and values[3].
  y = ((int)values[3]<<8)|(int)values[2];
  //The Z value is stored in values[4] and values[5].
  z = ((int)values[5]<<8)|(int)values[4];
  Serial.println("Accelerometer 1");
//  Serial.print(x, DEC);
//  Serial.print(',');
//  Serial.print(y, DEC);
//  Serial.print(',');
//  Serial.println(z, DEC);      
  xg = x*0.0078;
  yg = y*0.0078;
  zg = z*0.0078;
  //Print the results to the terminal.
  Serial.println("");
//  Serial.println("Accelerometer Reading");   
  Serial.print("X - axis: ");Serial.println(xg);
  Serial.print("Y - axis: ");Serial.println(yg);
  Serial.print("Z - axis: ");Serial.println(zg);
//  Serial.println("Readings stored in 'log01'. ");
  Serial.println("");
  delay(300); 
      //Put the ADXL345 into +/- 4G range by writing the value 0x01 to the DATA_FORMAT register.
  writeRegister(DATA_FORMAT, 0x01,CS2);
  //Put the ADXL345 into Measurement Mode by writing 0x08 to the POWER_CTL register.
  writeRegister(POWER_CTL, 0x08,CS2);  //Measurement mode  
  //Reading 6 bytes of data starting at register DATAX0 will retrieve the x,y and z acceleration values from the ADXL345.
  //The results of the read operation will get stored to the values[] buffer.
  readRegister(DATAX0, 6, values,CS2);
//The ADXL345 gives 10-bit acceleration values, but they are stored as bytes (8-bits). To get the full value, two bytes must be combined for each axis.
  //The X value is stored in values[0] and values[1].
  i = ((int)values[1]<<8)|(int)values[0];
  //The Y value is stored in values[2] and values[3].
  j = ((int)values[3]<<8)|(int)values[2];
  //The Z value is stored in values[4] and values[5].
  k = ((int)values[5]<<8)|(int)values[4];
  Serial.println("Accelerometer 2");
//  Serial.print(i, DEC);
//  Serial.print(',');
//  Serial.print(j, DEC);
//  Serial.print(',');
//  Serial.println(k, DEC); 
  ig = i*0.0078;
  jg = j*0.0078;
  kg = k*0.0078;
//  Serial.println("Accelerometer Reading");   
  Serial.print("I - axis: ");Serial.println(ig);
  Serial.print("J - axis: ");Serial.println(jg);
  Serial.print("K - axis: ");Serial.println(kg);
//  Serial.println("Readings stored in 'log01'. ");  
  Serial.println("");
    delay(300); 


//Put the ADXL345 into +/- 4G range by writing the value 0x01 to the DATA_FORMAT register.
  writeRegister(DATA_FORMAT, 0x01,CS3);
  //Put the ADXL345 into Measurement Mode by writing 0x08 to the POWER_CTL register.
  writeRegister(POWER_CTL, 0x08,CS3);  //Measurement mode  
  //Reading 6 bytes of data starting at register DATAX0 will retrieve the x,y and z acceleration values from the ADXL345.
  //The results of the read operation will get stored to the values[] buffer.
  readRegister(DATAX0, 6, values,CS3);
//The ADXL345 gives 10-bit acceleration values, but they are stored as bytes (8-bits). To get the full value, two bytes must be combined for each axis.
  //The X value is stored in values[0] and values[1].
  a = ((int)values[1]<<8)|(int)values[0];
  //The Y value is stored in values[2] and values[3].
  b = ((int)values[3]<<8)|(int)values[2];
  //The Z value is stored in values[4] and values[5].
  c = ((int)values[5]<<8)|(int)values[4];
    
  Serial.println("Accelerometer 3");
//  Serial.print(a, DEC);
//  Serial.print(',');
//  Serial.print(b, DEC);
//  Serial.print(',');
//  Serial.println(c, DEC); 
  ag = a*0.0078;
  bg = b*0.0078;
  cg = c*0.0078;
//  Serial.println("Accelerometer Reading");   
  Serial.print("A - axis: ");Serial.println(ag);
  Serial.print("B - axis: ");Serial.println(bg);
  Serial.print("C - axis: ");Serial.println(cg);
//  Serial.println("Readings stored in 'log01'. ");  
  Serial.println("");     
  delay(300); 
}

//This function will write a value to a register on the ADXL345.
//Parameters:
//  char registerAddress - The register to write a value to
//  char value - The value to be written to the specified register.
void writeRegister(char registerAddress, char value,int CS){
  //Set Chip Select pin low to signal the beginning of an SPI packet.
  digitalWrite(CS, 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(CS, 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,int CS){
  //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(CS, 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 i=0; i<numBytes; i++){
    values[i] = SPI.transfer(0x00);
  }
  //Set the Chips Select pin high to end the SPI packet.
  digitalWrite(CS, HIGH);
}

I'm not troubleshooting that code. The first thing I see is you using a function parameter name that is already used by the compiler (CS). That will cause you confusion.

Does the code work?

edit: I think it may not. Are these the pins you are using for the CS lines?

//Assign the Chip Select signal to pin 10.
int CS1=1;
int CS2=2;
int CS3=3;

SurferTim:
I’m not troubleshooting that code. The first thing I see is you using a function parameter name that is already used by the compiler (CS). That will cause you confusion.

Does the code work?

edit: I think it may not. Are these the pins you are using for the CS lines?

//Assign the Chip Select signal to pin 10.

int CS1=1;
int CS2=2;
int CS3=3;

Yes, I am using them as my CS lines. It is working for 3 ADXL. The code is nothing fanciful. I actually just copied and set two more cs from the original tutorial from sparkfun.

EDIT The CS pins that I used are pins 2,3,5

I have looked at a few sample codes and trying to understand the logic. hmm, how do I actually on and off the 3 ADXL345 in the writeRegister and readRegister?

#include <SD.h>
File myFile;
//Add the SPI library so we can communicate with the ADXL345 sensor
#include <SPI.h>

//Assign the Chip Select signal to pin 10.
int CS1=2;
int CS2=3;
int CS3=5;

//This is a list of some of the registers available on the ADXL345.
//To learn more about these and the rest of the registers on the ADXL345, read the datasheet!
char POWER_CTL = 0x2D;  //Power Control Register
char DATA_FORMAT = 0x31;
char DATAX0 = 0x32; //X-Axis Data 0
char DATAX1 = 0x33; //X-Axis Data 1
char DATAY0 = 0x34; //Y-Axis Data 0
char DATAY1 = 0x35; //Y-Axis Data 1
char DATAZ0 = 0x36; //Z-Axis Data 0
char DATAZ1 = 0x37; //Z-Axis Data 1

//This buffer will hold values read from the ADXL345 registers.
char values[10];
//These variables will be used to hold the x,y and z axis accelerometer values.
int x,y,z;
float xg, yg, zg;

int i,j,k;
float ig,jg,kg;

int a,b,c;
float ag,bg,cg;


void setup(){ 
  //Initiate an SPI communication instance.
  SPI.begin();
  //Configure the SPI connection for the ADXL345.
  SPI.setDataMode(SPI_MODE3);
  //Create a serial connection to display the data on the terminal.
  Serial.begin(9600);
  
  //Set up the Chip Select pin to be an output from the Arduino.
  pinMode(CS1, OUTPUT);
  //Before communication starts, the Chip Select pin needs to be set high.
  digitalWrite(CS1, HIGH);
    //Set up the Chip Select pin to be an output from the Arduino.
  pinMode(CS2, OUTPUT);
  //Before communication starts, the Chip Select pin needs to be set high.
  digitalWrite(CS2, HIGH);

   pinMode(CS3, OUTPUT);
  //Before communication starts, the Chip Select pin needs to be set high.
  digitalWrite(CS3, HIGH);

  SPI.setDataMode(SPI_MODE0);
      pinMode(4, OUTPUT);
       
      if (!SD.begin(4)) {
        Serial.println("initialization failed!");
        return;
      }
      Serial.println("initialization done.");
     
      myFile = SD.open("test.txt", FILE_WRITE);
      if (myFile)
      {
        Serial.print("Setting up... ");
      myFile.print("Time");
      myFile.print("\t");
        
      //myFile.close();
      Serial.println("Setup comlete.");
      }
      else
      {
        Serial.println("Error opening file.");
      }
}

void loop(){
    //Put the ADXL345 into +/- 4G range by writing the value 0x01 to the DATA_FORMAT register.
  writeRegister(DATA_FORMAT, 0x01,CS1);
  //Put the ADXL345 into Measurement Mode by writing 0x08 to the POWER_CTL register.
  writeRegister(POWER_CTL, 0x08,CS1);  //Measurement mode  
  //Reading 6 bytes of data starting at register DATAX0 will retrieve the x,y and z acceleration values from the ADXL345.
  //The results of the read operation will get stored to the values[] buffer.
  readRegister(DATAX0, 6, values,CS1);

  //The ADXL345 gives 10-bit acceleration values, but they are stored as bytes (8-bits). To get the full value, two bytes must be combined for each axis.
  //The X value is stored in values[0] and values[1].
  x = ((int)values[1]<<8)|(int)values[0];
  //The Y value is stored in values[2] and values[3].
  y = ((int)values[3]<<8)|(int)values[2];
  //The Z value is stored in values[4] and values[5].
  z = ((int)values[5]<<8)|(int)values[4];
  Serial.println("Accelerometer 1");    
  xg = x*0.0078;
  yg = y*0.0078;
  zg = z*0.0078;
  //Print the results to the terminal.
  Serial.println("");
//  Serial.println("Accelerometer Reading");   
  Serial.print("X - axis: ");Serial.println(xg);
  Serial.print("Y - axis: ");Serial.println(yg);
  Serial.print("Z - axis: ");Serial.println(zg);
//  Serial.println("Readings stored in 'log01'. ");
  Serial.println("");
  delay(300); 
      //Put the ADXL345 into +/- 4G range by writing the value 0x01 to the DATA_FORMAT register.
  writeRegister(DATA_FORMAT, 0x01,CS2);
  //Put the ADXL345 into Measurement Mode by writing 0x08 to the POWER_CTL register.
  writeRegister(POWER_CTL, 0x08,CS2);  //Measurement mode  
  //Reading 6 bytes of data starting at register DATAX0 will retrieve the x,y and z acceleration values from the ADXL345.
  //The results of the read operation will get stored to the values[] buffer.
  readRegister(DATAX0, 6, values,CS2);
//The ADXL345 gives 10-bit acceleration values, but they are stored as bytes (8-bits). To get the full value, two bytes must be combined for each axis.
  //The X value is stored in values[0] and values[1].
  i = ((int)values[1]<<8)|(int)values[0];
  //The Y value is stored in values[2] and values[3].
  j = ((int)values[3]<<8)|(int)values[2];
  //The Z value is stored in values[4] and values[5].
  k = ((int)values[5]<<8)|(int)values[4];
  Serial.println("Accelerometer 2");

  ig = i*0.0078;
  jg = j*0.0078;
  kg = k*0.0078;
//  Serial.println("Accelerometer Reading");   
  Serial.print("I - axis: ");Serial.println(ig);
  Serial.print("J - axis: ");Serial.println(jg);
  Serial.print("K - axis: ");Serial.println(kg);
//  Serial.println("Readings stored in 'log01'. ");  
  Serial.println("");
    delay(300); 


//Put the ADXL345 into +/- 4G range by writing the value 0x01 to the DATA_FORMAT register.
  writeRegister(DATA_FORMAT, 0x01,CS3);
  //Put the ADXL345 into Measurement Mode by writing 0x08 to the POWER_CTL register.
  writeRegister(POWER_CTL, 0x08,CS3);  //Measurement mode  
  //Reading 6 bytes of data starting at register DATAX0 will retrieve the x,y and z acceleration values from the ADXL345.
  //The results of the read operation will get stored to the values[] buffer.
  readRegister(DATAX0, 6, values,CS3);
//The ADXL345 gives 10-bit acceleration values, but they are stored as bytes (8-bits). To get the full value, two bytes must be combined for each axis.
  //The X value is stored in values[0] and values[1].
  a = ((int)values[1]<<8)|(int)values[0];
  //The Y value is stored in values[2] and values[3].
  b = ((int)values[3]<<8)|(int)values[2];
  //The Z value is stored in values[4] and values[5].
  c = ((int)values[5]<<8)|(int)values[4];
    
  Serial.println("Accelerometer 3");
  ag = a*0.0078;
  bg = b*0.0078;
  cg = c*0.0078;
//  Serial.println("Accelerometer Reading");   
  Serial.print("A - axis: ");Serial.println(ag);
  Serial.print("B - axis: ");Serial.println(bg);
  Serial.print("C - axis: ");Serial.println(cg);
//  Serial.println("Readings stored in 'log01'. ");  
  Serial.println("");     

  myFile.print(xg);
  myFile.print(",");
  myFile.print(jg);
  myFile.print(",");
  myFile.print(cg);
  myFile.close();

  delay(300); 
}

//This function will write a value to a register on the ADXL345.
//Parameters:
//  char registerAddress - The register to write a value to
//  char value - The value to be written to the specified register.
void writeRegister(char registerAddress, char value,int CS1,int CS2, int CS3){
  //Set Chip Select pin low to signal the beginning of an SPI packet.
 digitalWrite(CS1, LOW);
  digitalWrite(CS2, LOW);
  digitalWrite(CS3, 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(CS1, HIGH);
  digitalWrite(CS2, HIGH);
  digitalWrite(CS3, 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,int CS1,int CS2, int CS3){
  //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(CS1, LOW);
  digitalWrite(CS2, LOW);
  digitalWrite(CS3, 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 i=0; i<numBytes; i++){
    values[i] = SPI.transfer(0x00);
  }
  //Set the Chips Select pin high to end the SPI packet.
  digitalWrite(CS1, HIGH);
  digitalWrite(CS2, HIGH);
  digitalWrite(CS3, HIGH);
}

Please correct me, if i am wrong.

void readRegister(byte tcs, char registerAddress, int numBytes, char * values){ What is tcs for? Total CS??

SPI.setDataMode(SPI_MODE3); Call this SPI_mode to do the following command?

char address = 0x80 | registerAddress;

if(numBytes > 1)address = address | 0x40;

digitalWrite(tcs, LOW); On all three ADXL345?

SPI.transfer(address); transfer the data?

for(int i=0; i<numBytes; i++){
values = SPI.transfer(0x00);

  • }*

  • digitalWrite(tcs, HIGH); color=red]stop all three ADXL345?[/color]*

  • SPI.setDataMode(SPI_MODE0); ???*
    }
    void writeRegister(byte tcs, char registerAddress, char value){

  • SPI.setDataMode(SPI_MODE3); call this SPI_Mode*

  • digitalWrite(tcs, LOW); On the three ADXl345?*

  • SPI.transfer(registerAddress); Set the data format?*

  • SPI.transfer(value); collect and transfer the raw as DATAX0?*

  • digitalWrite(tcs, HIGH); Off the ADXL345*

  • SPI.setDataMode(SPI_MODE0); ???*
    }

Difficult to tell with all the colour tags and lack of code tags.

tcs is the temporary CS pin number. It is the digital pin that particular device CS is connected to. You read and write to/from one at a time.

edit: Read reply #3 again. That is how it works if the three ADXL345s are connected to D2, D3, and D5 respectively.