- Posts: 3333
DSM Telemetry support
- vlad_vy
-
- Offline
Less
More
17 Mar 2013 08:54 - 17 Mar 2013 09:31 #7846
by vlad_vy
Replied by vlad_vy on topic DSM Telemetry support
Thanks PB, all active telemetry code works fine. Tested telemetry temp, it also now works fine, value displayed correctly down to -17C (temp at my deep-freezer), for both Spektrum and Walkera telemetry.
Last edit: 17 Mar 2013 09:31 by vlad_vy.
- vlad_vy
-
- Offline
Less
More
- Posts: 3333
17 Mar 2013 12:20 - 18 Mar 2013 09:07 #7851
by vlad_vy
Replied by vlad_vy on topic DSM Telemetry support
Draft code for telemetry JetCat Sensor
Error !!!
case 0x0a: //Powerbox sensor has ID 0x0a, not 0x10
case 0x15: //JetCat sensor
//Telemetry.jc.status = packet[2];
//Possible messages for status:
//0x00:OFF
//0x01:WAIT FOR RPM
//0x02:IGNITE
//0x03;ACCELERATE
//0x04:STABILIZE
//0x05:LEARN HIGH
//0x06:LEARN LOW
//0x07:undef
//0x08:SLOW DOWN
//0x09:MANUAL
//0x0a,0x10:AUTO OFF
//0x0b,0x11:RUN
//0x0c,0x12:ACCELERATION DELAY
//0x0d,0x13:SPEED REG
//0x0e,0x14:TWO SHAFT REGULATE
//0x0f,0x15:PRE HEAT
//0x16:PRE HEAT 2
//0x17:MAIN F START
//0x18:not used
//0x19:KERO FULL ON
//0x1a:MAX STATE
//Telemetry.jc.throttle = (packet[3] >> 4) * 10 + (packet[3] & 0x0f); //up to 159% (the upper nibble is 0-f, the lower nibble 0-9)
//Telemetry.jc.pack_volt = (((packet[4] >> 4) * 10 + (packet[4] & 0x0f)) * 100
// + (packet[5] >> 4) * 10 + (packet[5] & 0x0f) + 5) / 10; //In 1/10 of Volts
//Telemetry.jc.pump_volt = (((packet[6] >> 6) * 10 + (packet[6] & 0x0f)) * 100
// + (packet[7] >> 4) * 10 + (packet[7] & 0x0f) + 5) / 10; //In 1/10 of Volts
//Telemetry.jc.rpm = ((packet[10] >> 4) * 10 + (packet[10] & 0x0f)) * 10000
// + ((packet[9] >> 4) * 10 + (packet[9] & 0x0f)) * 100
// + ((packet[8] >> 4) * 10 + (packet[8] & 0x0f)); //RPM up to 999999
//Telemetry.jc.tempEGT = (packet[13] & 0x0f) * 100 + (packet[12] >> 4) * 10 + (packet[12] & 0x0f); //EGT temp up to 999°
//Telemetry.jc.off_condition = packet[14];
//Messages for Off_Condition:
//0x00:NA
//0x01:OFF BY RC
//0x02:OVER TEMPERATURE
//0x03:IGNITION TIMEOUT
//0x04:ACCELERATION TIMEOUT
//0x05:ACCELERATION TOO SLOW
//0x06:OVER RPM
//0x07:LOW RPM OFF
//0x08:LOW BATTERY
//0x09:AUTO OFF
//0x0a.0x10:LOW TEMP OFF
//0x0b,0x11:HIGH TEMP OFF
//0x0c,0x12:GLOW PLUG DEFECTIVE
//0x0d,0x13:WATCH DOG TIMER
//0x0e,0x14:FAIL SAFE OFF
//0x0f,0x15:MANUAL OFF
//0x16:POWER BATT FAIL
//0x17:TEMP SENSOR FAIL
//0x18:FUEL FAIL
//0x19:PROP FAIL
//0x1a:2nd ENGINE FAIL
//0x1b:2nd ENGINE DIFFERENTIAL TOO HIGH
//0x1c:2nd ENGINE NO COMMUNICATION
//0x1d:MAX OFF CONDITION
//Telemetry.time[x6] = time_ms;
break;Error !!!
case 0x0a: //Powerbox sensor has ID 0x0a, not 0x10
Last edit: 18 Mar 2013 09:07 by vlad_vy.
- PhracturedBlue
-
Topic Author
- Offline
Less
More
- Posts: 4403
17 Mar 2013 13:15 #7852
by PhracturedBlue
Replied by PhracturedBlue on topic DSM Telemetry support
Only a Russian would request support for <0C temperatures 
I couldn't actually fathom anyone wanting to fly in such temperatures which is why it wasn't originally supported.
I couldn't actually fathom anyone wanting to fly in such temperatures which is why it wasn't originally supported.
- vlad_vy
-
- Offline
Less
More
- Posts: 3333
17 Mar 2013 13:46 #7854
by vlad_vy
Replied by vlad_vy on topic DSM Telemetry support
Russian pilots fly all the winter, down to -20C. With LiFe batteries and warm bag for Tx.
- domcars0
-
- Offline
Less
More
- Posts: 390
17 Mar 2013 13:48 #7855
by domcars0
Devo 10 (+7e) owner. It's mine, please don't touch it with your big fingers
Replied by domcars0 on topic DSM Telemetry support
That's why they won TWO Stalingrad battles
Devo 10 (+7e) owner. It's mine, please don't touch it with your big fingers
- vlad_vy
-
- Offline
Less
More
- Posts: 3333
19 Mar 2013 05:39 - 19 Mar 2013 05:39 #7914
by vlad_vy
Replied by vlad_vy on topic DSM Telemetry support
New draft version of telemetry parser, with corrected PowerBox (capacity1,2) and added JetCat sensor code
static void parse_telemetry_packet()
{
u32 time_ms = CLOCK_getms();
switch(packet[0]) {
case 0x7f: //TM1000 Flight log
case 0xff: //TM1100 Flight log
//Telemetry.fadesA = ((s32)packet[2] << 8) | packet[3];
//Telemetry.fadesB = ((s32)packet[4] << 8) | packet[5];
//Telemetry.fadesL = ((s32)packet[6] << 8) | packet[7];
//Telemetry.fadesR = ((s32)packet[8] << 8) | packet[9];
//Telemetry.frameloss = ((s32)packet[10] << 8) | packet[11];
//Telemetry.holds = ((s32)packet[12] << 8) | packet[13];
Telemetry.volt[1] = ((((s32)packet[14] << 8) | packet[15]) + 5) / 10; //In 1/10 of Volts
Telemetry.time[0] = time_ms;
Telemetry.time[1] = Telemetry.time[0];
break;
case 0x7e: //TM1000
case 0xfe: //TM1100
Telemetry.rpm[0] = (packet[2] << 8) | packet[3];
if ((Telemetry.rpm[0] == 0xffff) || (Telemetry.rpm[0] < 200))
Telemetry.rpm[0] = 0;
else
Telemetry.rpm[0] = 120000000 / 2 / Telemetry.rpm[0]; //In RPM (2 = number of poles)
//Telemetry.rpm[0] = 120000000 / number_of_poles(2, 4, ... 32) / gear_ratio(0.01 - 30.99) / Telemetry.rpm[0];
//by default number_of_poles = 2, gear_ratio = 1.00
Telemetry.volt[0] = ((((s32)packet[4] << 8) | packet[5]) + 5) / 10; //In 1/10 of Volts
Telemetry.temp[0] = (((packet[6] << 8) | packet[7]) - 32) * 5 / 9; //In degrees-C (16Bit signed integer !!!)
if (Telemetry.temp[0] > 500 || Telemetry.temp[0] < -100)
Telemetry.temp[0] = 0;
Telemetry.time[0] = time_ms;
Telemetry.time[1] = Telemetry.time[0];
break;
case 0x03: //High Current sensor
//Telemetry.current = (((s32)packet[2] << 8) | packet[3]) * 1967 / 1000; //In 1/10 of Amps (16bit value, 1 unit is 0.1967A)
//Telemetry.time[x1] = time_ms;
break;
case 0x0a: //Powerbox sensor
//Telemetry.pwb.volt1 = (((s32)packet[2] << 8) | packet[3] + 5) /10; //In 1/10 of Volts
//Telemetry.pwb.volt1 = (((s32)packet[4] << 8) | packet[5] + 5) /10; //In 1/10 of Volts
//Telemetry.pwb.capacity1 = ((s32)packet[6] << 8) | packet[7]; //In mAh
//Telemetry.pwb.capacity2 = ((s32)packet[8] << 8) | packet[9]; //In mAh
//Telemetry.pwb.alarm_v1 = packet[15] & 0x01; //0 = disable, 1 = enable
//Telemetry.pwb.alarm_v2 = (packet[15] >> 1) & 0x01; //0 = disable, 1 = enable
//Telemetry.pwb.alarm_c1 = (packet[15] >> 2) & 0x01; //0 = disable, 1 = enable
//Telemetry.pwb.alarm_c2 = (packet[15] >> 3) & 0x01; //0 = disable, 1 = enable
//Telemetry.time[x2] = time_ms;
break;
case 0x11: //AirSpeed sensor
//Telemetry.airspeed = ((s32)packet[2] << 8) | packet[3]; //In km/h (16Bit value, 1 unit is 1 km/h)
//Telemetry.time[x3] = time_ms;
break;
case 0x12: //Altimeter sensor
//Telemetry.altitude = (((s16)packet[2] << 8) | packet[3]) /10; //In meters (16Bit signed integer, 1 unit is 0.1m)
//Telemetry.time[x4] = time_ms;
break;
case 0x14: //G-Force sensor
//Telemetry.gforce.x = ((s16)packet[2] << 8) | packet[3]; //In 0.01g (16Bit signed integers, unit is 0.01g)
//Telemetry.gforce.y = ((s16)packet[4] << 8) | packet[5];
//Telemetry.gforce.z = ((s16)packet[6] << 8) | packet[7];
//Telemetry.gforce.xmax = ((s16)packet[8] << 8) | packet[9];
//Telemetry.gforce.ymax = ((s16)packet[10] << 8) | packet[11];
//Telemetry.gforce.zmax = ((s16)packet[12] << 8) | packet[13];
//Telemetry.gforce.zmin = ((s16)packet[14] << 8) | packet[15];
//Telemetry.time[x5] = time_ms;
break;
case 0x15: //JetCat sensor
//Telemetry.jc.status = packet[2];
//Possible messages for status:
//0x00:OFF
//0x01:WAIT FOR RPM
//0x02:IGNITE
//0x03;ACCELERATE
//0x04:STABILIZE
//0x05:LEARN HIGH
//0x06:LEARN LOW
//0x07:undef
//0x08:SLOW DOWN
//0x09:MANUAL
//0x0a,0x10:AUTO OFF
//0x0b,0x11:RUN
//0x0c,0x12:ACCELERATION DELAY
//0x0d,0x13:SPEED REG
//0x0e,0x14:TWO SHAFT REGULATE
//0x0f,0x15:PRE HEAT
//0x16:PRE HEAT 2
//0x17:MAIN F START
//0x18:not used
//0x19:KERO FULL ON
//0x1a:MAX STATE
//Telemetry.jc.throttle = (packet[3] >> 4) * 10 + (packet[3] & 0x0f); //up to 159% (the upper nibble is 0-f, the lower nibble 0-9)
//Telemetry.jc.pack_volt = (((packet[4] >> 4) * 10 + (packet[4] & 0x0f)) * 100
// + (packet[5] >> 4) * 10 + (packet[5] & 0x0f) + 5) / 10; //In 1/10 of Volts
//Telemetry.jc.pump_volt = (((packet[6] >> 6) * 10 + (packet[6] & 0x0f)) * 100
// + (packet[7] >> 4) * 10 + (packet[7] & 0x0f) + 5) / 10; //In 1/10 of Volts
//Telemetry.jc.rpm = ((packet[10] >> 4) * 10 + (packet[10] & 0x0f)) * 10000
// + ((packet[9] >> 4) * 10 + (packet[9] & 0x0f)) * 100
// + ((packet[8] >> 4) * 10 + (packet[8] & 0x0f)); //RPM up to 999999
//Telemetry.jc.tempEGT = (packet[13] & 0x0f) * 100 + (packet[12] >> 4) * 10 + (packet[12] & 0x0f); //EGT temp up to 999°
//Telemetry.jc.off_condition = packet[14];
//Messages for Off_Condition:
//0x00:NA
//0x01:OFF BY RC
//0x02:OVER TEMPERATURE
//0x03:IGNITION TIMEOUT
//0x04:ACCELERATION TIMEOUT
//0x05:ACCELERATION TOO SLOW
//0x06:OVER RPM
//0x07:LOW RPM OFF
//0x08:LOW BATTERY
//0x09:AUTO OFF
//0x0a,0x10:LOW TEMP OFF
//0x0b,0x11:HIGH TEMP OFF
//0x0c,0x12:GLOW PLUG DEFECTIVE
//0x0d,0x13:WATCH DOG TIMER
//0x0e,0x14:FAIL SAFE OFF
//0x0f,0x15:MANUAL OFF
//0x16:POWER BATT FAIL
//0x17:TEMP SENSOR FAIL
//0x18:FUEL FAIL
//0x19:PROP FAIL
//0x1a:2nd ENGINE FAIL
//0x1b:2nd ENGINE DIFFERENTIAL TOO HIGH
//0x1c:2nd ENGINE NO COMMUNICATION
//0x1d:MAX OFF CONDITION
//Telemetry.time[x6] = time_ms;
break;
case 0x16: //GPS sensor
Telemetry.gps.altitude = (((packet[3] >> 4) * 10 + (packet[3] & 0x0f)) * 100 //(16Bit decimal, 1 unit is 0.1m)
+ ((packet[2] >> 4) * 10 + (packet[2] & 0x0f))) * 100; //In meters * 1000
Telemetry.gps.latitude = ((packet[7] >> 4) * 10 + (packet[7] & 0x0f)) * 3600000
+ ((packet[6] >> 4) * 10 + (packet[6] & 0x0f)) * 60000
+ ((packet[5] >> 4) * 10 + (packet[5] & 0x0f)) * 600
+ ((packet[4] >> 4) * 10 + (packet[4] & 0x0f)) * 6;
if ((packet[15] & 0x01) == 0)
Telemetry.gps.latitude *= -1;
Telemetry.gps.longitude = ((packet[11] >> 4) * 10 + (packet[11] & 0x0f)) * 3600000
+ ((packet[10] >> 4) * 10 + (packet[10] & 0x0f)) * 60000
+ ((packet[9] >> 4) * 10 + (packet[9] & 0x0f)) * 600
+ ((packet[8] >> 4) * 10 + (packet[8] & 0x0f)) * 6;
if ((packet[15] & 0x04) == 4)
Telemetry.gps.longitude += 360000000;
if ((packet[15] & 0x02) == 0)
Telemetry.gps.longitude *= -1;
// Telemetry.gps.heading = ((packet[13] >> 4) * 10 + (packet[13] & 0x0f)) * 10 //(16Bit decimal, 1 unit is 0.1 degree)
// + ((packet[12] >> 4) * 10 + (packet[12] & 0x0f)) / 10; //In degrees
Telemetry.time[2] = time_ms;
break;
case 0x17: //GPS sensor
Telemetry.gps.velocity = (((packet[3] >> 4) * 10 + (packet[3] & 0x0f)) * 100
+ ((packet[2] >> 4) * 10 + (packet[2] & 0x0f))) * 5556 / 108; //In m/s * 1000
u8 hour = (packet[7] >> 4) * 10 + (packet[7] & 0x0f);
u8 min = (packet[6] >> 4) * 10 + (packet[6] & 0x0f);
u8 sec = (packet[5] >> 4) * 10 + (packet[5] & 0x0f);
//u8 ssec = (packet[4] >> 4) * 10 + (packet[4] & 0x0f);
u8 day = 0;
u8 month = 0;
u8 year = 0; // + 2000
Telemetry.gps.time = ((year & 0x3F) << 26)
| ((month & 0x0F) << 22)
| ((day & 0x1F) << 17)
| ((hour & 0x1F) << 12)
| ((min & 0x3F) << 6)
| ((sec & 0x3F) << 0);
// Telemetry.gps.sats = ((packet[8] >> 4) * 10 + (packet[8] & 0x0f));
Telemetry.time[2] = time_ms;
break;
}
}
Last edit: 19 Mar 2013 05:39 by vlad_vy.
- vlad_vy
-
- Offline
Less
More
- Posts: 3333
20 Mar 2013 18:32 - 20 Mar 2013 19:06 #7936
by vlad_vy
Replied by vlad_vy on topic DSM Telemetry support
GPS sensor
Telemetry.gps.heading = tested, OK
Telemetry.gps.sats = tested, OK
G-Force Sensor
Telemetry.gforce.x = tested, OK
Telemetry.gforce.y = tested, OK
Telemetry.gforce.z = tested, OK
Telemetry.gforce.xmax = tested, OK
Telemetry.gforce.ymax = tested, OK
Telemetry.gforce.zmax = tested, OK
Telemetry.gforce.zmin = tested, OK
I realized that I need to do 'signed' type conversion after left bits shift (and do it mandatory), at other case I got unsigned value (e.g. 65535 instead -1).
Code for G-Force Sensor, Telemetry.temp and Telemetry.altitude corrected
Telemetry.gps.heading = tested, OK
Telemetry.gps.sats = tested, OK
G-Force Sensor
Telemetry.gforce.x = tested, OK
Telemetry.gforce.y = tested, OK
Telemetry.gforce.z = tested, OK
Telemetry.gforce.xmax = tested, OK
Telemetry.gforce.ymax = tested, OK
Telemetry.gforce.zmax = tested, OK
Telemetry.gforce.zmin = tested, OK
I realized that I need to do 'signed' type conversion after left bits shift (and do it mandatory), at other case I got unsigned value (e.g. 65535 instead -1).
Code for G-Force Sensor, Telemetry.temp and Telemetry.altitude corrected
static void parse_telemetry_packet()
{
u32 time_ms = CLOCK_getms();
switch(packet[0]) {
case 0x7f: //TM1000 Flight log
case 0xff: //TM1100 Flight log
//Telemetry.fadesA = ((s32)packet[2] << 8) | packet[3];
//Telemetry.fadesB = ((s32)packet[4] << 8) | packet[5];
//Telemetry.fadesL = ((s32)packet[6] << 8) | packet[7];
//Telemetry.fadesR = ((s32)packet[8] << 8) | packet[9];
//Telemetry.frameloss = ((s32)packet[10] << 8) | packet[11];
//Telemetry.holds = ((s32)packet[12] << 8) | packet[13];
Telemetry.volt[1] = ((((s32)packet[14] << 8) | packet[15]) + 5) / 10; //In 1/10 of Volts
Telemetry.time[0] = time_ms;
Telemetry.time[1] = Telemetry.time[0];
break;
case 0x7e: //TM1000
case 0xfe: //TM1100
Telemetry.rpm[0] = (packet[2] << 8) | packet[3];
if ((Telemetry.rpm[0] == 0xffff) || (Telemetry.rpm[0] < 200))
Telemetry.rpm[0] = 0;
else
Telemetry.rpm[0] = 120000000 / 2 / Telemetry.rpm[0]; //In RPM (2 = number of poles)
//Telemetry.rpm[0] = 120000000 / number_of_poles(2, 4, ... 32) / gear_ratio(0.01 - 30.99) / Telemetry.rpm[0];
//by default number_of_poles = 2, gear_ratio = 1.00
Telemetry.volt[0] = ((((s32)packet[4] << 8) | packet[5]) + 5) / 10; //In 1/10 of Volts
Telemetry.temp[0] = (((s16)(packet[6] << 8) | packet[7]) - 32) * 5 / 9; //In degrees-C (16Bit signed integer !!!)
if (Telemetry.temp[0] > 500 || Telemetry.temp[0] < -100)
Telemetry.temp[0] = 0;
Telemetry.time[0] = time_ms;
Telemetry.time[1] = Telemetry.time[0];
break;
case 0x03: //High Current sensor
//Telemetry.current = (((s32)packet[2] << 8) | packet[3]) * 1967 / 1000; //In 1/10 of Amps (16bit value, 1 unit is 0.1967A)
//Telemetry.time[x1] = time_ms;
break;
case 0x0a: //Powerbox sensor
//Telemetry.pwb.volt1 = (((s32)packet[2] << 8) | packet[3] + 5) /10; //In 1/10 of Volts
//Telemetry.pwb.volt1 = (((s32)packet[4] << 8) | packet[5] + 5) /10; //In 1/10 of Volts
//Telemetry.pwb.capacity1 = ((s32)packet[6] << 8) | packet[7]; //In mAh
//Telemetry.pwb.capacity2 = ((s32)packet[8] << 8) | packet[9]; //In mAh
//Telemetry.pwb.alarm_v1 = packet[15] & 0x01; //0 = disable, 1 = enable
//Telemetry.pwb.alarm_v2 = (packet[15] >> 1) & 0x01; //0 = disable, 1 = enable
//Telemetry.pwb.alarm_c1 = (packet[15] >> 2) & 0x01; //0 = disable, 1 = enable
//Telemetry.pwb.alarm_c2 = (packet[15] >> 3) & 0x01; //0 = disable, 1 = enable
//Telemetry.time[x2] = time_ms;
break;
case 0x11: //AirSpeed sensor
//Telemetry.airspeed = ((s32)packet[2] << 8) | packet[3]; //In km/h (16Bit value, 1 unit is 1 km/h)
//Telemetry.time[x3] = time_ms;
break;
case 0x12: //Altimeter sensor
//Telemetry.altitude = ((s16)(packet[2] << 8) | packet[3]) /10; //In meters (16Bit signed integer, 1 unit is 0.1m)
//Telemetry.time[x4] = time_ms;
break;
case 0x14: //G-Force sensor
//Telemetry.gforce.x = (s16)(packet[2] << 8) | packet[3]; //In 0.01g (16Bit signed integers, unit is 0.01g)
//Telemetry.gforce.y = (s16)(packet[4] << 8) | packet[5];
//Telemetry.gforce.z = (s16)(packet[6] << 8) | packet[7];
//Telemetry.gforce.xmax = (s16)(packet[8] << 8) | packet[9];
//Telemetry.gforce.ymax = (s16)(packet[10] << 8) | packet[11];
//Telemetry.gforce.zmax = (s16)(packet[12] << 8) | packet[13];
//Telemetry.gforce.zmin = (s16)(packet[14] << 8) | packet[15];
//Telemetry.time[x5] = time_ms;
break;
case 0x15: //JetCat sensor
//Telemetry.jc.status = packet[2];
//Possible messages for status:
//0x00:OFF
//0x01:WAIT FOR RPM
//0x02:IGNITE
//0x03;ACCELERATE
//0x04:STABILIZE
//0x05:LEARN HIGH
//0x06:LEARN LOW
//0x07:undef
//0x08:SLOW DOWN
//0x09:MANUAL
//0x0a,0x10:AUTO OFF
//0x0b,0x11:RUN
//0x0c,0x12:ACCELERATION DELAY
//0x0d,0x13:SPEED REG
//0x0e,0x14:TWO SHAFT REGULATE
//0x0f,0x15:PRE HEAT
//0x16:PRE HEAT 2
//0x17:MAIN F START
//0x18:not used
//0x19:KERO FULL ON
//0x1a:MAX STATE
//Telemetry.jc.throttle = (packet[3] >> 4) * 10 + (packet[3] & 0x0f); //up to 159% (the upper nibble is 0-f, the lower nibble 0-9)
//Telemetry.jc.pack_volt = (((packet[4] >> 4) * 10 + (packet[4] & 0x0f)) * 100
// + (packet[5] >> 4) * 10 + (packet[5] & 0x0f) + 5) / 10; //In 1/10 of Volts
//Telemetry.jc.pump_volt = (((packet[6] >> 6) * 10 + (packet[6] & 0x0f)) * 100
// + (packet[7] >> 4) * 10 + (packet[7] & 0x0f) + 5) / 10; //In 1/10 of Volts
//Telemetry.jc.rpm = ((packet[10] >> 4) * 10 + (packet[10] & 0x0f)) * 10000
// + ((packet[9] >> 4) * 10 + (packet[9] & 0x0f)) * 100
// + ((packet[8] >> 4) * 10 + (packet[8] & 0x0f)); //RPM up to 999999
//Telemetry.jc.tempEGT = (packet[13] & 0x0f) * 100 + (packet[12] >> 4) * 10 + (packet[12] & 0x0f); //EGT temp up to 999°
//Telemetry.jc.off_condition = packet[14];
//Messages for Off_Condition:
//0x00:NA
//0x01:OFF BY RC
//0x02:OVER TEMPERATURE
//0x03:IGNITION TIMEOUT
//0x04:ACCELERATION TIMEOUT
//0x05:ACCELERATION TOO SLOW
//0x06:OVER RPM
//0x07:LOW RPM OFF
//0x08:LOW BATTERY
//0x09:AUTO OFF
//0x0a,0x10:LOW TEMP OFF
//0x0b,0x11:HIGH TEMP OFF
//0x0c,0x12:GLOW PLUG DEFECTIVE
//0x0d,0x13:WATCH DOG TIMER
//0x0e,0x14:FAIL SAFE OFF
//0x0f,0x15:MANUAL OFF
//0x16:POWER BATT FAIL
//0x17:TEMP SENSOR FAIL
//0x18:FUEL FAIL
//0x19:PROP FAIL
//0x1a:2nd ENGINE FAIL
//0x1b:2nd ENGINE DIFFERENTIAL TOO HIGH
//0x1c:2nd ENGINE NO COMMUNICATION
//0x1d:MAX OFF CONDITION
//Telemetry.time[x6] = time_ms;
break;
case 0x16: //GPS sensor
Telemetry.gps.altitude = (((packet[3] >> 4) * 10 + (packet[3] & 0x0f)) * 100 //(16Bit decimal, 1 unit is 0.1m)
+ ((packet[2] >> 4) * 10 + (packet[2] & 0x0f))) * 100; //In meters * 1000
Telemetry.gps.latitude = ((packet[7] >> 4) * 10 + (packet[7] & 0x0f)) * 3600000
+ ((packet[6] >> 4) * 10 + (packet[6] & 0x0f)) * 60000
+ ((packet[5] >> 4) * 10 + (packet[5] & 0x0f)) * 600
+ ((packet[4] >> 4) * 10 + (packet[4] & 0x0f)) * 6;
if ((packet[15] & 0x01) == 0)
Telemetry.gps.latitude *= -1;
Telemetry.gps.longitude = ((packet[11] >> 4) * 10 + (packet[11] & 0x0f)) * 3600000
+ ((packet[10] >> 4) * 10 + (packet[10] & 0x0f)) * 60000
+ ((packet[9] >> 4) * 10 + (packet[9] & 0x0f)) * 600
+ ((packet[8] >> 4) * 10 + (packet[8] & 0x0f)) * 6;
if ((packet[15] & 0x04) == 4)
Telemetry.gps.longitude += 360000000;
if ((packet[15] & 0x02) == 0)
Telemetry.gps.longitude *= -1;
// Telemetry.gps.heading = ((packet[13] >> 4) * 10 + (packet[13] & 0x0f)) * 10 //(16Bit decimal, 1 unit is 0.1 degree)
// + ((packet[12] >> 4) * 10 + (packet[12] & 0x0f)) / 10; //In degrees
Telemetry.time[2] = time_ms;
break;
case 0x17: //GPS sensor
Telemetry.gps.velocity = (((packet[3] >> 4) * 10 + (packet[3] & 0x0f)) * 100
+ ((packet[2] >> 4) * 10 + (packet[2] & 0x0f))) * 5556 / 108; //In m/s * 1000
u8 hour = (packet[7] >> 4) * 10 + (packet[7] & 0x0f);
u8 min = (packet[6] >> 4) * 10 + (packet[6] & 0x0f);
u8 sec = (packet[5] >> 4) * 10 + (packet[5] & 0x0f);
//u8 ssec = (packet[4] >> 4) * 10 + (packet[4] & 0x0f);
u8 day = 0;
u8 month = 0;
u8 year = 0; // + 2000
Telemetry.gps.time = ((year & 0x3F) << 26)
| ((month & 0x0F) << 22)
| ((day & 0x1F) << 17)
| ((hour & 0x1F) << 12)
| ((min & 0x3F) << 6)
| ((sec & 0x3F) << 0);
// Telemetry.gps.sats = ((packet[8] >> 4) * 10 + (packet[8] & 0x0f));
Telemetry.time[2] = time_ms;
break;
}
}
Last edit: 20 Mar 2013 19:06 by vlad_vy.
- vlad_vy
-
- Offline
Less
More
- Posts: 3333
21 Mar 2013 15:13 - 21 Mar 2013 15:20 #7960
by vlad_vy
at -18C it displayed 0C (----),
displayed temp correctly down to -21C.
AirSpeed Sensor
Telemetry.airspeed = tested, OK
Replied by vlad_vy on topic DSM Telemetry support
Telemetry.temp[0] = (((packet[6] << 8) | packet[7]) - 32) * 5 / 9;
or
Telemetry.temp[0] = ((((s16)packet[6] << 8) | packet[7]) - 32) * 5 / 9;
Telemetry.temp[0] = (((s16)(packet[6] << 8) | packet[7]) - 32) * 5 / 9;AirSpeed Sensor
Telemetry.airspeed = tested, OK
Last edit: 21 Mar 2013 15:20 by vlad_vy.
- PhracturedBlue
-
Topic Author
- Offline
Less
More
- Posts: 4403
21 Mar 2013 15:28 #7962
by PhracturedBlue
Replied by PhracturedBlue on topic DSM Telemetry support
just an fyi. you should always use (s32) for intermediate calculations. It results in more optimized code since the compiler doesn't nee to continuously truncate the calculations.
- vlad_vy
-
- Offline
Less
More
- Posts: 3333
21 Mar 2013 15:58 #7963
by vlad_vy
Replied by vlad_vy on topic DSM Telemetry support
In this case I need at first to get signed 16 bit integer from two bytes. Is it possible with (s32)? (s32)(0xFFFF) = -1?
- vlad_vy
-
- Offline
Less
More
- Posts: 3333
21 Mar 2013 16:24 - 21 Mar 2013 16:26 #7964
by vlad_vy
Replied by vlad_vy on topic DSM Telemetry support
PB, in this case it doesn't work. I tested new code and get:
at -18C it displayed 0C (----),
Possible the same will be for G-Force Sensor and Telemetry.altitude.
Telemetry.temp[0] = (((s32)(packet[6] << 8) | packet[7]) - 32) * 5 / 9;at -18C it displayed 0C (----),
Possible the same will be for G-Force Sensor and Telemetry.altitude.
Last edit: 21 Mar 2013 16:26 by vlad_vy.
- PhracturedBlue
-
Topic Author
- Offline
Less
More
- Posts: 4403
21 Mar 2013 18:17 - 21 Mar 2013 18:18 #7966
by PhracturedBlue
Replied by PhracturedBlue on topic DSM Telemetry support
It is a little complicatedruns as:so C will sign-extend a signed 8-bit int to 16 or 32 bits, but will not extend an unsigned 8-bit int to 16 or 32 bits
So when building a signed 16bit value from 2 8bit unsigned values, you are right in the need to cast to s16
int main() {
uint8_t a = 0xff;
int8_t a1 = a;
int16_t b = (int32_t) a;
int32_t c = (int32_t) a;
printf("u8: %d s16: %d s32: %d\n", a, b, c);
b = (int32_t) a1;
c = (int32_t) a1;
printf("s8: %d s16: %d s32: %d\n", a1, b, c);
return 0;
}u8: 255 s16: 255 s32: 255
s8: -1 s16: -1 s32: -1So when building a signed 16bit value from 2 8bit unsigned values, you are right in the need to cast to s16
Last edit: 21 Mar 2013 18:18 by PhracturedBlue.
- rbe2012
-
- Offline
- So much to do, so little time...
Less
More
- Posts: 1433
21 Mar 2013 21:08 #7975
by rbe2012
Replied by rbe2012 on topic DSM Telemetry support
I didn't look too far into it, but I think the problem is the "<<" what will moveSoBut (s16) works also.
(s8) 1xxxxxxx -> (s32) 00000000 00000000 1xxxxxxx 00000000 - always positive
(s8) 1xxxxxxx -> (s16) 1xxxxxxx 00000000 - keeps sign from s8((s32)(s8)1xxxxxxx) << 8 -> (s32) 11111111 11111111 1xxxxxxx 00000000- vlad_vy
-
- Offline
Less
More
- Posts: 3333
22 Mar 2013 03:56 - 22 Mar 2013 04:01 #7986
by vlad_vy
Replied by vlad_vy on topic DSM Telemetry support
Possible in this case will be better:
Telemetry.temp[0] = ((s32)((s16)(packet[6] << 8) | packet[7]) - 32) * 5 / 9;
or
Telemetry.temp[0] = ((s32)(s16)((packet[6] << 8) | packet[7]) - 32) * 5 / 9;
Last edit: 22 Mar 2013 04:01 by vlad_vy.
- rbe2012
-
- Offline
- So much to do, so little time...
Less
More
- Posts: 1433
22 Mar 2013 06:21 - 22 Mar 2013 06:22 #7989
by rbe2012
Replied by rbe2012 on topic DSM Telemetry support
The important thing will be that the compiler has to know if it has to preserve a sign flag (highest bit). The result of (byte << 8 ) will be unsigned 16 internally so expansion to 32bit will fill the MSB 16 bit with '0'. (s16)(byte << 8 ) tells the compiler that the result has a sign flag and it will expand it to 1..11..1byte0..0 if the MSB of byte was '1' and to 0..00..0byte0..0 if not.
I have not tested what happens if packet[] is s8, not u8 (such like "(s32)(((s8)byte) << 8 )". Possibly "(s8)byte << 8" will be treated as signed (and internally converted to s16).
I have not tested what happens if packet[] is s8, not u8 (such like "(s32)(((s8)byte) << 8 )". Possibly "(s8)byte << 8" will be treated as signed (and internally converted to s16).
Last edit: 22 Mar 2013 06:22 by rbe2012.
- vlad_vy
-
- Offline
Less
More
- Posts: 3333
22 Mar 2013 16:07 - 23 Mar 2013 13:37 #8005
by vlad_vy
Replied by vlad_vy on topic DSM Telemetry support
Altimeter sensor = tested, OK.
Sensor very sensitive, it really sense every 0.1m. Therefore code for altimeter slightly changed, to display altitude in 0.1m
Sensor very sensitive, it really sense every 0.1m. Therefore code for altimeter slightly changed, to display altitude in 0.1m
static void parse_telemetry_packet()
{
u32 time_ms = CLOCK_getms();
switch(packet[0]) {
case 0x7f: //TM1000 Flight log
case 0xff: //TM1100 Flight log
//Telemetry.fadesA = ((s32)packet[2] << 8) | packet[3];
//Telemetry.fadesB = ((s32)packet[4] << 8) | packet[5];
//Telemetry.fadesL = ((s32)packet[6] << 8) | packet[7];
//Telemetry.fadesR = ((s32)packet[8] << 8) | packet[9];
//Telemetry.frameloss = ((s32)packet[10] << 8) | packet[11];
//Telemetry.holds = ((s32)packet[12] << 8) | packet[13];
Telemetry.volt[1] = ((((s32)packet[14] << 8) | packet[15]) + 5) / 10; //In 1/10 of Volts
Telemetry.time[0] = time_ms;
Telemetry.time[1] = Telemetry.time[0];
break;
case 0x7e: //TM1000
case 0xfe: //TM1100
Telemetry.rpm[0] = (packet[2] << 8) | packet[3];
if ((Telemetry.rpm[0] == 0xffff) || (Telemetry.rpm[0] < 200))
Telemetry.rpm[0] = 0;
else
Telemetry.rpm[0] = 120000000 / 2 / Telemetry.rpm[0]; //In RPM (2 = number of poles)
//Telemetry.rpm[0] = 120000000 / number_of_poles(2, 4, ... 32) / gear_ratio(0.01 - 30.99) / Telemetry.rpm[0];
//by default number_of_poles = 2, gear_ratio = 1.00
Telemetry.volt[0] = ((((s32)packet[4] << 8) | packet[5]) + 5) / 10; //In 1/10 of Volts
Telemetry.temp[0] = (((s16)(packet[6] << 8) | packet[7]) - 32) * 5 / 9; //In degrees-C (16Bit signed integer !!!)
if (Telemetry.temp[0] > 500 || Telemetry.temp[0] < -100)
Telemetry.temp[0] = 0;
Telemetry.time[0] = time_ms;
Telemetry.time[1] = Telemetry.time[0];
break;
case 0x03: //High Current sensor
//Telemetry.current = (((s32)packet[2] << 8) | packet[3]) * 1967 / 1000; //In 1/10 of Amps (16bit value, 1 unit is 0.1967A)
//Telemetry.time[x1] = time_ms;
break;
case 0x0a: //Powerbox sensor
//Telemetry.pwb.volt1 = (((s32)packet[2] << 8) | packet[3] + 5) /10; //In 1/10 of Volts
//Telemetry.pwb.volt1 = (((s32)packet[4] << 8) | packet[5] + 5) /10; //In 1/10 of Volts
//Telemetry.pwb.capacity1 = ((s32)packet[6] << 8) | packet[7]; //In mAh
//Telemetry.pwb.capacity2 = ((s32)packet[8] << 8) | packet[9]; //In mAh
//Telemetry.pwb.alarm_v1 = packet[15] & 0x01; //0 = disable, 1 = enable
//Telemetry.pwb.alarm_v2 = (packet[15] >> 1) & 0x01; //0 = disable, 1 = enable
//Telemetry.pwb.alarm_c1 = (packet[15] >> 2) & 0x01; //0 = disable, 1 = enable
//Telemetry.pwb.alarm_c2 = (packet[15] >> 3) & 0x01; //0 = disable, 1 = enable
//Telemetry.time[x2] = time_ms;
break;
case 0x11: //AirSpeed sensor
//Telemetry.airspeed = ((s32)packet[2] << 8) | packet[3]; //In km/h (16Bit value, 1 unit is 1 km/h)
//Telemetry.time[x3] = time_ms;
break;
case 0x12: //Altimeter sensor
//Telemetry.altitude = (s16)(packet[2] << 8) | packet[3]; //In 0.1 meters (16Bit signed integer, 1 unit is 0.1m)
//Telemetry.time[x4] = time_ms;
break;
case 0x14: //G-Force sensor
//Telemetry.gforce.x = (s16)(packet[2] << 8) | packet[3]; //In 0.01g (16Bit signed integers, unit is 0.01g)
//Telemetry.gforce.y = (s16)(packet[4] << 8) | packet[5];
//Telemetry.gforce.z = (s16)(packet[6] << 8) | packet[7];
//Telemetry.gforce.xmax = (s16)(packet[8] << 8) | packet[9];
//Telemetry.gforce.ymax = (s16)(packet[10] << 8) | packet[11];
//Telemetry.gforce.zmax = (s16)(packet[12] << 8) | packet[13];
//Telemetry.gforce.zmin = (s16)(packet[14] << 8) | packet[15];
//Telemetry.time[x5] = time_ms;
break;
case 0x15: //JetCat sensor
//Telemetry.jc.status = packet[2];
//Possible messages for status:
//0x00:OFF
//0x01:WAIT FOR RPM
//0x02:IGNITE
//0x03;ACCELERATE
//0x04:STABILIZE
//0x05:LEARN HIGH
//0x06:LEARN LOW
//0x07:undef
//0x08:SLOW DOWN
//0x09:MANUAL
//0x0a,0x10:AUTO OFF
//0x0b,0x11:RUN
//0x0c,0x12:ACCELERATION DELAY
//0x0d,0x13:SPEED REG
//0x0e,0x14:TWO SHAFT REGULATE
//0x0f,0x15:PRE HEAT
//0x16:PRE HEAT 2
//0x17:MAIN F START
//0x18:not used
//0x19:KERO FULL ON
//0x1a:MAX STATE
//Telemetry.jc.throttle = (packet[3] >> 4) * 10 + (packet[3] & 0x0f); //up to 159% (the upper nibble is 0-f, the lower nibble 0-9)
//Telemetry.jc.pack_volt = (((packet[4] >> 4) * 10 + (packet[4] & 0x0f)) * 100
// + (packet[5] >> 4) * 10 + (packet[5] & 0x0f) + 5) / 10; //In 1/10 of Volts
//Telemetry.jc.pump_volt = (((packet[6] >> 6) * 10 + (packet[6] & 0x0f)) * 100
// + (packet[7] >> 4) * 10 + (packet[7] & 0x0f) + 5) / 10; //In 1/10 of Volts
//Telemetry.jc.rpm = ((packet[10] >> 4) * 10 + (packet[10] & 0x0f)) * 10000
// + ((packet[9] >> 4) * 10 + (packet[9] & 0x0f)) * 100
// + ((packet[8] >> 4) * 10 + (packet[8] & 0x0f)); //RPM up to 999999
//Telemetry.jc.tempEGT = (packet[13] & 0x0f) * 100 + (packet[12] >> 4) * 10 + (packet[12] & 0x0f); //EGT temp up to 999°
//Telemetry.jc.off_condition = packet[14];
//Messages for Off_Condition:
//0x00:NA
//0x01:OFF BY RC
//0x02:OVER TEMPERATURE
//0x03:IGNITION TIMEOUT
//0x04:ACCELERATION TIMEOUT
//0x05:ACCELERATION TOO SLOW
//0x06:OVER RPM
//0x07:LOW RPM OFF
//0x08:LOW BATTERY
//0x09:AUTO OFF
//0x0a,0x10:LOW TEMP OFF
//0x0b,0x11:HIGH TEMP OFF
//0x0c,0x12:GLOW PLUG DEFECTIVE
//0x0d,0x13:WATCH DOG TIMER
//0x0e,0x14:FAIL SAFE OFF
//0x0f,0x15:MANUAL OFF
//0x16:POWER BATT FAIL
//0x17:TEMP SENSOR FAIL
//0x18:FUEL FAIL
//0x19:PROP FAIL
//0x1a:2nd ENGINE FAIL
//0x1b:2nd ENGINE DIFFERENTIAL TOO HIGH
//0x1c:2nd ENGINE NO COMMUNICATION
//0x1d:MAX OFF CONDITION
//Telemetry.time[x6] = time_ms;
break;
case 0x16: //GPS sensor
Telemetry.gps.altitude = (((packet[3] >> 4) * 10 + (packet[3] & 0x0f)) * 100 //(16Bit decimal, 1 unit is 0.1m)
+ ((packet[2] >> 4) * 10 + (packet[2] & 0x0f))) * 100; //In meters * 1000
Telemetry.gps.latitude = ((packet[7] >> 4) * 10 + (packet[7] & 0x0f)) * 3600000
+ ((packet[6] >> 4) * 10 + (packet[6] & 0x0f)) * 60000
+ ((packet[5] >> 4) * 10 + (packet[5] & 0x0f)) * 600
+ ((packet[4] >> 4) * 10 + (packet[4] & 0x0f)) * 6; // (decimal, format DD MM.SSSS)
if ((packet[15] & 0x01) == 0)
Telemetry.gps.latitude *= -1;
Telemetry.gps.longitude = ((packet[11] >> 4) * 10 + (packet[11] & 0x0f)) * 3600000
+ ((packet[10] >> 4) * 10 + (packet[10] & 0x0f)) * 60000
+ ((packet[9] >> 4) * 10 + (packet[9] & 0x0f)) * 600
+ ((packet[8] >> 4) * 10 + (packet[8] & 0x0f)) * 6; // (decimal, format DD MM.SSSS)
if ((packet[15] & 0x04) == 4)
Telemetry.gps.longitude += 360000000;
if ((packet[15] & 0x02) == 0)
Telemetry.gps.longitude *= -1;
// Telemetry.gps.heading = ((packet[13] >> 4) * 10 + (packet[13] & 0x0f)) * 10 //(16Bit decimal, 1 unit is 0.1 degree)
// + ((packet[12] >> 4) * 10 + (packet[12] & 0x0f)) / 10; //In degrees
Telemetry.time[2] = time_ms;
break;
case 0x17: //GPS sensor
Telemetry.gps.velocity = (((packet[3] >> 4) * 10 + (packet[3] & 0x0f)) * 100
+ ((packet[2] >> 4) * 10 + (packet[2] & 0x0f))) * 5556 / 108; //In m/s * 1000
u8 hour = (packet[7] >> 4) * 10 + (packet[7] & 0x0f);
u8 min = (packet[6] >> 4) * 10 + (packet[6] & 0x0f);
u8 sec = (packet[5] >> 4) * 10 + (packet[5] & 0x0f);
//u8 ssec = (packet[4] >> 4) * 10 + (packet[4] & 0x0f);
u8 day = 0;
u8 month = 0;
u8 year = 0; // + 2000
Telemetry.gps.time = ((year & 0x3F) << 26)
| ((month & 0x0F) << 22)
| ((day & 0x1F) << 17)
| ((hour & 0x1F) << 12)
| ((min & 0x3F) << 6)
| ((sec & 0x3F) << 0);
// Telemetry.gps.sats = ((packet[8] >> 4) * 10 + (packet[8] & 0x0f));
Telemetry.time[2] = time_ms;
break;
}
}
Last edit: 23 Mar 2013 13:37 by vlad_vy.
- vlad_vy
-
- Offline
Less
More
- Posts: 3333
23 Mar 2013 09:33 - 30 Mar 2013 15:47 #8010
by vlad_vy
Replied by vlad_vy on topic DSM Telemetry support
High Current Sensor = tested and corrected, OK
The value is 16bit signed integer, the sensor can measure positive and negative current, therefore code for High Current Sensor changed:
The value is 16bit signed integer, the sensor can measure positive and negative current, therefore code for High Current Sensor changed:
static void parse_telemetry_packet()
{
u32 time_ms = CLOCK_getms();
switch(packet[0]) {
case 0x7f: //TM1000 Flight log
case 0xff: //TM1100 Flight log
//Telemetry.fadesA = ((s32)packet[2] << 8) | packet[3];
//Telemetry.fadesB = ((s32)packet[4] << 8) | packet[5];
//Telemetry.fadesL = ((s32)packet[6] << 8) | packet[7];
//Telemetry.fadesR = ((s32)packet[8] << 8) | packet[9];
//Telemetry.frameloss = ((s32)packet[10] << 8) | packet[11];
//Telemetry.holds = ((s32)packet[12] << 8) | packet[13];
Telemetry.volt[1] = ((((s32)packet[14] << 8) | packet[15]) + 5) / 10; //In 1/10 of Volts
Telemetry.time[0] = time_ms;
Telemetry.time[1] = Telemetry.time[0];
break;
case 0x7e: //TM1000
case 0xfe: //TM1100
Telemetry.rpm[0] = (packet[2] << 8) | packet[3];
if ((Telemetry.rpm[0] == 0xffff) || (Telemetry.rpm[0] < 200))
Telemetry.rpm[0] = 0;
else
Telemetry.rpm[0] = 120000000 / 2 / Telemetry.rpm[0]; //In RPM (2 = number of poles)
//Telemetry.rpm[0] = 120000000 / number_of_poles(2, 4, ... 32) / gear_ratio(0.01 - 30.99) / Telemetry.rpm[0];
//by default number_of_poles = 2, gear_ratio = 1.00
Telemetry.volt[0] = ((((s32)packet[4] << 8) | packet[5]) + 5) / 10; //In 1/10 of Volts
Telemetry.temp[0] = ((s32)((s16)(packet[6] << 8) | packet[7]) - 32) * 5 / 9; //In degrees-C (16Bit signed integer)
if (Telemetry.temp[0] > 500 || Telemetry.temp[0] < -100)
Telemetry.temp[0] = 0;
Telemetry.time[0] = time_ms;
Telemetry.time[1] = Telemetry.time[0];
break;
case 0x03: //High Current sensor
//Telemetry.current = (s32)((s16)(packet[2] << 8) | packet[3]) * 196791 / 100000; //In 1/10 of Amps (16bit signed integer, 1 unit is 0.196791A)
//Telemetry.time[x1] = time_ms;
break;
case 0x0a: //Powerbox sensor
//Telemetry.pwb.volt1 = (((s32)packet[2] << 8) | packet[3] + 5) /10; //In 1/10 of Volts
//Telemetry.pwb.volt1 = (((s32)packet[4] << 8) | packet[5] + 5) /10; //In 1/10 of Volts
//Telemetry.pwb.capacity1 = ((s32)packet[6] << 8) | packet[7]; //In mAh
//Telemetry.pwb.capacity2 = ((s32)packet[8] << 8) | packet[9]; //In mAh
//Telemetry.pwb.alarm_v1 = packet[15] & 0x01; //0 = disable, 1 = enable
//Telemetry.pwb.alarm_v2 = (packet[15] >> 1) & 0x01; //0 = disable, 1 = enable
//Telemetry.pwb.alarm_c1 = (packet[15] >> 2) & 0x01; //0 = disable, 1 = enable
//Telemetry.pwb.alarm_c2 = (packet[15] >> 3) & 0x01; //0 = disable, 1 = enable
//Telemetry.time[x2] = time_ms;
break;
case 0x11: //AirSpeed sensor
//Telemetry.airspeed = ((s32)packet[2] << 8) | packet[3]; //In km/h (16Bit value, 1 unit is 1 km/h)
//Telemetry.time[x3] = time_ms;
break;
case 0x12: //Altimeter sensor
//Telemetry.altitude = (s16)(packet[2] << 8) | packet[3]; //In 0.1 meters (16Bit signed integer, 1 unit is 0.1m)
//Telemetry.time[x4] = time_ms;
break;
case 0x14: //G-Force sensor
//Telemetry.gforce.x = (s16)(packet[2] << 8) | packet[3]; //In 0.01g (16Bit signed integers, unit is 0.01g)
//Telemetry.gforce.y = (s16)(packet[4] << 8) | packet[5];
//Telemetry.gforce.z = (s16)(packet[6] << 8) | packet[7];
//Telemetry.gforce.xmax = (s16)(packet[8] << 8) | packet[9];
//Telemetry.gforce.ymax = (s16)(packet[10] << 8) | packet[11];
//Telemetry.gforce.zmax = (s16)(packet[12] << 8) | packet[13];
//Telemetry.gforce.zmin = (s16)(packet[14] << 8) | packet[15];
//Telemetry.time[x5] = time_ms;
break;
case 0x15: //JetCat sensor
//Telemetry.jc.status = packet[2];
//Possible messages for status:
//0x00:OFF
//0x01:WAIT FOR RPM
//0x02:IGNITE
//0x03;ACCELERATE
//0x04:STABILIZE
//0x05:LEARN HIGH
//0x06:LEARN LOW
//0x07:undef
//0x08:SLOW DOWN
//0x09:MANUAL
//0x0a,0x10:AUTO OFF
//0x0b,0x11:RUN
//0x0c,0x12:ACCELERATION DELAY
//0x0d,0x13:SPEED REG
//0x0e,0x14:TWO SHAFT REGULATE
//0x0f,0x15:PRE HEAT
//0x16:PRE HEAT 2
//0x17:MAIN F START
//0x18:not used
//0x19:KERO FULL ON
//0x1a:MAX STATE
//Telemetry.jc.throttle = (packet[3] >> 4) * 10 + (packet[3] & 0x0f); //up to 159% (the upper nibble is 0-f, the lower nibble 0-9)
//Telemetry.jc.pack_volt = (((packet[4] >> 4) * 10 + (packet[4] & 0x0f)) * 100
// + (packet[5] >> 4) * 10 + (packet[5] & 0x0f) + 5) / 10; //In 1/10 of Volts
//Telemetry.jc.pump_volt = (((packet[6] >> 6) * 10 + (packet[6] & 0x0f)) * 100
// + (packet[7] >> 4) * 10 + (packet[7] & 0x0f) + 5) / 10; //In 1/10 of Volts
//Telemetry.jc.rpm = ((packet[10] >> 4) * 10 + (packet[10] & 0x0f)) * 10000
// + ((packet[9] >> 4) * 10 + (packet[9] & 0x0f)) * 100
// + ((packet[8] >> 4) * 10 + (packet[8] & 0x0f)); //RPM up to 999999
//Telemetry.jc.tempEGT = (packet[13] & 0x0f) * 100 + (packet[12] >> 4) * 10 + (packet[12] & 0x0f); //EGT temp up to 999°
//Telemetry.jc.off_condition = packet[14];
//Messages for Off_Condition:
//0x00:NA
//0x01:OFF BY RC
//0x02:OVER TEMPERATURE
//0x03:IGNITION TIMEOUT
//0x04:ACCELERATION TIMEOUT
//0x05:ACCELERATION TOO SLOW
//0x06:OVER RPM
//0x07:LOW RPM OFF
//0x08:LOW BATTERY
//0x09:AUTO OFF
//0x0a,0x10:LOW TEMP OFF
//0x0b,0x11:HIGH TEMP OFF
//0x0c,0x12:GLOW PLUG DEFECTIVE
//0x0d,0x13:WATCH DOG TIMER
//0x0e,0x14:FAIL SAFE OFF
//0x0f,0x15:MANUAL OFF
//0x16:POWER BATT FAIL
//0x17:TEMP SENSOR FAIL
//0x18:FUEL FAIL
//0x19:PROP FAIL
//0x1a:2nd ENGINE FAIL
//0x1b:2nd ENGINE DIFFERENTIAL TOO HIGH
//0x1c:2nd ENGINE NO COMMUNICATION
//0x1d:MAX OFF CONDITION
//Telemetry.time[x6] = time_ms;
break;
case 0x16: //GPS sensor
Telemetry.gps.altitude = (((packet[3] >> 4) * 10 + (packet[3] & 0x0f)) * 100
+ ((packet[2] >> 4) * 10 + (packet[2] & 0x0f))) * 100; //In meters * 1000 (16Bit decimal, 1 unit is 0.1m)
Telemetry.gps.latitude = ((packet[7] >> 4) * 10 + (packet[7] & 0x0f)) * 3600000
+ ((packet[6] >> 4) * 10 + (packet[6] & 0x0f)) * 60000
+ ((packet[5] >> 4) * 10 + (packet[5] & 0x0f)) * 600
+ ((packet[4] >> 4) * 10 + (packet[4] & 0x0f)) * 6; // (decimal, format DD MM.SSSS)
if ((packet[15] & 0x01) == 0)
Telemetry.gps.latitude *= -1; //1=N(+), 0=S(-)
Telemetry.gps.longitude = ((packet[11] >> 4) * 10 + (packet[11] & 0x0f)) * 3600000
+ ((packet[10] >> 4) * 10 + (packet[10] & 0x0f)) * 60000
+ ((packet[9] >> 4) * 10 + (packet[9] & 0x0f)) * 600
+ ((packet[8] >> 4) * 10 + (packet[8] & 0x0f)) * 6; // (decimal, format DD MM.SSSS)
if ((packet[15] & 0x04) == 4)
Telemetry.gps.longitude += 360000000; //1=+100 degrees
if ((packet[15] & 0x02) == 0)
Telemetry.gps.longitude *= -1; //1=E(+), 0=W(-)
//Telemetry.gps.heading = ((packet[13] >> 4) * 10 + (packet[13] & 0x0f)) * 10
// + ((packet[12] >> 4) * 10 + (packet[12] & 0x0f)) / 10; //In degrees (16Bit decimal, 1 unit is 0.1 degree)
Telemetry.time[2] = time_ms;
break;
case 0x17: //GPS sensor
Telemetry.gps.velocity = (((packet[3] >> 4) * 10 + (packet[3] & 0x0f)) * 100
+ ((packet[2] >> 4) * 10 + (packet[2] & 0x0f))) * 5556 / 108; //In m/s * 1000
u8 hour = (packet[7] >> 4) * 10 + (packet[7] & 0x0f);
u8 min = (packet[6] >> 4) * 10 + (packet[6] & 0x0f);
u8 sec = (packet[5] >> 4) * 10 + (packet[5] & 0x0f);
//u8 ssec = (packet[4] >> 4) * 10 + (packet[4] & 0x0f);
u8 day = 0;
u8 month = 0;
u8 year = 0; // + 2000
Telemetry.gps.time = ((year & 0x3F) << 26)
| ((month & 0x0F) << 22)
| ((day & 0x1F) << 17)
| ((hour & 0x1F) << 12)
| ((min & 0x3F) << 6)
| ((sec & 0x3F) << 0);
//Telemetry.gps.sats = ((packet[8] >> 4) * 10 + (packet[8] & 0x0f));
Telemetry.time[2] = time_ms;
break;
}
}
Last edit: 30 Mar 2013 15:47 by vlad_vy.
- vlad_vy
-
- Offline
Less
More
- Posts: 3333
23 Mar 2013 09:46 #8011
by vlad_vy
Replied by vlad_vy on topic DSM Telemetry support
I completed all possible tests. Up to present day were tested:
1. High Current sensor
2. AirSpeed sensor
3. Altimeter sensor
4. G-Force sensor
5. GPS sensor
6. Telemetry.rpm
7. Telemetry.temp
I can't test:
1. Powerbox sensor
2. JetCat sensor
1. High Current sensor
2. AirSpeed sensor
3. Altimeter sensor
4. G-Force sensor
5. GPS sensor
6. Telemetry.rpm
7. Telemetry.temp
I can't test:
1. Powerbox sensor
2. JetCat sensor
- vlad_vy
-
- Offline
Less
More
- Posts: 3333
18 Apr 2013 16:00 - 02 May 2013 12:54 #9033
by vlad_vy
Replied by vlad_vy on topic DSM Telemetry support
Some changes related to GPS altitude. In GPS packet (0x16) the altitude can be up to 999.9m, it's not enought. Last find - next part of GPS altitude transmitted in other GPS packet (0x17), it's the altitude in 1000m.
Therefore code for GPS sensor changed:
Therefore code for GPS sensor changed:
static void parse_telemetry_packet()
{
static s32 altitude;
u32 time_ms = CLOCK_getms();
switch(packet[0]) {
case 0x7f: //TM1000 Flight log
case 0xff: //TM1100 Flight log
//Telemetry.fadesA = ((s32)packet[2] << 8) | packet[3]; //0xFFFF = NC (not connected)
//Telemetry.fadesB = ((s32)packet[4] << 8) | packet[5]; //0xFFFF = NC (not connected)
//Telemetry.fadesL = ((s32)packet[6] << 8) | packet[7]; //0xFFFF = NC (not connected)
//Telemetry.fadesR = ((s32)packet[8] << 8) | packet[9]; //0xFFFF = NC (not connected)
//Telemetry.frameloss = ((s32)packet[10] << 8) | packet[11];
//Telemetry.holds = ((s32)packet[12] << 8) | packet[13];
Telemetry.volt[1] = ((((s32)packet[14] << 8) | packet[15]) + 5) / 10; //In 1/10 of Volts
Telemetry.time[0] = time_ms;
Telemetry.time[1] = Telemetry.time[0];
break;
case 0x7e: //TM1000
case 0xfe: //TM1100
Telemetry.rpm[0] = (packet[2] << 8) | packet[3];
if ((Telemetry.rpm[0] == 0xffff) || (Telemetry.rpm[0] < 200))
Telemetry.rpm[0] = 0;
else
Telemetry.rpm[0] = 120000000 / 2 / Telemetry.rpm[0]; //In RPM (2 = number of poles)
//Telemetry.rpm[0] = 120000000 / number_of_poles(2, 4, ... 32) / gear_ratio(0.01 - 30.99) / Telemetry.rpm[0];
//by default number_of_poles = 2, gear_ratio = 1.00
Telemetry.volt[0] = ((((s32)packet[4] << 8) | packet[5]) + 5) / 10; //In 1/10 of Volts
Telemetry.temp[0] = ((s32)((s16)(packet[6] << 8) | packet[7]) - 32) * 5 / 9; //In degrees-C (16Bit signed integer)
if (Telemetry.temp[0] > 500 || Telemetry.temp[0] < -100)
Telemetry.temp[0] = 0;
Telemetry.time[0] = time_ms;
Telemetry.time[1] = Telemetry.time[0];
break;
case 0x03: //High Current sensor
//Telemetry.current = (s32)((s16)(packet[2] << 8) | packet[3]) * 196791 / 100000; //In 1/10 of Amps (16bit signed integer, 1 unit is 0.196791A)
//Telemetry.time[x1] = time_ms;
break;
case 0x0a: //Powerbox sensor
//Telemetry.pwb.volt1 = (((s32)packet[2] << 8) | packet[3] + 5) /10; //In 1/10 of Volts
//Telemetry.pwb.volt1 = (((s32)packet[4] << 8) | packet[5] + 5) /10; //In 1/10 of Volts
//Telemetry.pwb.capacity1 = ((s32)packet[6] << 8) | packet[7]; //In mAh
//Telemetry.pwb.capacity2 = ((s32)packet[8] << 8) | packet[9]; //In mAh
//Telemetry.pwb.alarm_v1 = packet[15] & 0x01; //0 = disable, 1 = enable
//Telemetry.pwb.alarm_v2 = (packet[15] >> 1) & 0x01; //0 = disable, 1 = enable
//Telemetry.pwb.alarm_c1 = (packet[15] >> 2) & 0x01; //0 = disable, 1 = enable
//Telemetry.pwb.alarm_c2 = (packet[15] >> 3) & 0x01; //0 = disable, 1 = enable
//Telemetry.time[x2] = time_ms;
break;
case 0x11: //AirSpeed sensor
//Telemetry.airspeed = ((s32)packet[2] << 8) | packet[3]; //In km/h (16Bit value, 1 unit is 1 km/h)
//Telemetry.time[x3] = time_ms;
break;
case 0x12: //Altimeter sensor
//Telemetry.altitude = (s16)(packet[2] << 8) | packet[3]; //In 0.1 meters (16Bit signed integer, 1 unit is 0.1m)
//Telemetry.time[x4] = time_ms;
break;
case 0x14: //G-Force sensor
//Telemetry.gforce.x = (s16)(packet[2] << 8) | packet[3]; //In 0.01g (16Bit signed integers, unit is 0.01g)
//Telemetry.gforce.y = (s16)(packet[4] << 8) | packet[5];
//Telemetry.gforce.z = (s16)(packet[6] << 8) | packet[7];
//Telemetry.gforce.xmax = (s16)(packet[8] << 8) | packet[9];
//Telemetry.gforce.ymax = (s16)(packet[10] << 8) | packet[11];
//Telemetry.gforce.zmax = (s16)(packet[12] << 8) | packet[13];
//Telemetry.gforce.zmin = (s16)(packet[14] << 8) | packet[15];
//Telemetry.time[x5] = time_ms;
break;
case 0x15: //JetCat sensor
//Telemetry.jc.status = packet[2];
//Possible messages for status:
//0x00:OFF
//0x01:WAIT FOR RPM
//0x02:IGNITE
//0x03;ACCELERATE
//0x04:STABILIZE
//0x05:LEARN HIGH
//0x06:LEARN LOW
//0x07:undef
//0x08:SLOW DOWN
//0x09:MANUAL
//0x0a,0x10:AUTO OFF
//0x0b,0x11:RUN
//0x0c,0x12:ACCELERATION DELAY
//0x0d,0x13:SPEED REG
//0x0e,0x14:TWO SHAFT REGULATE
//0x0f,0x15:PRE HEAT
//0x16:PRE HEAT 2
//0x17:MAIN F START
//0x18:not used
//0x19:KERO FULL ON
//0x1a:MAX STATE
//Telemetry.jc.throttle = (packet[3] >> 4) * 10 + (packet[3] & 0x0f); //up to 159% (the upper nibble is 0-f, the lower nibble 0-9)
//Telemetry.jc.pack_volt = (((packet[4] >> 4) * 10 + (packet[4] & 0x0f)) * 100
// + (packet[5] >> 4) * 10 + (packet[5] & 0x0f) + 5) / 10; //In 1/10 of Volts
//Telemetry.jc.pump_volt = (((packet[6] >> 6) * 10 + (packet[6] & 0x0f)) * 100
// + (packet[7] >> 4) * 10 + (packet[7] & 0x0f) + 5) / 10; //In 1/10 of Volts
//Telemetry.jc.rpm = ((packet[10] >> 4) * 10 + (packet[10] & 0x0f)) * 10000
// + ((packet[9] >> 4) * 10 + (packet[9] & 0x0f)) * 100
// + ((packet[8] >> 4) * 10 + (packet[8] & 0x0f)); //RPM up to 999999
//Telemetry.jc.tempEGT = (packet[13] & 0x0f) * 100 + (packet[12] >> 4) * 10 + (packet[12] & 0x0f); //EGT temp up to 999°
//Telemetry.jc.off_condition = packet[14];
//Messages for Off_Condition:
//0x00:NA
//0x01:OFF BY RC
//0x02:OVER TEMPERATURE
//0x03:IGNITION TIMEOUT
//0x04:ACCELERATION TIMEOUT
//0x05:ACCELERATION TOO SLOW
//0x06:OVER RPM
//0x07:LOW RPM OFF
//0x08:LOW BATTERY
//0x09:AUTO OFF
//0x0a,0x10:LOW TEMP OFF
//0x0b,0x11:HIGH TEMP OFF
//0x0c,0x12:GLOW PLUG DEFECTIVE
//0x0d,0x13:WATCH DOG TIMER
//0x0e,0x14:FAIL SAFE OFF
//0x0f,0x15:MANUAL OFF
//0x16:POWER BATT FAIL
//0x17:TEMP SENSOR FAIL
//0x18:FUEL FAIL
//0x19:PROP FAIL
//0x1a:2nd ENGINE FAIL
//0x1b:2nd ENGINE DIFFERENTIAL TOO HIGH
//0x1c:2nd ENGINE NO COMMUNICATION
//0x1d:MAX OFF CONDITION
//Telemetry.time[x6] = time_ms;
break;
case 0x16: //GPS sensor (always second GPS packet)
altitude += (((packet[3] >> 4) * 10 + (packet[3] & 0x0f)) * 100
+ ((packet[2] >> 4) * 10 + (packet[2] & 0x0f))) * 100; //In meters * 1000 (16Bit decimal, 1 unit is 0.1m)
Telemetry.gps.altitude = altitude;
Telemetry.gps.latitude = ((packet[7] >> 4) * 10 + (packet[7] & 0x0f)) * 3600000
+ ((packet[6] >> 4) * 10 + (packet[6] & 0x0f)) * 60000
+ ((packet[5] >> 4) * 10 + (packet[5] & 0x0f)) * 600
+ ((packet[4] >> 4) * 10 + (packet[4] & 0x0f)) * 6; // (decimal, format DD MM.SSSS)
if ((packet[15] & 0x01) == 0)
Telemetry.gps.latitude *= -1; //1=N(+), 0=S(-)
Telemetry.gps.longitude = ((packet[11] >> 4) * 10 + (packet[11] & 0x0f)) * 3600000
+ ((packet[10] >> 4) * 10 + (packet[10] & 0x0f)) * 60000
+ ((packet[9] >> 4) * 10 + (packet[9] & 0x0f)) * 600
+ ((packet[8] >> 4) * 10 + (packet[8] & 0x0f)) * 6; // (decimal, format DD MM.SSSS)
if ((packet[15] & 0x04) == 4)
Telemetry.gps.longitude += 360000000; //1=+100 degrees
if ((packet[15] & 0x02) == 0)
Telemetry.gps.longitude *= -1; //1=E(+), 0=W(-)
//Telemetry.gps.heading = ((packet[13] >> 4) * 10 + (packet[13] & 0x0f)) * 10
// + ((packet[12] >> 4) * 10 + (packet[12] & 0x0f)) / 10; //In degrees (16Bit decimal, 1 unit is 0.1 degree)
Telemetry.time[2] = time_ms;
break;
case 0x17: //GPS sensor (always first GPS packet)
Telemetry.gps.velocity = (((packet[3] >> 4) * 10 + (packet[3] & 0x0f)) * 100
+ ((packet[2] >> 4) * 10 + (packet[2] & 0x0f))) * 5556 / 108; //In m/s * 1000
u8 hour = (packet[7] >> 4) * 10 + (packet[7] & 0x0f);
u8 min = (packet[6] >> 4) * 10 + (packet[6] & 0x0f);
u8 sec = (packet[5] >> 4) * 10 + (packet[5] & 0x0f);
//u8 ssec = (packet[4] >> 4) * 10 + (packet[4] & 0x0f);
u8 day = 0;
u8 month = 0;
u8 year = 0; // + 2000
Telemetry.gps.time = ((year & 0x3F) << 26)
| ((month & 0x0F) << 22)
| ((day & 0x1F) << 17)
| ((hour & 0x1F) << 12)
| ((min & 0x3F) << 6)
| ((sec & 0x3F) << 0);
//Telemetry.gps.sats = ((packet[8] >> 4) * 10 + (packet[8] & 0x0f));
altitude = ((packet[9] >> 4) * 10 + (packet[9] & 0x0f)) * 1000000; //In 1000 meters * 1000 (8Bit decimal, 1 unit is 1000m)
Telemetry.time[2] = time_ms;
break;
}
}
Last edit: 02 May 2013 12:54 by vlad_vy.
- FDR
-
- Offline
18 Apr 2013 17:38 - 18 Apr 2013 17:47 #9034
by FDR
Replied by FDR on topic DSM Telemetry support
Wow!
You fly really high!
You fly really high!
Last edit: 18 Apr 2013 17:47 by FDR.
Time to create page: 0.168 seconds
-
Home
-
Forum
-
Development
-
Protocol Development
- DSM Telemetry support