How to read register value from ADXL345 Eval board?

HI i am working on a project regarding using ADXL345 eval board (http://www.sparkfun.com/datasheets/Sensors/Accelerometer/ADXLEvalBoard%20User_Guide2009-09-14.pdf)
and arduino Uno and few servo motors (as outputs)

Now i met a bottleneck. The connection is direct connection from adxl 345eval board to arduino. So i need to get the value out from the register (0x32 till 0x37) in adxl345. In the first stage, i am using a LED to indicate whether i can read the register value or not..but it fail anyway. Anyone can please check the error for me?

Btw noted that direct connection from adxl345 eval board to arduino is using USB connection. Arduino Uno -> ADXL345 eval board (USB connected)

Here is my code:

int ledPin = 2;                 // LED connected to digital pin 2
#include <Wire.h>
#define DEVICE (0x53)   //define the address for DEVICE

void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(57600);  // start serial for output
  writeTo(DEVICE, 0x2D, 0);         //here is the part that I enable the bit in the register in 2D and 2E. for INT and Power configuration
  writeTo(DEVICE, 0x2D, 16);
  writeTo(DEVICE, 0x2D, 8);
  writeTo(DEVICE, 0x2E, 128);      
  writeTo(DEVICE, 0x2E, 2);
  writeTo(DEVICE, 0x2E, 1);
  pinMode(ledPin, OUTPUT);      // sets the digital pin as output
}

The read and write function:

void readfrom(int device, byte address)
{
  int temp = 0;
  Wire.beginTransmission(device); //start transmission to device 
  Wire.write(address);        //sends address to read from
  Wire.endTransmission(); //end transmission

  Wire.beginTransmission(device);
  Wire.requestFrom(device,1);
  
  while(Wire.available())
  {
    int c = Wire.read();
    if (c != temp){
  digitalWrite(ledPin, HIGH);   // sets the LED on
  delay(1000);}              // waits for a second
  else{
  digitalWrite(ledPin, LOW);    // sets the LED off
  delay(1000); }                 // waits for a second
  temp =c;
  }//end while loop.
  Wire.endTransmission(); //end transmission
}

void writeTo(int device, byte address, byte val) {
   Wire.beginTransmission(device); //start transmission to device 
   Wire.write(address);        // send register address
   Wire.write(val);        // send value to write
   Wire.endTransmission(); //end transmission
}

The loop function:

readfrom (0x53, address);

Obviously i am using I2C library....now i am wondering that will this code works if i am using USB connection?any replied is highly appreciate... :slight_smile:

In readFrom() you have an extra Wire.beginTransmission().

johnwasser:
In readFrom() you have an extra Wire.beginTransmission().

sorry i have a mistake just now, i correct my code already. it is not extra Wire.beginTransmission(). just i forgot to end the transmission since i begin another transmission again...

Now the 1st consideration is that i am USB connection. so is that problem if i am using I2C for coding??

The schematic (http://www.sparkfun.com/datasheets/Sensors/Accelerometer/ADXL345_Eval_Board-v11.pdf) shows the ADXL345 is connected to A0,A1,A2,and A3 and appears to use Soft SPI. Nothing is connected to the I2C bus so the Wire library won't help you any. Perhaps you should start with the source code from the product page (SparkFun Evaluation Board - ADXL345 - SEN-09814 - SparkFun Electronics)

johnwasser:
The schematic (http://www.sparkfun.com/datasheets/Sensors/Accelerometer/ADXL345_Eval_Board-v11.pdf) shows the ADXL345 is connected to A0,A1,A2,and A3 and appears to use Soft SPI. Nothing is connected to the I2C bus so the Wire library won't help you any. Perhaps you should start with the source code from the product page (SparkFun Evaluation Board - ADXL345 - SEN-09814 - SparkFun Electronics)

thanks so much...before that i noticed from schematic diagram, it seem like did not using I2C but SPI.I cant confirm..and i have no advanced people who can guide me on this...thanks...but i did try the source code but it is not arduino code...it is just normal C programming code regarding on this board..may i know what can i do on this code?and what software u can recommend me to compile it?...

sorry for all these noob question. i am a beginner by the way. Thanks

Some of the functions can be adapted:

#define ACCEL_CS	A0
#define ACCEL_SCK	A1
#define ACCEL_DI		A2
#define ACCEL_DO	A3

#define SELECT_ACCEL()        digitalWrite(ACCEL_CS, LOW)
#define UNSELECT_ACCEL()    digitalWrite(ACCEL_CS, HIGH)

#define CLOCK_HIGH()	        digitalWrite(ACCEL_SCK, HIGH)
#define CLOCK_LOW()		digitalWrite(ACCEL_SCK, LOW)

char adxl345_read(char register_address){
	char read_address=0x80 | register_address;
	char register_value=0;
	
	CLOCK_HIGH();
	SELECT_ACCEL();	//Lower CS pin.
	
	for(int bit=7; bit>=0; bit--){
		CLOCK_LOW();
                digitalWrite(DI, read_address & (1<<bit));
		delayMicroseconds(1);
		CLOCK_HIGH();
		delayMicroseconds(1);
	}
	
	for(int bit=7; bit>=0; bit--){
		CLOCK_LOW();
		delayMicroseconds(1);
		
		CLOCK_HIGH();
		delayMicroseconds(1);
		
		register_value |= digitalRead(ADXL_DI)<<bit;
	}
	
	UNSELECT_ACCEL();
	
	return register_value;
}

johnwasser:
Some of the functions can be adapted:

#define ACCEL_CS	A0

#define ACCEL_SCK A1
#define ACCEL_DI A2
#define ACCEL_DO A3

#define SELECT_ACCEL()        digitalWrite(ACCEL_CS, LOW)
#define UNSELECT_ACCEL()    digitalWrite(ACCEL_CS, HIGH)

#define CLOCK_HIGH()         digitalWrite(ACCEL_SCK, HIGH)
#define CLOCK_LOW() digitalWrite(ACCEL_SCK, LOW)

char adxl345_read(char register_address){
char read_address=0x80 | register_address;
char register_value=0;

CLOCK_HIGH();
SELECT_ACCEL();	//Lower CS pin.

for(int bit=7; bit>=0; bit--){
	CLOCK_LOW();

digitalWrite(DI, read_address & (1<<bit));
delayMicroseconds(1);
CLOCK_HIGH();
delayMicroseconds(1);
}

for(int bit=7; bit>=0; bit--){
	CLOCK_LOW();
	delayMicroseconds(1);
	
	CLOCK_HIGH();
	delayMicroseconds(1);
	
	register_value |= digitalRead(ADXL_DI)<<bit;
}

UNSELECT_ACCEL();

return register_value;

}

from your advice, i notice that some are defined frm A0 - A3....may i know what i can use for this?is that for analog pin?because my intention is for usb connection..

i had modify my code to be like this:
setup:

int ledPin = 2;                 // LED connected to digital pin 13
int ledPin1 = 3;
int _spiPin;
byte buff[6] ;
#include <SPI.h>
#define DEVICE 0x00
#define TO_READ (6)

void setup()
{
  SPI.begin();
  SPI.setDataMode(SPI_MODE3);
  Serial.begin(57600);  // start serial for output
  writeTo(DEVICE, 0x2D, 0);      
  writeTo(DEVICE, 0x2D, 16);
  writeTo(DEVICE, 0x2D, 8);
  writeTo(DEVICE, 0x2E, 128);      
  writeTo(DEVICE, 0x2E, 2);
  writeTo(DEVICE, 0x2E, 1);
  pinMode(ledPin, OUTPUT);
  pinMode(ledPin1, OUTPUT);  // sets the digital pin as output
}

loop:

void loop()
{
  byte address = 0x32;
  int temp;
  int x,y,z;
  readfrom (DEVICE, address, TO_READ, buff);
  x = (((int)buff[1]) << 8) | buff[0];
  if (x!=temp){
  digitalWrite(ledPin, HIGH);   // sets the LED on
  delay(1000);}              // waits for a second
  else{
  digitalWrite(ledPin, LOW);    // sets the LED off
  delay(1000); }                 // waits for a second
  temp = x;
}

read and write function:

void readfrom(int device, byte address, int num, byte buff[])
{
  int temp = 0;
  address = 0x80 | address;
  if (num > 1) address = address | 0x40;
  
  digitalWrite(_spiPin, LOW);
  SPI.transfer(address);             // sends address to read from
  for(int i = 0; i < num; i++)
  { 
    buff[i] = SPI.transfer(0x00);
  }
  //if (!SPI.available())digitalWrite(ledPin1, HIGH);
  digitalWrite(_spiPin, HIGH);
}

void writeTo(int device, byte address, byte val) {
  digitalWrite(_spiPin, LOW);
  SPI.transfer(address);             // send register address
  SPI.transfer(val);                // send value to write
  digitalWrite(_spiPin, HIGH);
}

i change it to use SPI...and why still wont work??i use a temp variable...to test whether the value is changing or not..if changing, then the LED would light up...but still fail to work on it........thanks and so appreciate your time..

tlslaj0417:
i change it to use SPI...and why still wont work??

See reply #3. The accelerometer is NOT connected to the hardware SPI pins. It is connected to A0-A3 (Pins 14-17).

johnwasser:

tlslaj0417:
i change it to use SPI...and why still wont work??

See reply #3. The accelerometer is NOT connected to the hardware SPI pins. It is connected to A0-A3 (Pins 14-17).

A0-A3 u mean is ADC0 till ADC3??(pin 23-26)...because pins 14-17 is for SPI right?....correct me if i am wrong...thanks

tlslaj0417:
A0-A3 u mean is ADC0 till ADC3??(pin 23-26)...because pins 14-17 is for SPI right?....correct me if i am wrong...thanks

ARDUINO pins 14-17 a.k.a. A0-A3. Yes, they are pins 23-26 on the ATmega chip.

Hardware SPI is on ARDUINO pins 10-13 which are pins 16-19 on the ATmega.

If you are going to use the Arduino libraries you should probably get used to calling the pins by their Arduino numbers to avoid confusion. You can learn more about the naming here: https://spreadsheets.google.com/spreadsheet/pub?key=0AtfNMvfWhA_ccnRId19SNmVWTDE0MEtTOV9HOEdQa0E&gid=0

johnwasser:

tlslaj0417:
A0-A3 u mean is ADC0 till ADC3??(pin 23-26)...because pins 14-17 is for SPI right?....correct me if i am wrong...thanks

ARDUINO pins 14-17 a.k.a. A0-A3. Yes, they are pins 23-26 on the ATmega chip.

Hardware SPI is on ARDUINO pins 10-13 which are pins 16-19 on the ATmega.

If you are going to use the Arduino libraries you should probably get used to calling the pins by their Arduino numbers to avoid confusion. You can learn more about the naming here: Arduino Pins - Google Drive

thanks for good reference..i will refer it when i calling the pins. and now i use the code u provided to me. as you said:
#define ACCEL_CS A0
#define ACCEL_SCK A1
#define ACCEL_DI A2
#define ACCEL_DO A3

then which pins i should connect to with all these 4 pins?or because of soft connection. i no need to connect it through any hardware?i just define it with these four pins?

johnwasser:
ARDUINO pins 14-17 a.k.a. A0-A3. Yes, they are pins 23-26 on the ATmega chip.

Hardware SPI is on ARDUINO pins 10-13 which are pins 16-19 on the ATmega.

If you are going to use the Arduino libraries you should probably get used to calling the pins by their Arduino numbers to avoid confusion. You can learn more about the naming here: Arduino Pins - Google Drive

hi John....sorry for use up your time for this. In the progress i edit my code till like this:
setup:

char adxl345_read(char address);
int ledPin = 2;
#define ACCEL_CS	A0
#define ACCEL_SCK	A1
#define ACCEL_DI	A2
#define ACCEL_DO	A3
#define DATAX0			0x32	//X-Axis Data 0
#define DATAX1			0x33	//X-Axis Data 1
#define DATAY0			0x34	//Y-Axis Data 0
#define DATAY1			0x35	//Y-Axis Data 1
#define DATAZ0			0x36	//Z-Axis Data 0
#define DATAZ1			0x37	//Z-Axis Data 1
#define SELECT_ACCEL()        digitalWrite(ACCEL_CS, LOW)
#define UNSELECT_ACCEL()    digitalWrite(ACCEL_CS, HIGH)

#define CLOCK_HIGH()	        digitalWrite(ACCEL_SCK, HIGH)
#define CLOCK_LOW()		digitalWrite(ACCEL_SCK, LOW)
#include <SPI.h>

void setup(){
  SPI.begin();
  Serial.begin(57600);
  pinMode(ledPin, OUTPUT);
}

read function:

char adxl345_read(char register_address){
	char read_address=0x80 | register_address;
	char register_value=0;
        char temp = 0;
	
	CLOCK_HIGH();
	SELECT_ACCEL();	//Lower CS pin.
	
        if (register_value!=temp)
            {
              digitalWrite(ledPin, HIGH);   // sets the LED on
              delay(1000);
             }
        else{
        digitalWrite(ledPin, LOW);    // sets the LED off
        delay(1000); }                 // waits for a second

	for(int bit=7; bit>=0; bit--){
		CLOCK_LOW();
                digitalWrite(ACCEL_DI, read_address & (1<<bit));
		delayMicroseconds(1);
		CLOCK_HIGH();
		delayMicroseconds(1);
	}
	
	for(int bit=7; bit>=0; bit--){
		CLOCK_LOW();
		delayMicroseconds(1);
		
		CLOCK_HIGH();
		delayMicroseconds(1);
		
		register_value |= digitalRead(ACCEL_DI)<<bit;
	}
	
	UNSELECT_ACCEL();
        temp = register_value;
	return register_value;
}

Loop:

void loop(){
  adxl345_read(DATAX0);
}

same i use ledpin to indicate the availability of the register_value....but still no given any response....following the reference that u gave:

i connect the A0-A3 to pin 11-13 (while pin 10 is not for SPI right?)...so is there any error?

Again, thanks for sparing your time on me. Appreciate so much :slight_smile:

Probably need:

    pinMode(ACCEL_CS, OUTPUT);
    pinMode(ACCEL_SCK, OUTPUT);
    pinMode(ACCEL_DI, OUTPUT);
    pinMode(ACCEL_DO, INPUT);

You don't seem to include any output in your sketch so I don't understand how you detect if it is working or not.

You can remove references to the SPI library since the adxl345_read() function does software SPI.

johnwasser:
Probably need:

    pinMode(ACCEL_CS, OUTPUT);

pinMode(ACCEL_SCK, OUTPUT);
    pinMode(ACCEL_DI, OUTPUT);
    pinMode(ACCEL_DO, INPUT);




You don't seem to include any output in your sketch so I don't understand how you detect if it is working or not.

You can remove references to the SPI library since the adxl345_read() function does software SPI.

while i am testing my circuit...would u mind to tell me what is the exact of software SPI and hardware SPI???software is that mean that is not exact hardware connection???..thanks

Plus: i do output to test it is working or not..i test with light up a LED...:slight_smile:
i test it if the register value change all the time thats mean register != temp (not equal to the value before) then the LED is light up.

if (register_value!=temp)
            {
              digitalWrite(ledPin, HIGH);   // sets the LED on
              delay(1000);
             }

Hi, i follow your advise, add all these
pinMode(ACCEL_CS, OUTPUT);
pinMode(ACCEL_SCK, OUTPUT);
pinMode(ACCEL_DI, OUTPUT);
pinMode(ACCEL_DO, INPUT);

but still no giving any output.... :~...really stuck now...

Show your sketch and I'll see if I can figure out what is wrong.

johnwasser:
Show your sketch and I'll see if I can figure out what is wrong.

Thanks so much!!! :smiley:
ok now i am referring here: ADXL345 Hookup Guide - SparkFun Learn

make my sketch to become like this:
Setup:

//Add the SPI library so we can communicate with the ADXL345 sensor
#include <SPI.h>
int CS=10;
#define ACCEL_CS	A0
#define ACCEL_SCK	A1
#define ACCEL_DI	A2
#define ACCEL_DO	A3
int ledPin = 2;
//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;

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(CS, OUTPUT);
  //Before communication starts, the Chip Select pin needs to be set high.
  digitalWrite(CS, HIGH);
  pinMode(ledPin, OUTPUT);
  pinMode(ACCEL_CS, OUTPUT);
  pinMode(ACCEL_SCK, OUTPUT);
  pinMode(ACCEL_DI, OUTPUT);
  pinMode(ACCEL_DO, INPUT);
  
  //Put the ADXL345 into +/- 4G range by writing the value 0x01 to the DATA_FORMAT register.
  writeRegister(DATA_FORMAT, 0x01);
  //Put the ADXL345 into Measurement Mode by writing 0x08 to the POWER_CTL register.
  writeRegister(POWER_CTL, 0x08);  //Measurement mode  
}

loop:

void loop(){
  //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);
  int temp;
  //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];
  if (EnsureConnected()){
       digitalWrite(ledPin, HIGH);   // sets the LED on
       delay(1000);}
        else{
        digitalWrite(ledPin, LOW);    // sets the LED off
        delay(1000); }                 // waits for a second
  //Print the results to the terminal.
 /* Serial.print(x, DEC);
  Serial.print(',');
  Serial.print(y, DEC);
  Serial.print(',');
  Serial.println(z, DEC);      
  delay(10); */
  temp = x;
}

write and read:

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);
}

Now i am just wondering..as i am using USB connection between adxl eval board and arduino...above SPI code can works or not?

In the loop function, i add a if else condition e.g :ensure connection() to test whether it is really getting any result or not....can you suggest me any condition that i can make to test whether i can read the register value or not?

Thousand thanks for you. =(

Make sure you don't have an SD card in the SD card slot. The SD card slot uses the hardware SPI pins (10-13) so if you put a card in the slot you can't use Pin 10 for anything else.

If you want to use the sketch from ADXL345 Hookup Guide - SparkFun Learn you will have to re-wire the evaluation board to connect the ADXL345 to pins 10-13 instead of pins 14-17 (A0-A3). You should not need to make any change to the sketch supplied with that tutorial.

johnwasser:
Make sure you don't have an SD card in the SD card slot. The SD card slot uses the hardware SPI pins (10-13) so if you put a card in the slot you can't use Pin 10 for anything else.

If you want to use the sketch from ADXL345 Hookup Guide - SparkFun Learn you will have to re-wire the evaluation board to connect the ADXL345 to pins 10-13 instead of pins 14-17 (A0-A3). You should not need to make any change to the sketch supplied with that tutorial.

thanks for your guidance..so that's mean instead of declare it by:
#define ACCEL_CS A0
#define ACCEL_SCK A1
#define ACCEL_DI A2
#define ACCEL_DO A3
i can change it to lets say:
#define ACCEL_CS 10
#define ACCEL_SCK 13
#define ACCEL_DI 11
#define ACCEL_DO 12

??then the rest of code works fine??ya i did read on the user guide of eval board said that SD card will used up the SPI so i didnt insert the SD card. Thanks for that also. Your explanation make my uncertainty clear. thanks so much. and actually with the code above, will it really works for USB connection?

and what do u mean by rewired??since the eval board is a complete module???sorry for any lame question....thanks so much^^

Edit: this is what i am connect for my arduino board. and this is act what i wan...hope u understand...i just draw it using mspaint...sorry for unclear picture.

Led is just use for testing...if really confirm getting the register value then i will replace it with servo motor.

The ADXL345 Evaluation Board is NOT a good choice if you want to connect the ADXL345 to an Arduino UNO. You should buy an ADXL345 on a breakout board: