Are you Ready for this? I HAVE AN ANSWER! It took me about 2 weeks of constant work to get this thing to talk to the arduino correctly. So I'm not professional programmer. I'm working mostly off of understandings I learned in VB 10 years ago in high school so there may be a more elegant way to structure this than what I've done. I'm more than open to ideas if someone finds an easier way but the internet is pretty dry on Xsense - Arduino communications. So I'll give you my hardware setup, post my code, and answer questions if need be.
FIRST: You have to match the levels. I used This { SparkFun RS232 Shifter - SMD - PRT-00449 - SparkFun Electronics }handy little level shifter from spark fun to make sure the RS232 speaking xsense could talk to my 5V TTL arduino. If you don't have a level shifter you're going to have a bad day because occasionally things like the preamble, BID, and MID will come through correctly then you get Gobbly Gook after that (Sorry about the technical terminology).
SECOND: When you read from the xsense you're reading a float (which is made of 4 bytes) one byte at a time. I couldn't figure out how to put these together so after some searching through C coding sites I found that you could define a variable as both a float AND an array of bytes[]. For example
union {
byte asByte[4];
float asFloat;
} xsensLatitude;
So you can read in one byte at a time xsensLatitude.asByte[3] = Serial.read();
then read out one float Serial.print(xsensLatitude.asFloat);
LAST: It is much easier to get the output mode you want using the MT Manager. The outputmode will stay on your xsens even after it's shut down so then all you have to do is read it with the arduino rather than configuring it with the arduino (which is possible if you want to go there.
EXAMPLE TIME: So I'm going to post the code that I used. Before running this on the arduino I used MT Manager to set up the Xsens so that it only put out position and and status (make sure to select none under angles if you're running this exactly). I used ArduinoMEGA2560 with the Xsens on Serial1 and the computer plugged in through USB.
EDIT I accidentally posted the wrong sketch the first time. This is what I meant to post EDIT
//0xFA preamble
byte gotoConfig[] = {0xFA,0xFF,0x30,0x00,0xD1};
byte gotoMeasurement[] = {0xFA,0xFF,0x10,0x00,0xF1};
byte setOutputSkipFactor[] = {0xFA,0x01,0xD4,0x02,0xFF,0xFF,0x2B};
byte reqData[] = {0xFA,0x01,0x34,0x00,0xCB};
byte inByte = 0x00;
byte xsensBID,xsensMID,xsensLEN,xsensCHECKSUM,xsensSTATUS;
union {
byte asByte[4];
float asFloat;
} xsensLatitude;
union {
byte asByte[4];
float asFloat;
} xsensLongitude;
union {
byte asByte[4];
float asFloat;
} xsensAltitude;
union {
byte asByte[2];
unsigned int asInt;
} xsensSample;
void setup(){
Serial.begin(115200);
Serial1.begin(115200);
xsensConfigure();
}
void loop() {
/*poll xsens for a message*/
xsensGetData();
delay(1000);
}
/*********************************************************
This function is to take the MTData message from xsens and
place it into global variables which can be recorded by the
microcontroller
**********************************************************/
void xsensGetData(){
byte xsensBuffer[100];
int i = 0;
Serial1.write(reqData,5);
//Serial.print("\nRequest Data");
while(Serial1.available() ==0){}
while(Serial1.available()){
xsensBuffer[i] = Serial1.read();
i++;
}
xsensBID=xsensBuffer[1];
xsensMID=xsensBuffer[2];
xsensLEN=xsensBuffer[3];
if(xsensBID==0xFF && xsensMID == 0x32){
//Latitude, longitude, altitude
xsensLatitude.asByte[3] = xsensBuffer[4];
xsensLatitude.asByte[2] = xsensBuffer[5];
xsensLatitude.asByte[1] = xsensBuffer[6];
xsensLatitude.asByte[0] = xsensBuffer[7];
xsensLongitude.asByte[3] = xsensBuffer[8];
xsensLongitude.asByte[2] = xsensBuffer[9];
xsensLongitude.asByte[1] = xsensBuffer[10];
xsensLongitude.asByte[0] = xsensBuffer[11];
xsensAltitude.asByte[3] = xsensBuffer[12];
xsensAltitude.asByte[2] = xsensBuffer[13];
xsensAltitude.asByte[1] = xsensBuffer[14];
xsensAltitude.asByte[0] = xsensBuffer[15];
xsensSTATUS = xsensBuffer[16];
xsensSample.asByte[1] = xsensBuffer[17];
xsensSample.asByte[0] = xsensBuffer[18];
xsensCHECKSUM = xsensBuffer[19];
byte byteSum = 0;
for(i = 1;i<=19;i++){
byteSum += xsensBuffer[i];
}
/*The following will print GPS Active - 1, Kalman filter active -1, latitude, longitude, altidude, sample number*/
Serial.print("MSG-0:");Serial.print(byteSum,HEX);
Serial.print("\tGPS:");Serial.print(bitRead(xsensSTATUS,2));
Serial.print("\tKXF:");Serial.print(bitRead(xsensSTATUS,1));
Serial.print("\t");Serial.print(xsensLatitude.asFloat,DEC);
Serial.print("\t");Serial.print(xsensLongitude.asFloat,DEC);
Serial.print("\t");Serial.print(xsensAltitude.asFloat,DEC);
Serial.print("\t");Serial.print(xsensSample.asInt,DEC);
xsensLatitude.asFloat = 0;
xsensLongitude.asFloat = 0;
xsensAltitude.asFloat = 0;
xsensSample.asInt = 0;
}//end if
Serial.print("\tBID:");
Serial.print(xsensBID,HEX);
Serial.print("\tMID:");
Serial.print(xsensMID,HEX);
Serial.print("\tLEN:");
Serial.print(xsensLEN,DEC);
Serial.print("\n");
}
/********************************************************
the purpose of this function is to configure the
xsens to only send data when it is polled
*********************************************************/
void xsensConfigure(){
byte xsensByte = 0x00;
int i = 0; //i is a generic counter
Serial.println("\nConfiguration Mode\n");
/*set xsens to configuration mode*/
Serial1.write(gotoConfig,5);
while(Serial1.available() ==0){}
while(Serial1.available()){
xsensByte = Serial1.read();
Serial.print(xsensByte);
Serial.print("\t");
delay(5);
}
/*Tells xsens to only send messagewhen polled*/
Serial.println("\nOnly send data when polled\n");
Serial1.write(setOutputSkipFactor,7);
while(Serial1.available() ==0){}
while(Serial1.available()){
xsensByte = Serial1.read();
Serial.print(xsensByte);
Serial.print("\t");
delay(5);
}
/*set xsens to configuration mode*/
Serial.println("\nMeasurement Mode\n");
Serial1.write(gotoMeasurement,5);
while(Serial1.available() ==0){}
while(Serial1.available()){
xsensByte = Serial1.read();
Serial.print(xsensByte);
Serial.print("\t");
delay(5);
}
Serial.print("\n");
}
/*Message Order
1. GPSPVT Data
2.Temp
3. Calibrated Data
4. Orientation Data
5. Auxiliary Data
6. Position (float - 4 BYTE)
7. Velocity (float - 4 BYTE)
8. Status
9. Sample (unsigned int 2 BYTES)
*/