Start a new topic

Using YEI 3-space sensor with Arduino Due, using SPI

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. 

1 Comment

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]



Login or Signup to post a comment