// RMN: Volkslogger // Source data: // $PGCS,1,0EC0,FFF9,0C6E,02*61 // $PGCS,1,0EC0,FFFA,0C6E,03*18 static bool vl_PGCS1(NMEAInputLine &line, NMEAInfo &info) { if (line.Read(1) != 1) return false; /* pressure sensor */ line.Skip(); // four characers, hex, barometric altitude unsigned u_altitude; if (line.ReadHexChecked(u_altitude)) { int altitude(u_altitude); if (altitude > 60000) /* Assuming that altitude has wrapped around. 60 000 m occurs at QNH ~2000 hPa */ altitude -= 65535; info.ProvidePressureAltitude(fixed(altitude)); } // ExtractParameter(String,ctemp,3); // four characters, hex, constant. Value 1371 (dec) // nSatellites = (int)(min(12,HexStrToDouble(ctemp, NULL))); return false; }
static bool ParseData(NMEAInputLine &line, NMEAInfo &info) { // $PCPROBE,T,Q0,Q1,Q2,Q3,ax,ay,az,temp,rh,batt,delta_press,abs_press,C, // see http://www.compassitaly.com/CMS/index.php/en/download/c-probe/231-c-probeusermanual/download unsigned _q[4]; bool q_available = line.ReadHexChecked(_q[0]); if (!line.ReadHexChecked(_q[1])) q_available = false; if (!line.ReadHexChecked(_q[2])) q_available = false; if (!line.ReadHexChecked(_q[3])) q_available = false; if (q_available) { fixed q[4]; for (unsigned i = 0; i < 4; ++i) // Cast to int16_t to interpret the 16th bit as the sign bit q[i] = fixed((int16_t)_q[i]) / 1000; fixed sin_pitch = -2 * (q[0] * q[2] - q[3] * q[1]); if (sin_pitch <= fixed(1) && sin_pitch >= fixed(-1)) { info.attitude.pitch_angle_available = true; info.attitude.pitch_angle = Angle::asin(sin_pitch); Angle heading = Angle::HalfCircle() + Angle::FromXY(sqr(q[3]) - sqr(q[0]) - sqr(q[1]) + sqr(q[2]), Double(q[1] * q[2] + q[3] * q[0])); info.attitude.heading_available.Update(info.clock); info.attitude.heading = heading; Angle roll = Angle::FromXY(sqr(q[3]) + sqr(q[0]) - sqr(q[1]) - sqr(q[2]), Double(q[0] * q[1] + q[3] * q[2])); info.attitude.bank_angle_available = true; info.attitude.bank_angle = roll; } } unsigned _a[3]; bool a_available = line.ReadHexChecked(_a[0]); if (!line.ReadHexChecked(_a[1])) a_available = false; if (!line.ReadHexChecked(_a[2])) a_available = false; if (a_available) { fixed a[3]; for (unsigned i = 0; i < 3; ++i) // Cast to int16_t to interpret the 16th bit as the sign bit a[i] = fixed((int16_t)_a[i]) / 1000; info.acceleration.ProvideGLoad(sqrt(sqr(a[0]) + sqr(a[1]) + sqr(a[2])), true); } unsigned temperature; if (line.ReadHexChecked(temperature)) { info.temperature_available = true; info.temperature = CelsiusToKelvin(fixed((int16_t)temperature) / 10); } unsigned humidity; if (line.ReadHexChecked(humidity)) { info.humidity_available = true; info.humidity = fixed((int16_t)humidity) / 10; } unsigned battery_level; if (line.ReadHexChecked(battery_level)) { info.battery_level_available.Update(info.clock); info.battery_level = fixed((int16_t)battery_level); } unsigned _delta_pressure; if (line.ReadHexChecked(_delta_pressure)) { fixed delta_pressure = fixed((int16_t)_delta_pressure) / 10; info.ProvideDynamicPressure(AtmosphericPressure::Pascal(delta_pressure)); } return true; }