├── README.md
├── Test Setup.jpg
└── x_IMU_Arduino_Example
├── Quaternion.cpp
├── Quaternion.h
├── XimuReceiver.cpp
├── XimuReceiver.h
└── x_IMU_Arduino_Example.ino
/README.md:
--------------------------------------------------------------------------------
1 | x-IMU-Arduino-Example
2 | =====================
3 |
4 | Generic C++ library for receiving data from the [x-IMU](http://www.x-io.co.uk/x-imu/), implemented and tested with Arduino. x-IMU auxiliary port must be configured for UART mode, see x_IMU_Arduino_Example.ino for details.
5 |
6 | =========
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Test Setup.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xioTechnologies/x-IMU-Arduino-Example/0e524efdc00b717eb4eef4ba4bd5a1995da34e14/Test Setup.jpg
--------------------------------------------------------------------------------
/x_IMU_Arduino_Example/Quaternion.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Quaternion.cpp
3 | Author: Seb Madgwick
4 |
5 | C++ library for basic usage of quaternions.
6 | See: http://www.x-io.co.uk/quaternions/
7 | */
8 |
9 | //------------------------------------------------------------------------------
10 | // Includes
11 |
12 | #include "Quaternion.h"
13 | #include
14 |
15 | //------------------------------------------------------------------------------
16 | // Variables
17 |
18 | float q[4];
19 |
20 | //------------------------------------------------------------------------------
21 | // Methods
22 |
23 | Quaternion::Quaternion(void) {
24 | q[0] = 1.0f;
25 | q[1] = 0.0f;
26 | q[2] = 0.0f;
27 | q[3] = 0.0f;
28 | }
29 |
30 | Quaternion::Quaternion(const float w, const float x, const float y, const float z) {
31 | q[0] = w;
32 | q[1] = x;
33 | q[2] = y;
34 | q[3] = z;
35 | }
36 |
37 | Quaternion Quaternion::getConjugate(void) const {
38 | Quaternion conjugate;
39 | conjugate.q[0] = q[0];
40 | conjugate.q[1] = -q[1];
41 | conjugate.q[2] = -q[2];
42 | conjugate.q[3] = -q[3];
43 | return conjugate;
44 | }
45 |
46 | EulerAnglesStruct Quaternion::getEulerAngles(void) const {
47 | EulerAnglesStruct eulerAnglesStruct;
48 | eulerAnglesStruct.roll = radiansToDegrees(atan2(2.0f * (q[2] * q[3] - q[0] * q[1]), 2.0f * q[0] * q[0] - 1.0f + 2.0f * q[3] * q[3]));
49 | eulerAnglesStruct.pitch = radiansToDegrees(-atan((2.0f * (q[1] * q[3] + q[0] * q[2])) / sqrt(1.0f - pow((2.0f * q[1] * q[3] + 2.0f * q[0] * q[2]), 2.0f))));
50 | eulerAnglesStruct.yaw = radiansToDegrees(atan2(2.0f * (q[1] * q[2] - q[0] * q[3]), 2.0f * q[0] * q[0] - 1.0f + 2.0f * q[1] * q[1]));
51 | return eulerAnglesStruct;
52 | }
53 |
54 | float Quaternion::radiansToDegrees (float radians) const {
55 | return 57.2957795130823f * radians;
56 | }
57 |
58 | //------------------------------------------------------------------------------
59 | // End of file
60 |
--------------------------------------------------------------------------------
/x_IMU_Arduino_Example/Quaternion.h:
--------------------------------------------------------------------------------
1 | /*
2 | Quaternion.h
3 | Author: Seb Madgwick
4 |
5 | C++ library for basic usage of quaternions.
6 | See: http://www.x-io.co.uk/quaternions/
7 | */
8 |
9 | #ifndef Quaternion_h
10 | #define Quaternion_h
11 |
12 | //------------------------------------------------------------------------------
13 | // Definitions
14 |
15 | typedef struct {
16 | float roll; /* rotation around x axis in degrees */
17 | float pitch; /* rotation around y axis in degrees */
18 | float yaw; /* rotation around z axis in degrees */
19 | } EulerAnglesStruct;
20 |
21 | //------------------------------------------------------------------------------
22 | // Class declaration
23 |
24 | class Quaternion {
25 | public:
26 | Quaternion(void);
27 | Quaternion(const float w, const float x, const float y, const float z);
28 | Quaternion getConjugate(void) const;
29 | EulerAnglesStruct getEulerAngles(void) const;
30 |
31 | private:
32 | float q[4];
33 | float radiansToDegrees (float radians) const;
34 | };
35 |
36 | #endif
37 |
38 | //------------------------------------------------------------------------------
39 | // End of file
40 |
--------------------------------------------------------------------------------
/x_IMU_Arduino_Example/XimuReceiver.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | XimuReceiver.cpp
3 | Author: Seb Madgwick
4 |
5 | C++ library for receiving data from the x-IMU. Current implementation
6 | supports only a few packet types.
7 |
8 | See x_IMU_Arduino_Example.ino for example usage.
9 | */
10 |
11 | //------------------------------------------------------------------------------
12 | // Includes
13 |
14 | #include "XimuReceiver.h"
15 |
16 | //------------------------------------------------------------------------------
17 | // Definitions
18 |
19 | enum PacketHeaders {
20 | PKT_ERROR,
21 | PKT_COMMAND,
22 | PKT_READ_REGISTER,
23 | PKT_WRITE_REGISTER,
24 | PKT_READ_DATE_TIME,
25 | PKT_WRITE_DATE_TIME,
26 | PKT_RAW_BATTERY_AND_THERMOMETER_DATA,
27 | PKT_CAL_BATTERY_AND_THERMOMETER_DATA,
28 | PKT_RAW_INERTIAL_AND_MAGNETIC_DATA,
29 | PKT_CAL_INERTIAL_AND_MAGNETIC_DATA,
30 | PKT_QUATERNION_DATA,
31 | PKT_DIGITAL_IO_DATA,
32 | PKT_RAW_ANALOGUE_INPUT_DATA,
33 | PKT_CAL_ANALOGUE_INPUT_DATA,
34 | PKT_PWM_OUTPUT_DATA,
35 | PKT_RAW_DXL345_BUS_DATA,
36 | PKT_CAL_DXL345_BUS_DATA,
37 | };
38 |
39 | enum PacketLengths {
40 | LEN_ERROR = 4,
41 | LEN_COMMAND = 6,
42 | LEN_READ_REGISTER = 4,
43 | LEN_WRITE_REGISTER = 8,
44 | LEN_READ_DATE_TIME = 2,
45 | LEN_WRITE_DATE_TIME = 8,
46 | LEN_RAW_BATTERY_AND_THERMOMETER_DATA = 6,
47 | LEN_CAL_BATTERY_AND_THERMOMETER_DATA = 6,
48 | LEN_RAW_INERTIAL_AND_MAGNETIC_DATA = 20,
49 | LEN_CAL_INERTIAL_AND_MAGNETIC_DATA = 20,
50 | LEN_QUATERNION_DATA = 10,
51 | LEN_DIGITAL_IO_DATA = 4,
52 | LEN_RAW_ANALOGUE_INPUT_DATA = 18,
53 | LEN_CAL_ANALOGUE_INPUT_DATA = 18,
54 | LEN_PWM_OUTPUT_DATA = 10,
55 | LEN_RAW_DXL345_BUS_DATA = 26,
56 | LEN_CAL_DXL345_BUS_DATA = 26,
57 | };
58 |
59 |
60 | typedef enum {
61 | Q_CALIBRATED_BATTERY = 12,
62 | Q_CALIBRATED_THERMOEMTER = 8,
63 | Q_CALIBRATED_GYROSCOPE = 4,
64 | Q_CALIBRATED_ACCELEROEMETER = 11,
65 | Q_CALIBRATED_MAGNETOMETER = 11,
66 | Q_QUATERNION = 15,
67 | Q_BATTERY_SENSITIVITY = 5,
68 | Q_BATTERY_BIAS = 8,
69 | Q_THERMOMETER_SENSITIVITY = 6,
70 | Q_THERMOMETER_BIAS = 0,
71 | Q_GYROSCOPE_SENSITIVITY = 7,
72 | Q_GYROSCOPE_SAMPLED_200DPS = 0,
73 | Q_GYROSCOPE_BIAS_AT_25DEGC = 3,
74 | Q_GYROSCOPE_BIAS_TEMP_SENSITIVITY = 11,
75 | Q_GYROSCOPE_SAMPLED_BIAS = 3,
76 | Q_ACCELEROMETER_SENSITIVITY = 4,
77 | Q_ACCELEROMETER_BIAS = 8,
78 | Q_ACCELEROMETER_Sampled1g = 4,
79 | Q_MAGNETOMETER_SENSITIVITY = 4,
80 | Q_MAGNETOMETER_BIAS = 8,
81 | Q_MAGNETOMETER_HARD_IRON_BIAS = 11,
82 | Q_ALGORITHM_KP = 11,
83 | Q_ALGORITHM_KI = 15,
84 | Q_ALGORITHM_INIT_KP = 11,
85 | Q_ALGORITHM_INIT_PERIOD = 11,
86 | Q_CALIBRATED_ANALOGUE_INPUT = 12,
87 | Q_ANALOGUE_INPUT_SENSITIVITY = 4,
88 | Q_ANALOGUE_INPUT_BIAS = 8,
89 | Q_CALIRBATED_ADXL345 = 10,
90 | Q_ADXL345_BUS_SENSITIVITY = 6,
91 | Q_ADXL345_BUS_BIAS = 8,
92 | } FixedQ;
93 |
94 | //------------------------------------------------------------------------------
95 | // Variables
96 |
97 | // Serial stream decoding
98 | unsigned char buf[256];
99 | unsigned char bufIndex = 0;
100 |
101 | // Decoded data
102 | BattAndThermStruct battAndThermStruct = { 0.0f, 0.0f };
103 | InertialAndMagStruct inertialAndMagStruct = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
104 | QuaternionStruct quaternionStruct = { 1.0f, 0.0f, 0.0f, 0.0f };
105 |
106 | // Data ready flags
107 | bool battAndThermGetReady = false;
108 | bool inertialAndMagGetReady = false;
109 | bool quaternionGetReady = false;
110 |
111 | //------------------------------------------------------------------------------
112 | // Methods
113 |
114 | XimuReceiver::XimuReceiver() {
115 | }
116 |
117 | ErrorCode XimuReceiver::processNewChar(unsigned char c) {
118 |
119 | // Add new byte to buffer
120 | buf[bufIndex++] = c;
121 |
122 | // Process receive buffer if framing char received
123 | if(c & 0x80) {
124 |
125 | // Calculate packet size
126 | int packetSize = bufIndex - 1 - ((bufIndex - 1) >> 3);
127 | bufIndex = 0; //reset index
128 |
129 | // Extract packet (truncate to discard all msb)
130 | unsigned char packet[256];
131 | packet[0] = (buf[0 ] << 1) | (buf[1 ] >> 6);
132 | packet[1] = (buf[1 ] << 2) | (buf[2 ] >> 5);
133 | packet[2] = (buf[2 ] << 3) | (buf[3 ] >> 4);
134 | packet[3] = (buf[3 ] << 4) | (buf[4 ] >> 3);
135 | packet[4] = (buf[4 ] << 5) | (buf[5 ] >> 2);
136 | packet[5] = (buf[5 ] << 6) | (buf[6 ] >> 1);
137 | packet[6] = (buf[6 ] << 7) | (buf[7 ] >> 0);
138 | packet[7] = (buf[8 ] << 1) | (buf[9 ] >> 6);
139 | packet[8] = (buf[9 ] << 2) | (buf[10] >> 5);
140 | packet[9] = (buf[10] << 3) | (buf[11] >> 4);
141 | packet[10] = (buf[11] << 4) | (buf[12] >> 3);
142 | packet[11] = (buf[12] << 5) | (buf[13] >> 2);
143 | packet[12] = (buf[13] << 6) | (buf[14] >> 1);
144 | packet[13] = (buf[14] << 7) | (buf[15] >> 0);
145 | packet[14] = (buf[16] << 1) | (buf[17] >> 6);
146 | packet[15] = (buf[17] << 2) | (buf[18] >> 5);
147 | packet[16] = (buf[18] << 3) | (buf[19] >> 4);
148 | packet[17] = (buf[19] << 4) | (buf[20] >> 3);
149 | packet[18] = (buf[20] << 5) | (buf[21] >> 2);
150 | packet[19] = (buf[21] << 6) | (buf[22] >> 1);
151 | packet[20] = (buf[22] << 7) | (buf[23] >> 0);
152 | packet[21] = (buf[24] << 1) | (buf[25] >> 6);
153 | packet[22] = (buf[25] << 2) | (buf[26] >> 5);
154 | packet[23] = (buf[26] << 3) | (buf[27] >> 4);
155 | packet[24] = (buf[27] << 4) | (buf[28] >> 3);
156 | packet[25] = (buf[28] << 5) | (buf[29] >> 2);
157 | packet[26] = (buf[29] << 6) | (buf[30] >> 1);
158 | packet[27] = (buf[30] << 7) | (buf[31] >> 0);
159 |
160 | /*
161 | TODO: Verify checksum here, if fail then return ERR_INVALID_CHECKSUM;
162 | */
163 |
164 | // Interpret packet according to header
165 | switch(packet[0]) {
166 |
167 | case PKT_CAL_BATTERY_AND_THERMOMETER_DATA:
168 | if(packetSize != LEN_CAL_BATTERY_AND_THERMOMETER_DATA) {
169 | return ERR_INVALID_NUM_BYTES_FOR_PACKET_HEADER;
170 | }
171 | battAndThermStruct.battery = fixedToFloat(concat(packet[1], packet[2]), Q_CALIBRATED_BATTERY);
172 | battAndThermStruct.thermometer = fixedToFloat(concat(packet[3], packet[4]), Q_CALIBRATED_THERMOEMTER);
173 | battAndThermGetReady = true;
174 | break;
175 |
176 | case(PKT_CAL_INERTIAL_AND_MAGNETIC_DATA):
177 | if(packetSize != LEN_CAL_INERTIAL_AND_MAGNETIC_DATA) {
178 | return ERR_INVALID_NUM_BYTES_FOR_PACKET_HEADER;
179 | }
180 | inertialAndMagStruct.gyrX = fixedToFloat(concat(packet[1], packet[2]), Q_CALIBRATED_GYROSCOPE);
181 | inertialAndMagStruct.gyrY = fixedToFloat(concat(packet[3], packet[4]), Q_CALIBRATED_GYROSCOPE);
182 | inertialAndMagStruct.gyrZ = fixedToFloat(concat(packet[5], packet[6]), Q_CALIBRATED_GYROSCOPE);
183 | inertialAndMagStruct.accX = fixedToFloat(concat(packet[7], packet[8]), Q_CALIBRATED_ACCELEROEMETER);
184 | inertialAndMagStruct.accY = fixedToFloat(concat(packet[9], packet[10]), Q_CALIBRATED_ACCELEROEMETER);
185 | inertialAndMagStruct.accZ = fixedToFloat(concat(packet[11], packet[12]), Q_CALIBRATED_ACCELEROEMETER);
186 | inertialAndMagStruct.magX = fixedToFloat(concat(packet[13], packet[14]), Q_CALIBRATED_MAGNETOMETER);
187 | inertialAndMagStruct.magY = fixedToFloat(concat(packet[15], packet[16]), Q_CALIBRATED_MAGNETOMETER);
188 | inertialAndMagStruct.magZ = fixedToFloat(concat(packet[17], packet[18]), Q_CALIBRATED_MAGNETOMETER);
189 | inertialAndMagGetReady = true;
190 | break;
191 |
192 | case(PKT_QUATERNION_DATA):
193 | if(packetSize != LEN_QUATERNION_DATA) {
194 | return ERR_INVALID_NUM_BYTES_FOR_PACKET_HEADER;
195 | }
196 | quaternionStruct.w = fixedToFloat(concat(packet[1], packet[2]), Q_QUATERNION);
197 | quaternionStruct.x = fixedToFloat(concat(packet[3], packet[4]), Q_QUATERNION);
198 | quaternionStruct.y = fixedToFloat(concat(packet[5], packet[6]), Q_QUATERNION);
199 | quaternionStruct.z = fixedToFloat(concat(packet[7], packet[8]), Q_QUATERNION);
200 | quaternionGetReady = true;
201 | break;
202 |
203 | default:
204 | break;
205 | }
206 | }
207 | return ERR_NO_ERROR;
208 | }
209 |
210 | float XimuReceiver::fixedToFloat(const short fixed, const unsigned char q) const {
211 | return (float)fixed / (float)(1 << q);
212 | }
213 |
214 | unsigned short XimuReceiver::concat(const unsigned char msb, const unsigned char lsb) const {
215 | return ((unsigned short)msb << 8) | (unsigned short)lsb;
216 | }
217 |
218 | bool XimuReceiver::isBattAndThermGetReady(void) const {
219 | return battAndThermGetReady;
220 | }
221 |
222 | bool XimuReceiver::isInertialAndMagGetReady(void) const {
223 | return inertialAndMagGetReady;
224 | }
225 |
226 | bool XimuReceiver::isQuaternionGetReady(void) const {
227 | return quaternionGetReady;
228 | }
229 |
230 | BattAndThermStruct XimuReceiver::getBattAndTherm(void) {
231 | battAndThermGetReady = false;
232 | return battAndThermStruct;
233 | }
234 |
235 | InertialAndMagStruct XimuReceiver::getInertialAndMag(void) {
236 | inertialAndMagGetReady = false;
237 | return inertialAndMagStruct;
238 | }
239 |
240 | QuaternionStruct XimuReceiver::getQuaternion(void) {
241 | quaternionGetReady = false;
242 | return quaternionStruct;
243 | }
244 |
245 | //------------------------------------------------------------------------------
246 | // End of file
--------------------------------------------------------------------------------
/x_IMU_Arduino_Example/XimuReceiver.h:
--------------------------------------------------------------------------------
1 | /*
2 | XimuReceiver.h
3 | Author: Seb Madgwick
4 |
5 | C++ library for receiving data from the x-IMU. Current implementation
6 | supports only a few packet types.
7 |
8 | See x_IMU_Arduino_Example.ino for example usage.
9 | */
10 |
11 | #ifndef XimuReceiver_h
12 | #define XimuReceiver_h
13 |
14 | //------------------------------------------------------------------------------
15 | // Definitions
16 |
17 | typedef enum {
18 | ERR_NO_ERROR,
19 | ERR_FACTORY_RESET_FAILED,
20 | ERR_LOW_BATTERY,
21 | ERR_USB_RECEIVE_BUFFER_OVERRUN,
22 | ERR_USB_TRANSMIT_BUFFER_OVERRUN,
23 | ERR_BLUETOOTH_RECEIVE_BUFFER_OVERRUN,
24 | ERR_BLUETOOTH_TRANSMIT_BUFFER_OVERRUN,
25 | ERR_SD_CARD_WRITE_BUFFER_OVERRUN,
26 | ERR_TOO_FEW_BYTES_IN_PACKET,
27 | ERR_TOO_MANY_BYTES_IN_PACKET,
28 | ERR_INVALID_CHECKSUM,
29 | ERR_UNKNOWN_HEADER,
30 | ERR_INVALID_NUM_BYTES_FOR_PACKET_HEADER,
31 | ERR_INVALID_REGISTER_ADDRESS,
32 | ERR_REGISTER_READ_ONLY,
33 | ERR_INVALID_REGSITER_VALUE,
34 | ERR_INVALID_COMMAND,
35 | ERR_GYROSCOPE_AXIS_NOT_AT_200DPS,
36 | ERR_GYROSCOPE_NOT_STATIONARY,
37 | ERR_ACCELEROMETER_AXIS_NOT_AT_1G,
38 | ERR_MMAGNETOMETER_SATURATION,
39 | ERR_INCORRECT_AUXILIARY_PORT_MODE,
40 | ERR_UART_RECEIVE_BUFFER_OVERRUN,
41 | ERR_UART_TRANSMIT_BUFFER_OVERRUN,
42 | } ErrorCode;
43 |
44 | typedef struct {
45 | float battery; /* battery voltage in V */
46 | float thermometer; /* thermometer in degC */
47 | } BattAndThermStruct;
48 |
49 | typedef struct {
50 | float gyrX; /* gyroscope x axis in dps */
51 | float gyrY; /* gyroscope y axis in dps */
52 | float gyrZ; /* gyroscope z axis in dps */
53 | float accX; /* accelerometer x axis in g */
54 | float accY; /* accelerometer y axis in g */
55 | float accZ; /* accelerometer z axis in g */
56 | float magX; /* magnetometer x axis in Ga */
57 | float magY; /* magnetometer y axis in Ga */
58 | float magZ; /* magnetometer z axis in Ga */
59 | } InertialAndMagStruct;
60 |
61 | typedef struct {
62 | float w;
63 | float x;
64 | float y;
65 | float z;
66 | } QuaternionStruct;
67 |
68 | //------------------------------------------------------------------------------
69 | // Class declaration
70 |
71 | class XimuReceiver {
72 | public:
73 | XimuReceiver(void);
74 | ErrorCode processNewChar(unsigned char c);
75 | bool isBattAndThermGetReady(void) const;
76 | bool isInertialAndMagGetReady(void) const;
77 | bool isQuaternionGetReady(void) const;
78 | BattAndThermStruct getBattAndTherm(void);
79 | InertialAndMagStruct getInertialAndMag(void);
80 | QuaternionStruct getQuaternion(void);
81 |
82 | private:
83 | unsigned char buf[256];
84 | unsigned char bufIndex;
85 | BattAndThermStruct battAndThermStruct;
86 | InertialAndMagStruct inertialAndMagStruct;
87 | QuaternionStruct quaternionStruct;
88 | bool battAndThermGetReady;
89 | bool inertialAndMagGetReady;
90 | bool quaternionGetReady;
91 | float fixedToFloat(const short fixed, const unsigned char q) const;
92 | unsigned short concat(const unsigned char msb, const unsigned char lsb) const;
93 | };
94 |
95 | #endif
96 |
97 | //------------------------------------------------------------------------------
98 | // End of file
99 |
--------------------------------------------------------------------------------
/x_IMU_Arduino_Example/x_IMU_Arduino_Example.ino:
--------------------------------------------------------------------------------
1 | /*
2 | x_IMU_Arduino_Example.ino
3 | Author: Seb Madgwick
4 |
5 | Example usage of x-IMU C++ library. Also uses the quaternion library to
6 | convert the received quaternion to Euler angles.
7 |
8 | Requires two hardware serial modules: one to receive from the x-IMU and one
9 | to transmit the decoded data to be displayed on computer.
10 |
11 | x-IMU settings:
12 | Auxiliary Port > Auxiliary Port Mode: "UART"
13 | Auxiliary Port > UART > Baud Rate: 115200
14 | Auxiliary Port > UART > Hardware Flow Control: Off
15 |
16 | Hardware connections:
17 | x-IMU GND -> Arduino MEGA GND
18 | x-IMU EXT -> Arduino MEGA 5V
19 | x-IMU AX2 -> Arduino MEGA RX1
20 |
21 | Tested with "arduino-1.0.3" and "Arduino MEGA".
22 | */
23 |
24 | //------------------------------------------------------------------------------
25 | // Includes
26 |
27 | #include "Quaternion.h"
28 | #include "XimuReceiver.h"
29 |
30 | //------------------------------------------------------------------------------
31 | // Variables
32 |
33 | XimuReceiver ximuReceiver;
34 |
35 | //------------------------------------------------------------------------------
36 | // Functions
37 |
38 | void setup() {
39 | Serial.begin(115200); // for sending data to computer
40 | Serial1.begin(115200); // for receiving data from x-IMU
41 | }
42 |
43 | void loop() {
44 | ErrorCode e = ERR_NO_ERROR;
45 |
46 | // Process recieved data
47 | while(Serial1.available() > 0) {
48 | e = ximuReceiver.processNewChar(Serial1.read());
49 | }
50 |
51 | // Print error code (receive error)
52 | if(e != ERR_NO_ERROR) {
53 | Serial.print("ERROR: ");
54 | Serial.print(e);
55 | Serial.print("\r");
56 | }
57 |
58 | // Print battery and thermometer data
59 | if(ximuReceiver.isBattAndThermGetReady()) {
60 | BattAndThermStruct battAndThermStruct = ximuReceiver.getBattAndTherm();
61 | Serial.print("battery = ");
62 | Serial.print(battAndThermStruct.battery);
63 | Serial.print(", thermometer = ");
64 | Serial.print(battAndThermStruct.thermometer);
65 | Serial.print("\r");
66 | }
67 |
68 | // Print sensor data
69 | if(ximuReceiver.isInertialAndMagGetReady()) {
70 | InertialAndMagStruct inertialAndMagStruct = ximuReceiver.getInertialAndMag();
71 | Serial.print("gyrX = ");
72 | Serial.print(inertialAndMagStruct.gyrX);
73 | Serial.print(", gyrY = ");
74 | Serial.print(inertialAndMagStruct.gyrY);
75 | Serial.print(", gyrZ = ");
76 | Serial.print(inertialAndMagStruct.gyrZ);
77 | Serial.print(", accX = ");
78 | Serial.print(inertialAndMagStruct.accX);
79 | Serial.print(", accY = ");
80 | Serial.print(inertialAndMagStruct.accY);
81 | Serial.print(", accZ = ");
82 | Serial.print(inertialAndMagStruct.accZ);
83 | Serial.print(", magX = ");
84 | Serial.print(inertialAndMagStruct.magX);
85 | Serial.print(", magY = ");
86 | Serial.print(inertialAndMagStruct.magY);
87 | Serial.print(", magZ = ");
88 | Serial.print(inertialAndMagStruct.magZ);
89 | Serial.print("\r");
90 | }
91 |
92 | // Print quaternion data as Euler angles
93 | if(ximuReceiver.isQuaternionGetReady()) {
94 | QuaternionStruct quaternionStruct = ximuReceiver.getQuaternion();
95 | Quaternion quaternion = Quaternion(quaternionStruct.w, quaternionStruct.x, quaternionStruct.y, quaternionStruct.z);
96 | EulerAnglesStruct eulerAnglesStruct = quaternion.getEulerAngles();
97 | Serial.print("roll = ");
98 | Serial.print(eulerAnglesStruct.roll);
99 | Serial.print(", pitch = ");
100 | Serial.print(eulerAnglesStruct.pitch);
101 | Serial.print(", yaw = ");
102 | Serial.print(eulerAnglesStruct.yaw);
103 | Serial.print("\r");
104 | }
105 | }
106 |
107 | //------------------------------------------------------------------------------
108 | // End of file
109 |
--------------------------------------------------------------------------------