-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathNazaDecoder.h
More file actions
234 lines (170 loc) · 6.18 KB
/
NazaDecoder.h
File metadata and controls
234 lines (170 loc) · 6.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
/**
* Arduino Naza Decoder
*
* Inspired by the Pawelsky's work.
*/
#ifndef __ARDUINO_NAZA_DECODER_H__
#define __ARDUINO_NAZA_DECODER_H__
#include <Arduino.h>
#include <Gps.h>
#include <Magnetometer.h>
#define MESSAGE_HEADER_SIZE 0x04
#define NAZA_MESSAGE_MAX_PAYLOAD_LENGTH 0x3a
class NazaDecoder: public Gps, public Magnetometer {
public:
enum GPSPayloadPosition {
// date and time
NAZA_MESSAGE_POS_DT = 0x04 - MESSAGE_HEADER_SIZE,
// longitude (x10^7, degree decimal)
NAZA_MESSAGE_POS_LO = 0x08 - MESSAGE_HEADER_SIZE,
// latitude (x10^7, degree decimal)
NAZA_MESSAGE_POS_LA = 0x0c - MESSAGE_HEADER_SIZE,
// altitude (in millimeters)
NAZA_MESSAGE_POS_AL = 0x10 - MESSAGE_HEADER_SIZE,
// horizontal accuracy estimate (see uBlox NAV-POSLLH message for details)
NAZA_MESSAGE_POS_HA = 0x14 - MESSAGE_HEADER_SIZE,
// vertical accuracy estimate (see uBlox NAV-POSLLH message for details)
NAZA_MESSAGE_POS_VA = 0x18 - MESSAGE_HEADER_SIZE,
// NED north velocity (see uBlox NAV-VELNED message for details)
NAZA_MESSAGE_POS_NV = 0x20 - MESSAGE_HEADER_SIZE,
// NED east velocity (see uBlox NAV-VELNED message for details)
NAZA_MESSAGE_POS_EV = 0x24 - MESSAGE_HEADER_SIZE,
// NED down velocity (see uBlox NAV-VELNED message for details)
NAZA_MESSAGE_POS_DV = 0x28 - MESSAGE_HEADER_SIZE,
// position DOP (see uBlox NAV-DOP message for details)
NAZA_MESSAGE_POS_PD = 0x2c - MESSAGE_HEADER_SIZE,
// vertical DOP (see uBlox NAV-DOP message for details)
NAZA_MESSAGE_POS_VD = 0x2e - MESSAGE_HEADER_SIZE,
// northing DOP (see uBlox NAV-DOP message for details)
NAZA_MESSAGE_POS_ND = 0x30 - MESSAGE_HEADER_SIZE,
//easting DOP (see uBlox NAV-DOP message for details)
NAZA_MESSAGE_POS_ED = 0x32 - MESSAGE_HEADER_SIZE,
// number of satellites (not XORed)
NAZA_MESSAGE_POS_NS = 0x34 - MESSAGE_HEADER_SIZE,
// fix type (0 - no lock, 2 - 2D lock, 3 - 3D lock, not sure if other values can be expected - see uBlox NAV-SOL message for details)
NAZA_MESSAGE_POS_FT = 0x36 - MESSAGE_HEADER_SIZE,
// fix status flags (see uBlox NAV-SOL message for details)
NAZA_MESSAGE_POS_SF = 0x38 - MESSAGE_HEADER_SIZE,
// XOR mask
NAZA_MESSAGE_POS_XM = 0x3b - MESSAGE_HEADER_SIZE,
// sequence number (not XORed), once there is a lock - increases with every message. When the lock is lost later LSB and MSB are swapped with every message.
NAZA_MESSAGE_POS_SN = 0x3c - MESSAGE_HEADER_SIZE,
// checksum, calculated the same way as for uBlox binary messages
NAZA_MESSAGE_POS_CS = 0x3e - MESSAGE_HEADER_SIZE
};
enum MagnetometerPayloadPosition {
// magnetometer X axis data (signed)
NAZA_MESSAGE_POS_CX = 0x04 - MESSAGE_HEADER_SIZE,
// magnetometer Y axis data (signed)
NAZA_MESSAGE_POS_CY = 0x06 - MESSAGE_HEADER_SIZE,
// magnetometer Z axis data (signed)
NAZA_MESSAGE_POS_CZ = 0x08 - MESSAGE_HEADER_SIZE
};
enum ModuleVersionPayloadPosition {
// firmware version
NAZA_MESSAGE_POS_FW = 0x08 - MESSAGE_HEADER_SIZE,
// hardware id
NAZA_MESSAGE_POS_HW = 0x0c - MESSAGE_HEADER_SIZE
};
enum MessageType {
NAZA_MESSAGE_NONE_TYPE = 0x00,
NAZA_MESSAGE_GPS_TYPE = 0x10,
NAZA_MESSAGE_MAGNETOMETER_TYPE = 0x20,
NAZA_MESSAGE_MODULE_VERSION_TYPE = 0x30
};
enum MessageSize {
NAZA_MESSAGE_GPS_SIZE = 0x3a,
NAZA_MESSAGE_MAGNETOMETER_SIZE = 0x06,
NAZA_MESSAGE_MODULE_VERSION_SIZE = 0x0c
};
struct VersionSchemeType {
uint8_t revision;
uint8_t build;
uint8_t minor;
uint8_t major;
};
union VersionType {
uint32_t version;
VersionSchemeType scheme;
};
NazaDecoder();
uint8_t decode(int16_t input);
/**
* Gps API.
*/
double getLatitude();
double getLongitude();
double getAltitude();
double getSpeed();
FixType getFixType();
uint8_t getSatellites();
double getCourseOverGround();
double getVerticalSpeedIndicator();
double getHorizontalDilutionOfPrecision();
double getVerticalDilutionOfPrecision();
uint8_t getYear();
uint8_t getMonth();
uint8_t getDay();
// Note that for time between 16:00 and 23:59 the hour returned from GPS module is actually 00:00 - 7:59.
uint8_t getHour();
uint8_t getMinute();
uint8_t getSecond();
/**
* Magnetometer API
*/
double getHeading();
// Note that you need to read version numbers backwards (02 01 00 06 means v6.0.1.2)
VersionType getFirmwareVersion();
VersionType getHardwareVersion();
uint8_t isLocked();
private:
int16_t payload[NAZA_MESSAGE_MAX_PAYLOAD_LENGTH];
int16_t sequence;
int16_t count;
int16_t messageId;
int16_t messageLength;
// checksum #1
uint8_t checksum1;
// checksum #2
uint8_t checksum2;
int16_t magXMin;
int16_t magXMax;
int16_t magYMin;
int16_t magYMax;
// longitude in degree decimal
double longitude;
// latitude in degree decimal
double latitude;
// altitude in m (from GPS)
double altitude;
// speed in m/s
double speed;
// fix type
FixType fix;
// number of satellites
uint8_t satellites;
// heading (not tilt compensated) in degrees
double heading;
// course over ground
double courseOverGround;
// vertical speed indicator (from GPS) in m/s (a.k.a. climb speed)
double verticalSpeedIndicator;
// horizontal dilution of precision
double horizontalDilutionOfPrecision;
// vertical dilution of precision
double verticalDilutionOfPrecision;
uint8_t year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t minute;
uint8_t second;
VersionType firmwareVersion;
VersionType hardwareVersion;
uint16_t lastLock;
uint8_t locked;
int32_t pack4(uint8_t i, uint8_t mask);
int16_t pack2(uint8_t i, uint8_t mask);
void updateChecksum(int16_t input);
};
#endif /* __ARDUINO_NAZA_DECODER_H__ */