SPI communications with an Yost Labs IMU 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 &lt;SPI.h&gt;

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(&quot;Cleared internal buffer. Result: &quot;),Serial.println(result);

 // Send start of packet:
 result = transferByte(0xF6);
      Serial.print(&quot;Send start of packet. Result: &quot;),Serial.println(result);
 
 // Send command (tared euler angles)
 result = transferByte(0x01);
      Serial.print(&quot;Send commmand 0x01. Result: &quot;),Serial.println(result);
 
 // Get status of device:
 result = transferByte(0xFF);
      Serial.print(&quot;Status of device. Result: &quot;),Serial.println(result);

 while (result != 0x01) {  // Repeat until device is Ready
   delay(1);
   result = transferByte(0xFF);
   Serial.print(&quot;Status of device. Result: &quot;),Serial.println(result);
 }
 
 // Get the 12 bytes of return data from the device:
 for (int ii=0; ii&lt;3; ii++) {
   for (int jj=0; jj&lt;4; jj++) {
     data[ii].b[jj] =  transferByte(0xFF);
     delay(1);
   }
 }  

 SPI.endTransaction();

 for( int mm=0; mm&lt;3; mm++) {
   endianSwap(data[mm].b);
 }
 
 
 Serial.print(&quot;fval 1:&quot;), Serial.println(data[0].fval);
 Serial.print(&quot;fval 2:&quot;), Serial.println(data[1].fval);
 Serial.print(&quot;fval 3:&quot;), Serial.println(data[2].fval);

 delay(3000);
}
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 &quot;...the 3-Space Sensor will not work properly in outer space or on planets with no magnetic field&quot;.