- Posts: 3333
DSM Telemetry support
- vlad_vy
-
- Offline
PhracturedBlue wrote: I reworked the state-machine again. Now it does read both frames of telemetry and it does work with >= 8 channels. However, for unknown reasons only every other telemetry packet is received correctly. I have no idea why that is, but I never get the expected 'end of packet' bit on every other read.
of course, it needs testing to see what else I broke.
Maybe telemetry module change something at every transmission? CRC coding or anything else? What telemetry packet is correct? First or second? Does it has place at both 6/7 and 8/9 channel modes?
- vlad_vy
-
- Offline
- Posts: 3333
www.helifreak.com/showthread.php?t=320846
- PhracturedBlue
-
Topic Author
- Offline
- Posts: 4403
That is useful to know, but I need to know how many pulses Spektrum expects per revolution. Since I don't have a Spektrum radio, there doesn't appear to beany way for me to figure this out.vlad_vy wrote: PB, you can check RPM sensor telemetry without real RPM sensor:
www.helifreak.com/showthread.php?t=320846
It is probably easier for someone with the proper sensor (and a known RPM to just tell me what is reported.
- vlad_vy
-
- Offline
- Posts: 3333
1) AR8000 + TM1000 telemetry module. TM1000 doesn't bind at 6 and 7 channel mode, but bind at 8 and 9 channel mode (bind LED solid).
2) AR6210 + TM1000 telemetry module. TM1000 doesn't bind at 6 and 7 channel mode, and it seems doesn't bind at 8 and 9 channel mode, but TM1000 bind LED fast blink and telemetry really work.
It seems that with DSMX protocol the telemetry works only at 8/9 channel mode. With DSM2 protocol the telemetry works at any channels mode. What is the difference?
Also,
1) Will be better assign internal Rx voltage to Telemetry.volt[1] as for Walkera telemetry.
2) Telemetry temperature data (packet[6] and packet[7]) need to check for 0xFFFF if temperature sensor is disconnected.
- vlad_vy
-
- Offline
- Posts: 3333
PhracturedBlue wrote: I reworked the state-machine again. Now it does read both frames of telemetry and it does work with >= 8 channels. However, for unknown reasons only every other telemetry packet is received correctly. I have no idea why that is, but I never get the expected 'end of packet' bit on every other read.
of course, it needs testing to see what else I broke.
PB, if I right understand RW9UAO, with DSMX protocol (unlike dsm2) the telemetry packet transmit only once at second half of 22ms. Can you check it?
- PhracturedBlue
-
Topic Author
- Offline
- Posts: 4403
- RW9UAO
-
- Offline
- Posts: 25
some rework code for DSM telemetry. i think it more usable. DEVO telemetry screen as is.
check for //RW9UAO comments. don`t know how to make diff patch.
https://docs.google.com/file/d/0B1Bo-wTTor5LZDZWM3UzZHZCSUE/edit?usp=sharing
p.s. found small bug: PhracturedBlue-deviation-b1b5bcecde6b\src\target\common_devo\protocol\cyrf6936.c
u8 CYRF_ReadRSSI(u32 dodummyread){
return (result & 0x0F);
return (result & 0x1F);//rssi has 5 bits, not 4
- rbe2012
-
- Offline
- So much to do, so little time...
- Posts: 1433
with "patch -p1 < filename.patch".
For the bug you have found you should file an issue on bitbucket.
- vlad_vy
-
- Offline
- Posts: 3333
Data structure:
0[00] 22(0x16)
1[01] 00
2[02] Altitude LSB
3[03] Altitude MSB
4[04] 1/100th of a degree second latitude (Decimal)
5[05] degree seconds latitude (Decimal)
6[06] degree minutes latitude (Decimal)
7[07] degrees latitude (Decimal)
8[08] 1/100th of a degree second longitude (Decimal)
9[09] degree seconds longitude (Decimal)
10[0A] degree minutes longitude (Decimal)
11[0B] degrees longitude (Decimal)
12[0C] Heading LSB (Decimal)
13[0D] Heading MSB (Decimal) Divide by 10 for Degrees
14[0E] Unknown
15[0F] Unknown
0[00] 23(0x17)
1[01] 00
2[02] Speed LSB (Decimal)
3[03] Speed MSB (Decimal) Divide by 10 for Knots. Multiply by 0.185 for Kph and 0.115 for Mph
4[04] UTC Time LSB 1/10th sec.
5[05] UTC Time
6[06] UTC Time
7[07] UTC Time MSB
8[08] Number of Sats (Decimal)
9[09] 00
10[0A]-15[0F] Unused (But contains Data left in buffer)
- vlad_vy
-
- Offline
- Posts: 3333
if(Model.protocol == PROTOCOL_DSMX)
packet[12] = num_channels < 8 ? 0xb2 : 0xb2;
else
packet[12] = num_channels < 8 ? 0x01 : 0x02;
- vlad_vy
-
- Offline
- Posts: 3333
static void parse_telemetry_packet()
{
if(packet[0] == 0x7f || packet[0] == 0xff) { //TM1000 or 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] = CLOCK_getms();
Telemetry.time[1] = Telemetry.time[0];
} else if (packet[0] == 0x7e || packet[0] == 0xfe) { //TM1000 or TM1100
Telemetry.rpm[0] = ((packet[2] << 8) | packet[3]); //In RPM
if (Telemetry.rpm[0] == 0xffff)
Telemetry.rpm[0] = 0;
Telemetry.volt[0] = ((((s32)packet[4] << 8) | packet[5]) + 5) / 10; //In 1/10 of Volts
Telemetry.temp[0] = packet[7] == 0xff ? 0 : (packet[7] - 32) * 5 / 9; //In degrees-C (16Bit signed integer !!!)
//Telemetry.temp[0] = ((((s16)packet[6] << 8) | packet[7]) - 32) * 5 / 9; //(16Bit signed integer)
//if (Telemetry.temp[0] > 500 || Telemetry.temp[0] < -100)
// Telemetry.temp[0] = 0;
Telemetry.time[0] = CLOCK_getms();
Telemetry.time[1] = Telemetry.time[0];
} else if (packet[0] == 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] = CLOCK_getms();
} else if (packet[0] == 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] + 5); //In mAh
//Telemetry.pwb.capacity2 = (((s32)packet[8] << 8) | packet[9] + 5); //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] = CLOCK_getms();
} else if (packet[0] == 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] = CLOCK_getms();
} else if (packet[0] == 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] = CLOCK_getms();
} else if (packet[0] == 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] = CLOCK_getms();
} else if (packet[0] == 0x15) { //JetCat sensor
} else if (packet[0] == 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;
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;
// 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] = CLOCK_getms();
} else if (packet[0] == 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
//u32 utc_time = ((packet[7] >> 4) * 10 + (packet[7] & 0x0f)) * 1000000
//+ ((packet[6] >> 4) * 10 + (packet[6] & 0x0f)) * 10000
//+ ((packet[5] >> 4) * 10 + (packet[5] & 0x0f)) * 100
//+ ((packet[4] >> 4) * 10 + (packet[4] & 0x0f));
Telemetry.gps.time = 0; //Not calculated yet
// Telemetry.gps.sats = ((packet[8] >> 4) * 10 + (packet[8] & 0x0f));
Telemetry.time[2] = CLOCK_getms();
}
}
GPS sensor tested and works fine, with except:
1) I cann't calculate date/time from UTC time
2) I cann't test Heading and number of sats without screen output
3) I don't know how telemetry transmit lattitude N and S, and four longitude sectors (0-90) for +0~+180 and -0~-180. Now it works only for lattitude +0~+90 degree and longitude +0~+90 degree. Possible this info contained at 14 and 15 bytes of GPS(0x16) packet.
What I can test:
1) GPS Sensor
2) High Current Sensor
3) AirSpeed Sensor
4) G-Force Sensor
5) Brushless RPM Sensor
6) Magnetic RPM Sensor (Eagle Tree, waiting connectors)
7) Altimeter Sensor (will get it soon)
- RW9UAO
-
- Offline
- Posts: 25
one more adding:
_telemtest_page.c
void PAGE_TelemtestEvent() {
time_count ++;
//if (time_count < 10) // 100ms x10 = 2seconds, to slow down the refresh rate to once per 2s
// return;
time_count = 0;
int i;
u32 time = CLOCK_getms();
//RW9UAO
if (Telemetry.RSSI != tp.telem.RSSI) {
if (OBJ_IS_USED(&gui1->RSSI))
GUI_Redraw(&gui1->RSSI);
tp.telem.RSSI = Telemetry.RSSI;
}
if (Telemetry.A != tp.telem.A) {
if (OBJ_IS_USED(&gui1->A))
GUI_Redraw(&gui1->A);
tp.telem.A = Telemetry.A;
}
if (Telemetry.B != tp.telem.B) {
if (OBJ_IS_USED(&gui1->B))
GUI_Redraw(&gui1->B);
tp.telem.B = Telemetry.B;
}
if (Telemetry.L != tp.telem.L) {
if (OBJ_IS_USED(&gui1->L))
GUI_Redraw(&gui1->L);
tp.telem.L = Telemetry.L;
}
if (Telemetry.R != tp.telem.R) {
if (OBJ_IS_USED(&gui1->R))
GUI_Redraw(&gui1->R);
tp.telem.R = Telemetry.R;
}
if (Telemetry.F != tp.telem.F) {
if (OBJ_IS_USED(&gui1->F))
GUI_Redraw(&gui1->F);
tp.telem.F = Telemetry.F;
}
if (Telemetry.H != tp.telem.H) {
if (OBJ_IS_USED(&gui1->H))
GUI_Redraw(&gui1->H);
tp.telem.H = Telemetry.H;
}
if (Telemetry.current != tp.telem.current) {
if (OBJ_IS_USED(&gui1->current))
GUI_Redraw(&gui1->current);
tp.telem.current = Telemetry.current;
}
//RW9UAO
for(i = 0; i < 3; i++) {
if (Telemetry.volt[i] != tp.telem.volt[i]) {
if (OBJ_IS_USED(&gui1->volt[i])) // in devo10, the item objects are drawn in different pages, so some of them might not exist in a page
GUI_Redraw(&gui1->volt[i]);
tp.telem.volt[i] = Telemetry.volt[i];
}
}dsm2.c
//Read telemetry if needed
if(CYRF_ReadRegister(0x07) & 0x02) {
//RW9UAO
Telemetry.RSSI = CYRF_ReadRegister(0x13) & 0x1F;
CYRF_ReadDataPacket(packet);
if(CYRF_ReadRegister(0x09) == 0x10){//rx count
parse_telemetry_packet();
}
}- RW9UAO
-
- Offline
- Posts: 25
- vlad_vy
-
- Offline
- Posts: 3333
vlad_vy wrote: Draft version of telemetry parser
3) I don't know how telemetry transmit lattitude N and S, and four longitude sectors (0-90) for +0~+180 and -0~-180. Now it works only for lattitude +0~+90 degree and longitude +0~+90 degree. Possible this info contained at 14 and 15 bytes of GPS(0x16) packet.
Byte 15 of GPS(0x16) packet:
First bit is lattitude sign 1=N(+), 0=S(-),
second bit is longitude sign 1=E(+), 0=W(-),
third bit is longitude over 100 degree, 1=(+-100 degree)
- vlad_vy
-
- Offline
- Posts: 3333
- vlad_vy
-
- Offline
- Posts: 3333
vlad_vy wrote: Draft version of telemetry parser
1) I cann't calculate date/time from UTC time
Spektrum UTC time is simple time in decimal format HH:MM:SS.SS
New draft version of telemetry parser, with full GPS code
static void parse_telemetry_packet()
{
if(packet[0] == 0x7f || packet[0] == 0xff) { //TM1000 or 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] = CLOCK_getms();
Telemetry.time[1] = Telemetry.time[0];
} else if (packet[0] == 0x7e || packet[0] == 0xfe) { //TM1000 or TM1100
Telemetry.rpm[0] = ((packet[2] << 8) | packet[3]); //In RPM
if (Telemetry.rpm[0] == 0xffff)
Telemetry.rpm[0] = 0;
Telemetry.volt[0] = ((((s32)packet[4] << 8) | packet[5]) + 5) / 10; //In 1/10 of Volts
Telemetry.temp[0] = packet[7] == 0xff ? 0 : (packet[7] - 32) * 5 / 9; //In degrees-C (16Bit signed integer !!!)
//Telemetry.temp[0] = ((((s16)packet[6] << 8) | packet[7]) - 32) * 5 / 9; //(16Bit signed integer)
//if (Telemetry.temp[0] > 500 || Telemetry.temp[0] < -100)
// Telemetry.temp[0] = 0;
Telemetry.time[0] = CLOCK_getms();
Telemetry.time[1] = Telemetry.time[0];
} else if (packet[0] == 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] = CLOCK_getms();
} else if (packet[0] == 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] + 5); //In mAh
//Telemetry.pwb.capacity2 = (((s32)packet[8] << 8) | packet[9] + 5); //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] = CLOCK_getms();
} else if (packet[0] == 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] = CLOCK_getms();
} else if (packet[0] == 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] = CLOCK_getms();
} else if (packet[0] == 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] = CLOCK_getms();
} else if (packet[0] == 0x15) { //JetCat sensor
} else if (packet[0] == 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] = CLOCK_getms();
} else if (packet[0] == 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] = CLOCK_getms();
}
}Data type = 0x16 GPS Sensor
0[00] 22(0x16)
1[01] 00
2[02] Altitude LSB (Decimal) //In 0.1m
3[03] Altitude MSB (Decimal)
4[04] 1/100th of a degree second latitude (Decimal) (DD MM.SSSS)
5[05] degree seconds latitude (Decimal)
6[06] degree minutes latitude (Decimal)
7[07] degrees latitude (Decimal)
8[08] 1/100th of a degree second longitude (Decimal) (DD MM.SSSS)
9[09] degree seconds longitude (Decimal)
10[0A] degree minutes longitude (Decimal)
11[0B] degrees longitude (Decimal)
12[0C] Heading LSB (Decimal) Divide by 10 for Degrees
13[0D] Heading MSB (Decimal)
14[0E] Unknown
15[0F] First bit for latitude: 1=N(+), 0=S(-);
Second bit for longitude: 1=E(+), 0=W(-);
Third bit for longitude over 100 degree: 1=+-100 degrees
Data type = 0x17 GPS Sensor
0[00] 23(0x17)
1[01] 00
2[02] Speed LSB (Decimal) Divide by 10 for Knots. Multiply by 0.185 for Kph and 0.115 for Mph
3[03] Speed MSB (Decimal)
4[04] UTC Time LSB (Decimal) 1/100th sec. (HH:MM:SS.SS)
5[05] UTC Time (Decimal) = SS
6[06] UTC Time (Decimal) = MM
7[07] UTC Time MSB (Decimal) = HH
8[08] Number of Sats (Decimal)
9[09] 00
10[0A]-15[0F] Unused (But contains Data left in buffer)
- vlad_vy
-
- Offline
- Posts: 3333
RW9UAO wrote: too much "if", use switch/case =)
static void parse_telemetry_packet()
{
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] = CLOCK_getms();
Telemetry.time[1] = Telemetry.time[0];
break;
case 0x7e: //TM1000
case 0xfe: //TM1100
Telemetry.rpm[0] = ((packet[2] << 8) | packet[3]); //In RPM
if (Telemetry.rpm[0] == 0xffff)
Telemetry.rpm[0] = 0;
Telemetry.volt[0] = ((((s32)packet[4] << 8) | packet[5]) + 5) / 10; //In 1/10 of Volts
Telemetry.temp[0] = packet[7] == 0xff ? 0 : (packet[7] - 32) * 5 / 9; //In degrees-C (16Bit signed integer !!!)
//Telemetry.temp[0] = ((((s16)packet[6] << 8) | packet[7]) - 32) * 5 / 9; //(16Bit signed integer)
//if (Telemetry.temp[0] > 500 || Telemetry.temp[0] < -100)
// Telemetry.temp[0] = 0;
Telemetry.time[0] = CLOCK_getms();
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] = CLOCK_getms();
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] + 5); //In mAh
//Telemetry.pwb.capacity2 = (((s32)packet[8] << 8) | packet[9] + 5); //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] = CLOCK_getms();
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] = CLOCK_getms();
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] = CLOCK_getms();
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] = CLOCK_getms();
break;
case 0x15: //JetCat sensor
//No data yet
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] = CLOCK_getms();
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] = CLOCK_getms();
break;
}
}- vlad_vy
-
- Offline
- Posts: 3333
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]; //In RPM
//by default number_of_poles = 2, gear_ratio = 1.00The most common equation will be:
Telemetry.rpm[0] = 120000000 / number_of_poles(2, 4, ... 32) / gear_ratio(0.01 - 30.99) / Telemetry.rpm[0]; //In RPM
By default number_of_poles equal to 2, gear_ratio = 1.00
New draft version of telemetry parser, with corrected RPM calculation
static void parse_telemetry_packet()
{
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] = CLOCK_getms();
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[7] == 0xff ? 0 : (packet[7] - 32) * 5 / 9; //In degrees-C (16Bit signed integer !!!)
//Telemetry.temp[0] = ((((s16)packet[6] << 8) | packet[7]) - 32) * 5 / 9; //(16Bit signed integer)
//if (Telemetry.temp[0] > 500 || Telemetry.temp[0] < -100)
// Telemetry.temp[0] = 0;
Telemetry.time[0] = CLOCK_getms();
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] = CLOCK_getms();
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] + 5); //In mAh
//Telemetry.pwb.capacity2 = (((s32)packet[8] << 8) | packet[9] + 5); //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] = CLOCK_getms();
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] = CLOCK_getms();
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] = CLOCK_getms();
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] = CLOCK_getms();
break;
case 0x15: //JetCat sensor
//No data yet
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] = CLOCK_getms();
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] = CLOCK_getms();
break;
}
}- PhracturedBlue
-
Topic Author
- Offline
- Posts: 4403
- PhracturedBlue
-
Topic Author
- Offline
- Posts: 4403
-
Home
-
Forum
-
Development
-
Protocol Development
- DSM Telemetry support