DSM Telemetry support

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.

Please Log in or Create an account to join the conversation.

More
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
        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.

Please Log in or Create an account to join the conversation.

More
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.

Please Log in or Create an account to join the conversation.

More
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.

Please Log in or Create an account to join the conversation.

More
17 Mar 2013 13:48 #7855 by domcars0
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 :angry:

Please Log in or Create an account to join the conversation.

More
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.

Please Log in or Create an account to join the conversation.

More
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
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.

Please Log in or Create an account to join the conversation.

More
21 Mar 2013 15:13 - 21 Mar 2013 15:20 #7960 by vlad_vy
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;
at -18C it displayed 0C (----),


Telemetry.temp[0] = (((s16)(packet[6] << 8) | packet[7]) - 32) * 5 / 9;
displayed temp correctly down to -21C.


AirSpeed Sensor
Telemetry.airspeed = tested, OK
Last edit: 21 Mar 2013 15:20 by vlad_vy.

Please Log in or Create an account to join the conversation.

More
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.

Please Log in or Create an account to join the conversation.

More
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?

Please Log in or Create an account to join the conversation.

More
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:
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.

Please Log in or Create an account to join the conversation.

More
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 complicated
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;
}
runs as:
u8: 255 s16: 255 s32: 255
s8: -1 s16: -1 s32: -1
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
Last edit: 21 Mar 2013 18:18 by PhracturedBlue.

Please Log in or Create an account to join the conversation.

  • rbe2012
  • rbe2012's Avatar
  • Offline
  • So much to do, so little time...
More
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 move
(s8) 1xxxxxxx -> (s32) 00000000 00000000 1xxxxxxx 00000000 - always positive
(s8) 1xxxxxxx -> (s16) 1xxxxxxx 00000000 - keeps sign from s8
So
((s32)(s8)1xxxxxxx) << 8 -> (s32) 11111111 11111111 1xxxxxxx 00000000
But (s16) works also.

Please Log in or Create an account to join the conversation.

More
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.

Please Log in or Create an account to join the conversation.

  • rbe2012
  • rbe2012's Avatar
  • Offline
  • So much to do, so little time...
More
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).
Last edit: 22 Mar 2013 06:22 by rbe2012.

Please Log in or Create an account to join the conversation.

More
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
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.

Please Log in or Create an account to join the conversation.

More
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:
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.

Please Log in or Create an account to join the conversation.

More
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

Please Log in or Create an account to join the conversation.

More
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:
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.

Please Log in or Create an account to join the conversation.

More
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! ;)
Last edit: 18 Apr 2013 17:47 by FDR.

Please Log in or Create an account to join the conversation.

Time to create page: 0.098 seconds
Powered by Kunena Forum