void WesterboerVW921Device::SentenceOne(const void *_data, size_t length, struct NMEAInfo &info) { const uint8_t *data = (const uint8_t *)_data; // Sentence one exists in multiple versions based on firmware version if (length == 31) { // According to test device fixed wing_loading = fixed(ReadFloat(data + 13)); info.settings.ProvideWingLoading(wing_loading, info.clock); uint8_t polar_type = *(data + 30); if (polar_type == 0) info.settings.ProvideBugs(fixed_one, info.clock); else if (polar_type == 1) info.settings.ProvideBugs(fixed(0.85), info.clock); else if (polar_type == 2) info.settings.ProvideBugs(fixed(0.95), info.clock); } else if (length == 26) { // According to version 3.30 documentation int16_t wing_loading = ReadUnalignedLE16((const uint16_t *)(const void *)(data + 11)); info.settings.ProvideWingLoading(fixed(wing_loading) / 10, info.clock); uint8_t polar_type = *(data + 13); if (polar_type == 0) info.settings.ProvideBugs(fixed_one, info.clock); else if (polar_type == 1) info.settings.ProvideBugs(fixed(0.95), info.clock); else if (polar_type == 2) info.settings.ProvideBugs(fixed(0.85), info.clock); } }
uint16_t GetSequenceNumber() const { return ReadUnalignedLE16(&sequence_number); }
void WesterboerVW921Device::SentenceZero(const void *_data, size_t length, struct NMEAInfo &info) { const uint8_t *data = (const uint8_t *)_data; /* Received sentence #0 with length = 45 24 77 2d 3c 00 10 82 07 c8 6c 28 00 00 bd ff 46 00 04 02 00 00 46 00 00 00 12 00 01 00 00 00 00 00 3f 0b 80 62 d5 b1 7d 5a 0d cd a6 ff */ // 0 - 4 Header // 24 77 2d 3c 00 // 5 Byte Flight status (Bitmask) // 6 Byte Flight status 2 (Bitmask) // Bit 7 : External Switch (1=Climbing, 0=Cruise) uint8_t flight_status2 = *(data + 6); if ((flight_status2 & (1 << 7)) == 0) { info.switch_state.flight_mode = SwitchInfo::FlightMode::CRUISE; info.switch_state.speed_command = true; } else { info.switch_state.flight_mode = SwitchInfo::FlightMode::CIRCLING; info.switch_state.speed_command = false; } info.switch_state_available = true; // 7 Byte GPS status (Bitmask) // Bit 3: GPS-Status-Flag ("A"-valid position/"V"- NAV receiver warning) // 8 Byte GPS status 2 (Bitmask) // 9 Word Flight time (sec) // 11 Word Distance to next target (0.1 km) // 6c 28 00 00 // 13 Int STD altitude (m) // 15 Int QFE-Höhe h (m) // b8 ff 00 00 int16_t std_altitude = ReadUnalignedLE16((const uint16_t *)(const void *)(data + 13)); info.ProvidePressureAltitude(fixed(std_altitude)); // 17 Int Windempfehlung (km/ h) // 19 Int delta speed (km/ h) // 21 Int Gleitpath deviation (m) // 00 00 00 00 00 00 // 23 Int avg. Vario (0,1 m/s) // 25 Int Nettovario (0,1 m/s) // 27 Int Vario (0,1 m/s) // 00 00 11 00 f7 ff int16_t netto_vario = ReadUnalignedLE16((const uint16_t *)(const void *)(data + 25)); info.ProvideNettoVario(fixed(netto_vario) / 10); int16_t vario = ReadUnalignedLE16((const uint16_t *)(const void *)(data + 27)); info.ProvideTotalEnergyVario(fixed(vario) / 10); // 29 Int True Air Speed TAS (0,1 m/s) // 31 Int Groundspeed GS (0,1 m/s) // 00 00 e6 00 int16_t tas = ReadUnalignedLE16((const uint16_t *)(const void *)(data + 29)); info.ProvideTrueAirspeed(fixed(tas) / 10); int16_t ground_speed = ReadUnalignedLE16((const uint16_t *)(const void *)(data + 31)); info.ground_speed = fixed(ground_speed) / 10; info.ground_speed_available.Update(info.clock); // Next 12 bytes are zero if GPS connection is bad: // 33 Int Track (0.1 deg) // eb 03 // 35 Float Latitude (arc, -pi/2 .. +pi/2) // 80 62 d6 ce = N504606 // 39 Float Longitude (arc, -pi .. +pi) // 7d 59 e4 01 = E 60601 // 43 Int DiffAngle (0.1 deg) // 62 fd uint8_t gps_status = *(data + 7); if ((gps_status & (1 << 3)) != 0) { // GPS has a valid fix int16_t track = ReadUnalignedLE16((const uint16_t *)(const void *)(data + 31)); info.track = Angle::Degrees(fixed(track) / 10); info.track_available.Update(info.clock); info.location.latitude = Angle::Radians(fixed(ReadFloat(data + 35))); info.location.longitude = Angle::Radians(fixed(ReadFloat(data + 39))); info.location_available.Update(info.clock); } }