Alright the code now works. The code is below for reference:
To anyone who is trying to do what I was, keep in mind that SPI modes 1, 2, 3 and 4 have different meanings for different chips. So for example, with respect to this particular sensor, the Arduino Due needs to be set to SPI Mode 0, while the Mega needs to be set to SPI mode 1. Further, if you are using the Evaluation kit like I was, make sure that both the chip and the board are receiving power. In my case, I did not have to power the board separately when using the Mega, but did have to power it when using the Due. I hope, this is helpful to anyone trying to implement this.
[code]
#include <SPI.h>
SPISettings settings(6000000, MSBFIRST, SPI_MODE0 ); //variable to hold SPI settings
//Set Slave Select, MOSI, MISO, CLK
const int CSN = 4;
const int SO = 74;
const int SI = 75;
const int CLK = 76;
// Needed to convert the bytes from SPI to float
union u_types {
byte b[4];
float fval;
} data[3]; // Create 3 unions, one for each euler angle
void setup() {
//Set Pin Modes
pinMode(CSN, OUTPUT);
pinMode(SI, OUTPUT);
pinMode(SO, INPUT);
pinMode(CLK, OUTPUT);
//Set Slave Select High to Start i.e disable chip
digitalWrite(CSN, HIGH);
//Initialize SPI
SPI.begin();
//pour a bowl of serial
Serial.begin(9600);
}
//function to transfer commands through SPI
byte transferByte(byte byteToWrite) {
byte Result = 0x00;
digitalWrite(CSN,LOW);
delay(1);
Result = SPI.transfer(byteToWrite);
delay(1);
digitalWrite(CSN,HIGH);
return Result;
}
//function to swap endian
void endianSwap(byte temp[4]) {
byte myTemp = temp[0];
temp[0] = temp[3];
temp[3] = myTemp;
myTemp = temp[1];
temp[1] = temp[2];
temp[2] = myTemp;
}
void loop() {
SPI.beginTransaction(settings);
// Clear the internal data buffer on the IMU
byte result = transferByte(0x01);
Serial.print("Cleared internal buffer. Result: "),Serial.println(result);
// Send start of packet:
result = transferByte(0xF6);
Serial.print("Send start of packet. Result: "),Serial.println(result);
// Send command (tared euler angles)
result = transferByte(0x01);
Serial.print("Send commmand 0x01. Result: "),Serial.println(result);
// Get status of device:
result = transferByte(0xFF);
Serial.print("Status of device. Result: "),Serial.println(result);
while (result != 0x01) { // Repeat until device is Ready
delay(1);
result = transferByte(0xFF);
Serial.print("Status of device. Result: "),Serial.println(result);
}
// Get the 12 bytes of return data from the device:
for (int ii=0; ii<3; ii++) {
for (int jj=0; jj<4; jj++) {
data[ii].b[jj] = transferByte(0xFF);
delay(1);
}
}
SPI.endTransaction();
for( int mm=0; mm<3; mm++) {
endianSwap(data[mm].b);
}
Serial.print("fval 1:"), Serial.println(data[0].fval);
Serial.print("fval 2:"), Serial.println(data[1].fval);
Serial.print("fval 3:"), Serial.println(data[2].fval);
delay(3000);
}
[/code]
i'm running an exact copy of this code (adapted to an Arduino UNO on the SPI settings and pin locations) and it outputs full 0xFFs, am I missing something?
ArjanS96
Hello,
I am having serious issues with getting the 3 space sensor working with an Arduino Due. Here is my code for reference
[code/]
#include <SPI.h>
//Set Slave Select Pin
//MOSI, MISO, CLK are handeled automatically
const int CSN = 4;
const int SO = 74;
const int SI = 75;
const int CLK = 76 ;
// Needed to convert the bytes from SPI to float
union u_types {
byte b[4];
float fval;
} data[3]; // Create 3 unions, one for each euler angle
void setup() {
//Set Pin Modes
pinMode(CSN, OUTPUT);
pinMode(SI, OUTPUT);
pinMode(SO, INPUT);
pinMode(CLK, OUTPUT);
//Set Slave Select High to Start i.e disable chip
digitalWrite(CSN, HIGH);
//Initialize SPI and set SPI mode/bit order
SPI.begin();
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE0);
//pour a bowl of serial
Serial.begin(9600);
}
//function to transfer commands through SPI
byte transferByte(byte byteToWrite) {
byte Result = 0x00;
digitalWrite(CSN,LOW);
delay(1);
Result = SPI.transfer(byteToWrite);
delay(1);
digitalWrite(CSN,HIGH);
return Result;
}
//function to swap endian
void endianSwap(byte temp[4]) {
byte myTemp = temp[0];
temp[0] = temp[3];
temp[3] = myTemp;
myTemp = temp[1];
temp[1] = temp[2];
temp[2] = myTemp;
}
void loop() {
// Clear the internal data buffer on the IMU
byte result = transferByte(0x01);
Serial.print("Cleared internal buffer. Result: "),Serial.println(result);
// Send start of packet:
result = transferByte(0xF6);
Serial.print("Send start of packet. Result: "),Serial.println(result);
// Send command (tared euler angles)
result = transferByte(0x01);
Serial.print("Send commmand 0x01. Result: "),Serial.println(result);
// Get status of device:
result = transferByte(0xFF);
Serial.print("Status of device. Result: "),Serial.println(result);
while (result != 0x01) { // Repeat until device is Ready
result = transferByte(0xFF);
Serial.print("Status of device. Result: "),Serial.println(result);
}
// Get the 12 bytes of return data from the device:
for (int ii=0; ii<3; ii++) {
for (int jj=0; jj<4; jj++) {
data[ii].b[jj] = transferByte(0xFF);
delay(1);
}
}
for( int mm=0; mm<3; mm++) {
endianSwap(data[mm].b);
}
Serial.print("fval 1:"), Serial.println(data[0].fval);
Serial.print("fval 2:"), Serial.println(data[1].fval);
Serial.print("fval 3:"), Serial.println(data[2].fval);
delay(1000);
}
[code/]
After I send the command (0x01), and read, waiting for a 0x01, I end up getting random numbers, followed by zeroes (Which, I believe means that the sensor is idle), and never actually get the one. So, if you look at the code, this means that I just get stuck in the while loop. I suspect it might be a timing issue, so I added delays in my function "transferByte", but with no luck.
I would really appreciate help on the matter.