1
+ /*
2
+ u-blox Example: ESF MEAS (Wheel Ticks)
3
+ By: Paul Clark
4
+ SparkFun Electronics
5
+ Date: December 19th, 2023
6
+ License: MIT. See license file for more information
7
+
8
+ This example configures the External Sensor Fusion MEAS sensor messages on the ZED-F9R and
9
+ shows how to access the ESF data using callbacks.
10
+
11
+ Feel like supporting open source hardware?
12
+ Buy a board from SparkFun!
13
+ ZED-F9R: https://www.sparkfun.com/products/22660
14
+
15
+ Hardware Connections:
16
+ Plug a Qwiic cable into the GPS and a Redboard Qwiic
17
+ If you don't have a platform with a Qwiic connection use the
18
+ SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
19
+
20
+ Open the serial monitor at >>> 230400 <<< baud to see the output
21
+
22
+ */
23
+
24
+ #include < Wire.h> // Needed for I2C to GPS
25
+
26
+ #include < SparkFun_u-blox_GNSS_v3.h> // http://librarymanager/All#SparkFun_u-blox_GNSS_v3
27
+ SFE_UBLOX_GNSS myGNSS;
28
+
29
+ // Callback: printESFMEASdata will be called when new ESF MEAS data arrives
30
+ // See u-blox_structs.h for the full definition of UBX_ESF_MEAS_data_t
31
+ // _____ You can use any name you like for the callback. Use the same name when you call setAutoESFMEAScallback
32
+ // / _____ This _must_ be UBX_ESF_MEAS_data_t
33
+ // | / _____ You can use any name you like for the struct
34
+ // | | /
35
+ // | | |
36
+ void printESFMEASdata (UBX_ESF_MEAS_data_t *ubxDataStruct)
37
+ {
38
+ // New ESF MEAS data has arrived:
39
+
40
+ // Print the timeTag
41
+ Serial.print (F (" Time: " ));
42
+ Serial.println (ubxDataStruct->timeTag );
43
+
44
+ // ubxDataStruct->flags.bits.numMeas indicates how many sensor groups the UBX_ESF_MEAS_data_t contains.
45
+ for (uint8_t i = 0 ; i < ubxDataStruct->flags .bits .numMeas ; i++)
46
+ {
47
+ // Print the sensor data type
48
+ // From the M8 interface description:
49
+ // 0: None
50
+ // 1-4: Reserved
51
+ // 5: z-axis gyroscope angular rate deg/s * 2^-12 signed
52
+ // 6: front-left wheel ticks: Bits 0-22: unsigned tick value. Bit 23: direction indicator (0=forward, 1=backward)
53
+ // 7: front-right wheel ticks: Bits 0-22: unsigned tick value. Bit 23: direction indicator (0=forward, 1=backward)
54
+ // 8: rear-left wheel ticks: Bits 0-22: unsigned tick value. Bit 23: direction indicator (0=forward, 1=backward)
55
+ // 9: rear-right wheel ticks: Bits 0-22: unsigned tick value. Bit 23: direction indicator (0=forward, 1=backward)
56
+ // 10: speed ticks: Bits 0-22: unsigned tick value. Bit 23: direction indicator (0=forward, 1=backward)
57
+ // 11: speed m/s * 1e-3 signed
58
+ // 12: gyroscope temperature deg Celsius * 1e-2 signed
59
+ // 13: y-axis gyroscope angular rate deg/s * 2^-12 signed
60
+ // 14: x-axis gyroscope angular rate deg/s * 2^-12 signed
61
+ // 16: x-axis accelerometer specific force m/s^2 * 2^-10 signed
62
+ // 17: y-axis accelerometer specific force m/s^2 * 2^-10 signed
63
+ // 18: z-axis accelerometer specific force m/s^2 * 2^-10 signed
64
+ switch (ubxDataStruct->data [i].data .bits .dataType )
65
+ {
66
+ case 5 :
67
+ Serial.print (F (" Z Gyro: " ));
68
+ break ;
69
+ case 6 :
70
+ Serial.print (F (" Front Left: " ));
71
+ break ;
72
+ case 7 :
73
+ Serial.print (F (" Front Right: " ));
74
+ break ;
75
+ case 8 :
76
+ Serial.print (F (" Rear Left: " ));
77
+ break ;
78
+ case 9 :
79
+ Serial.print (F (" Rear Right: " ));
80
+ break ;
81
+ case 10 :
82
+ Serial.print (F (" Speed Ticks: " ));
83
+ break ;
84
+ case 11 :
85
+ Serial.print (F (" Speed: " ));
86
+ break ;
87
+ case 12 :
88
+ Serial.print (F (" Temp: " ));
89
+ break ;
90
+ case 13 :
91
+ Serial.print (F (" Y Gyro: " ));
92
+ break ;
93
+ case 14 :
94
+ Serial.print (F (" X Gyro: " ));
95
+ break ;
96
+ case 16 :
97
+ Serial.print (F (" X Accel: " ));
98
+ break ;
99
+ case 17 :
100
+ Serial.print (F (" Y Accel: " ));
101
+ break ;
102
+ case 18 :
103
+ Serial.print (F (" Z Accel: " ));
104
+ break ;
105
+ default :
106
+ break ;
107
+ }
108
+
109
+ // Tick data
110
+ if ((ubxDataStruct->data [i].data .bits .dataType >= 6 ) && (ubxDataStruct->data [i].data .bits .dataType <= 10 ))
111
+ {
112
+ if ((ubxDataStruct->data [i].data .bits .dataField & (1 << 23 )) > 0 )
113
+ Serial.print (F (" -" )); // Backward
114
+ else
115
+ Serial.print (F (" +" )); // Forward
116
+ Serial.println (ubxDataStruct->data [i].data .bits .dataField & 0x007FFFFF );
117
+ }
118
+ // Speed
119
+ else if (ubxDataStruct->data [i].data .bits .dataType == 11 )
120
+ {
121
+ union
122
+ {
123
+ int32_t signed32;
124
+ uint32_t unsigned32;
125
+ } signedUnsigned; // Avoid any ambiguity casting uint32_t to int32_t
126
+ // The dataField is 24-bit signed, stored in the 24 LSBs of a uint32_t
127
+ signedUnsigned.unsigned32 = ubxDataStruct->data [i].data .bits .dataField << 8 ; // Shift left by 8 bits to correctly align the data
128
+ float speed = signedUnsigned.signed32 ; // Extract the signed data. Convert to float
129
+ speed /= 256.0 ; // Divide by 256 to undo the shift
130
+ speed *= 0.001 ; // Convert from m/s * 1e-3 to m/s
131
+ Serial.println (speed, 3 );
132
+ }
133
+ // Gyro data
134
+ else if ((ubxDataStruct->data [i].data .bits .dataType == 5 ) || (ubxDataStruct->data [i].data .bits .dataType == 13 ) || (ubxDataStruct->data [i].data .bits .dataType == 14 ))
135
+ {
136
+ union
137
+ {
138
+ int32_t signed32;
139
+ uint32_t unsigned32;
140
+ } signedUnsigned; // Avoid any ambiguity casting uint32_t to int32_t
141
+ // The dataField is 24-bit signed, stored in the 24 LSBs of a uint32_t
142
+ signedUnsigned.unsigned32 = ubxDataStruct->data [i].data .bits .dataField << 8 ; // Shift left by 8 bits to correctly align the data
143
+ float rate = signedUnsigned.signed32 ; // Extract the signed data. Convert to float
144
+ rate /= 256.0 ; // Divide by 256 to undo the shift
145
+ rate *= 0.000244140625 ; // Convert from deg/s * 2^-12 to deg/s
146
+ Serial.println (rate);
147
+ }
148
+ // Accelerometer data
149
+ else if ((ubxDataStruct->data [i].data .bits .dataType == 16 ) || (ubxDataStruct->data [i].data .bits .dataType == 17 ) || (ubxDataStruct->data [i].data .bits .dataType == 18 ))
150
+ {
151
+ union
152
+ {
153
+ int32_t signed32;
154
+ uint32_t unsigned32;
155
+ } signedUnsigned; // Avoid any ambiguity casting uint32_t to int32_t
156
+ // The dataField is 24-bit signed, stored in the 24 LSBs of a uint32_t
157
+ signedUnsigned.unsigned32 = ubxDataStruct->data [i].data .bits .dataField << 8 ; // Shift left by 8 bits to correctly align the data
158
+ float force = signedUnsigned.signed32 ; // Extract the signed data. Convert to float
159
+ force /= 256.0 ; // Divide by 256 to undo the shift
160
+ force *= 0.0009765625 ; // Convert from m/s^2 * 2^-10 to m/s^2
161
+ Serial.println (force);
162
+ }
163
+ // Gyro Temperature
164
+ else if (ubxDataStruct->data [i].data .bits .dataType == 12 )
165
+ {
166
+ union
167
+ {
168
+ int32_t signed32;
169
+ uint32_t unsigned32;
170
+ } signedUnsigned; // Avoid any ambiguity casting uint32_t to int32_t
171
+ // The dataField is 24-bit signed, stored in the 24 LSBs of a uint32_t
172
+ signedUnsigned.unsigned32 = ubxDataStruct->data [i].data .bits .dataField << 8 ; // Shift left by 8 bits to correctly align the data
173
+ float temperature = signedUnsigned.signed32 ; // Extract the signed data. Convert to float
174
+ temperature /= 256.0 ; // Divide by 256 to undo the shift
175
+ temperature *= 0.01 ; // Convert from C * 1e-2 to C
176
+ Serial.println (temperature);
177
+ }
178
+ }
179
+ }
180
+
181
+ void setup ()
182
+ {
183
+ Serial.begin (230400 ); // <-- Use a fast baud rate to avoid the Serial prints slowing the code
184
+
185
+ while (!Serial)
186
+ ; // Wait for user to open terminal
187
+ Serial.println (F (" SparkFun u-blox Example" ));
188
+
189
+ Wire.begin ();
190
+ Wire.setClock (400000 ); // <-- Use 400kHz I2C
191
+
192
+ // myGNSS.enableDebugging(); // Uncomment this line to enable debug messages on Serial
193
+
194
+ if (myGNSS.begin () == false ) // Connect to the u-blox module using Wire port
195
+ {
196
+ Serial.println (F (" u-blox GNSS not detected at default I2C address. Please check wiring. Freezing." ));
197
+ while (1 )
198
+ ;
199
+ }
200
+
201
+ myGNSS.setI2COutput (COM_TYPE_UBX); // Set the I2C port to output UBX only (turn off NMEA noise)
202
+ myGNSS.saveConfigSelective (VAL_CFG_SUBSEC_IOPORT); // Save (only) the communications port settings to flash and BBR
203
+
204
+ if (myGNSS.setAutoESFMEAScallbackPtr (&printESFMEASdata) == true ) // Enable automatic ESF MEAS messages with callback to printESFMEASdata
205
+ Serial.println (F (" setAutoESFMEAScallback successful" ));
206
+ }
207
+
208
+ void loop ()
209
+ {
210
+ myGNSS.checkUblox (); // Check for the arrival of new data and process it.
211
+ myGNSS.checkCallbacks (); // Check if any callbacks are waiting to be processed.
212
+ }
0 commit comments