0

I am pairing an Arduino UNO with a Yost Labs 3-Space Sensor Nano, the user manual for said sensor can be found here and the user manual for the sensor family here (kinda confusing, Yost Lab's documentation contradicts itself IMO)

This is my code, pretty straight forward (although this is my first time working with SPI). I am 100% sure the wiring is correct, and I have attached a diagram of my wiring here. The logic voltage converter I am using is this

I believe that as per the user manual, this should successfully return 3 floats in 4 bytes each, corresponding to the filtered euler angles of pitch, yaw, and roll. However, all I am reading is bytes full of 0xFF (or 11111111 in binary) which I believe corresponds to null / no command.

Are there any visible errors in my code?

#include <SPI.h>

SPISettings settings(6000000, MSBFIRST, SPI_MODE0 ); //variable to hold SPI settings
//Set Slave Select, MOSI, MISO, CLK 
const int CSN = 10;
const int SI = 11;
const int SO = 12;
const int CLK = 13;

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

You almost certainly shouldn't raise CSN after each byte, only after the entire packet.

Although the data sheet is not explicit the chip select is usually used to frame an entire command. As it is at the moment it keeps starting a new transaction.

I like the comment in the data sheet that "...the 3-Space Sensor will not work properly in outer space or on planets with no magnetic field".

| improve this answer | |
  • I've tried moving the CSN raise around and no luck, where would you put it? Intuitively, I would do CSN low and the start of the void loop, and high right at the end. – hat_tr1ck Jul 17 at 2:03
  • It should go low before the first command byte of a packet and be raised after the last data is received. The data sheet is very difficult to understand, they mention sending 0x69 to read SPI data but no reference to that elsewhere. Have you tried using one of the other modes of data transfer - serial ASCII would be the easiest to debug. – Kevin White Jul 17 at 2:50
  • just tried low before the first command byte and raised after the last data is received, did not work. have not tried ASCII (I also have 0 experience with that) – hat_tr1ck Jul 17 at 3:10

Not the answer you're looking for? Browse other questions tagged or ask your own question.