DeviationTX / deviation

Custom firmware for RC Transmitters
http://www.deviationtx.com
GNU General Public License v3.0
247 stars 153 forks source link

(Solution) Hubsan Telemetry - Here is how to read all of it. #994

Open ramiss opened 3 years ago

ramiss commented 3 years ago

Hey Guys,

I don't use deviation, but your code initially pointed me in the right direction, so I want to provide my findings for your use. I am currently writing Arduino nano code to convert Hubsan telemetry to DJI for the DJI HD FPV air unit, and I do believe I have cracked the rest of the Hubsan telemetry protocol. Maybe others had too, but I'll be damned if I could find it. Every other code repo said "to do: voltage working, figure out rest of telemetry".

So here ya go. Took me one week of dreaming about packets. Initial tests show the following works on an H501. Hope someone finds it useful.

static void hubsan_update_telemetry()
{
    if((packet[0]==0xe1 || packet[0]==0xe7) && hubsan_check_integrity()) {        
        Heading = HubsanTelemetry(packet[1], packet[2]); 
        Rotation = HubsanTelemetry(packet[3], packet[4]);
        Pitch = HubsanTelemetry(packet[5], packet[6]);
        Speed = HubsanTelemetryFloat(packet[7], packet[8]);
        Distance = HubsanTelemetryFloat(packet[9], packet[10]);
        Altitude = HubsanTelemetryFloat(packet[11], packet[12]);
        Voltage = (float)(packet[13]/10.0);
    }
}

int HubsanTelemetry(unsigned int FirstByte, unsigned int SecondByte)
{
  int combined;
  if (FirstByte < 128) {
    combined = (FirstByte*255 + SecondByte)/10;
  } else {
    combined = 0-((255-FirstByte)*255 + (255-SecondByte))/10;
  }
  return combined;
}

float HubsanTelemetryFloat(unsigned int FirstByte, unsigned int SecondByte)
{
  float combined;
  if (FirstByte < 128) {
    combined = ((float)FirstByte*255.0 + (float)SecondByte)/10.0;
  } else {
    combined = 0.0-((255.0-(float)FirstByte)*255.0 + (255.0-(float)SecondByte))/10.0;
  }
  return combined;
}

static u8 hubsan_check_integrity() 
{
    int sum = 0;
    for(int i = 0; i < 15; i++)
        sum += packet[i];
    return packet[15] == ((256 - (sum % 256)) & 0xff);
}