SPI communication to the ADXRS450 gyroscope

I am trying to read the angular rate from register 0x00. I am getting a constant value all the time.

Here's the datasheet for the gyroscope:
http://www.analog.com/static/imported-files/data_sheets/ADXRS450.pdf?ref=ASC-PR-342

Help is greatly appreciated!

Here's my code:

#include <SPI.h>
unsigned int result;

const int chipSelectPin = 10;

void setup() {
Serial.begin(9600);
SPI.begin();

// initalize chip select pin:
pinMode(chipSelectPin, OUTPUT);
digitalWrite(chipSelectPin,HIGH);
SPI.setBitOrder(MSBFIRST);
SPI.setClockDivider(SPI_CLOCK_DIV8);
SPI.setDataMode(SPI_MODE3);
delay(100);
}

void loop() {
digitalWrite(chipSelectPin, LOW);
SPI.transfer(0x20);
SPI.transfer(0x00);
SPI.transfer(0x00);
delay(4);
result = SPI.transfer(0x00);
result = result << 8;
result |=SPI.transfer(0x00);
digitalWrite(chipSelectPin, HIGH);
Serial.println(result,DEC);
delay(500);
}

Commands and responses are all FOUR bytes. You are only sending three for the command and accepting two for the response.

The fourth byte of the command contains a parity bit. You will probably have to calculate that.

Thank you for your response. I have changed the code. I still have the same problem.

I always get the same exact value. I have checked my connections over and over. If nothing is wrong with this code, I am going to assume that the chip I am using is damaged!

Here's the modified code:
#include <SPI.h>
long result;
unsigned int byte2;
unsigned int byte3;
unsigned int byte4;
const int chipSelectPin = 10;

void setup() {
Serial.begin(9600);
SPI.begin();

// initalize chip select pin:
pinMode(chipSelectPin, OUTPUT);
digitalWrite(chipSelectPin,HIGH);
SPI.setBitOrder(MSBFIRST);
SPI.setClockDivider(SPI_CLOCK_DIV32);
SPI.setDataMode(SPI_MODE3);
delay(100);
}

void loop() {
digitalWrite(chipSelectPin, LOW);
// Sending 4 bytes as a command
SPI.transfer(0x20);
SPI.transfer(0x00);
SPI.transfer(0x00);
SPI.transfer(0x00);
delay(4);
result = SPI.transfer(0x00);
Serial.print("First byte: ");
Serial.println(result,BIN);
result = result << 24; // shift the first byte all the way to the left
byte2=SPI.transfer(0x00)<<16;
Serial.print("Second byte: ");
Serial.println(byte2,BIN);
result |=(byte2);
byte3=SPI.transfer(0x00)<<8;
Serial.print("Third byte: ");
Serial.println(byte3,BIN);
result |=(byte3);
byte4=SPI.transfer(0x00);
Serial.print("4rth byte: ");
Serial.println(byte4,BIN);
result |=(byte4);
digitalWrite(chipSelectPin, HIGH);
Serial.println(result,BIN);
delay(500);
}

maan:
I always get the same exact value.

By not telling us what value you get you guarantee that nobody can help further.

First byte: 1111111
Second byte: 0
Third byte: 1111111100000000
4rth byte: 11111111

1111111000000001111111111111111

maan:
First byte: 1111111
Second byte: 0
Third byte: 1111111100000000
4rth byte: 11111111

1111111000000001111111111111111

It's impossible for the third byte to contain 16 bits so perhaps you should try again.

Try replacing this code:

  digitalWrite(chipSelectPin, LOW);
  // Sending 4 bytes as a command
  SPI.transfer(0x20);
  SPI.transfer(0x00);
  SPI.transfer(0x00);
  SPI.transfer(0x00);
  delay(4);
  result = SPI.transfer(0x00);
  Serial.print("First byte: ");
  Serial.println(result,BIN);
  result = result << 24; // shift the first byte all the way to the left
  byte2=SPI.transfer(0x00)<<16;
  Serial.print("Second byte: ");
  Serial.println(byte2,BIN);
  result |=(byte2);
  byte3=SPI.transfer(0x00)<<8;
  Serial.print("Third byte: ");
  Serial.println(byte3,BIN);
  result |=(byte3);
  byte4=SPI.transfer(0x00);
  Serial.print("4rth byte: ");
  Serial.println(byte4,BIN);
  result |=(byte4);
  digitalWrite(chipSelectPin, HIGH);
  Serial.println(result,BIN);

with this:

  digitalWrite(chipSelectPin, LOW);
  // Sending 4 bytes as a command
  SPI.transfer(0x20);
  SPI.transfer(0x00);
  SPI.transfer(0x00);
  SPI.transfer(0x00);
  digitalWrite(chipSelectPin, HIGH);  // End of command

  delay(4);

  digitalWrite(chipSelectPin, LOW);   // Start of data retrieval
  result = SPI.transfer(0x00);
  Serial.print("One byte: ");
  Serial.println(result,HEX);

  result = result << 8 | SPI.transfer(0x00);
  Serial.print("Two bytes: ");
  Serial.println(result,HEX);

  result = result << 8 | SPI.transfer(0x00);
  Serial.print("Three bytes: ");
  Serial.println(result,HEX);

  result = result << 8 | SPI.transfer(0x00);
  Serial.print("Four bytes: ");
  Serial.println(result,HEX);

  digitalWrite(chipSelectPin, HIGH);

Any more tips on this device? I am having a hard time reading the data. It should be easy, but so far it isn't.

// the sensor communicates using SPI, so include the library:
#include <SPI.h>
long result;

const int chipSelectPin = 7;

void setup() {
  Serial.begin(9600);

  // start the SPI library:
  SPI.begin();

  pinMode(7, OUTPUT);
  digitalWrite(7,HIGH);
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV32);
  SPI.setDataMode(SPI_MODE3);
  delay(100);
 
}

void loop() {
 

  digitalWrite(7, LOW);
  // Sending 4 bytes as a command
  SPI.transfer(0x20);
  SPI.transfer(0x00);
  SPI.transfer(0x00);
  SPI.transfer(0x00);
  digitalWrite(7, HIGH);  // End of command

  delay(4);

  digitalWrite(7, LOW);   // Start of data retrieval
  
  result = SPI.transfer(0x00);
  result = result << 8 | SPI.transfer(0x00);
  result = result << 8 | SPI.transfer(0x00);
  result = result << 8 | SPI.transfer(0x00);
  Serial.println(result);
  digitalWrite(7, HIGH);
  delay(100);

}

Currently, the only output is; 1006895115, no matter how I move the device.

SuperR:

void loop() {

digitalWrite(7, LOW);
 // Sending 4 bytes as a command
 SPI.transfer(0x20);
 SPI.transfer(0x00);
 SPI.transfer(0x00);
 SPI.transfer(0x00);

digitalWrite(7, HIGH);  // End of command
                         delay(4);
                         digitalWrite(7, LOW);   // Start of data retrieval
 
 result = SPI.transfer(0x00);
 result = result << 8 | SPI.transfer(0x00);
 result = result << 8 | SPI.transfer(0x00);
 result = result << 8 | SPI.transfer(0x00);
 Serial.println(result);
 digitalWrite(7, HIGH);
 delay(100);
}

I'm sorry I failed to mention it before but it would be highly unusual for the Slave Select pin (7) to be set HIGH between the sending of the command and the receiving of the data. Try removing the three indented lines.

Thanks for your reply. I removed the lines and had no succes. The output is -1 now, that's it. Stupid thing is, I have a (cheap ebay salae clone) logic analyser laying around in the house, but I cannot find it. I did find 'the missing roll of solder' though.

SuperR:
Thanks for your reply. I removed the lines and had no succes. The output is -1 now, that's it.

I was wrong. I just looked at the datasheet again and your previous code was right. As you send out Command-N you receive the results from the previous command (N-1). The command and response are two different transactions.

It might be time to give up on the ADXRS450 and get a easier to use gyroscope. :frowning:

How hard can it be? It's 'just' SPI. Next to that, I purchased three of these expensive badboys.

SuperR:
How hard can it be? It's 'just' SPI.

There's bit order, byte order, mode, and various parity bits to get right. That may take a very close reading of the datasheet.

I asked the device nicely, and it works now. I did not change much, set the clock polarity and phase to 0 and used an extra integer to store the lowest 6 bits from the data. That´s it. Data looks good.

#include <SPI.h>

int result;
int result2;
int Gyro1;

void setup() {
  Serial.begin(9600);
  SPI.begin();

  pinMode(7, OUTPUT);
  digitalWrite(7,HIGH);
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV16); 
  SPI.setDataMode(SPI_MODE0);
  delay(100);
 
}

void loop() {
 

  digitalWrite(7, LOW);
  result = SPI.transfer(0x20);
  result = result << 8 | SPI.transfer(0x00);
  result2 = SPI.transfer(0x00) >>2;
  SPI.transfer(0x00);
  result = result << 6 | result2;
  digitalWrite(7, HIGH);  

  Gyro1 = (Gyro1)*0.5 + result*(1 - 0.5);

  Serial.println(Gyro1);

}