BrushlessPower / SBUS2-Telemetry

Arduino Library for SBUS and SBUS2 with Futaba Telemetry
GNU General Public License v3.0
86 stars 24 forks source link

GPS SBS-02G #42

Open magnum3131 opened 2 years ago

magnum3131 commented 2 years ago

Hi,

I'm working on the code to adding the GPS sensor SBS-02G. For the moment i manage to send the altitude, variometer and the pressure. But i'm stuck by the latitude and the longitude.

The latitude is coded on 26 bit wich can have the maximum value 67 108 864, insuffisant for 90°. According to my test the value of the bit is not always a power of 2. Here the detail of the 26 bit : 55554432, 27577216, 13588608, 6594304, 3297152, 1448576, 524288, 262144, 131072, 65536, 32768, 16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1

Same thing with the longitude but this time with 27 bit : 111508864, 55554432, 27577216, 13588608, 6594304, 3297152, 1448576, 524288, 262144, 131072, 65536, 32768, 16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2,1

I tried to make a fonction to convert value with this bit but the radio display different value. Depending on the case i have the following difference between the send value and the display. 2400000, 2000000, 1600000, 1200000, 800000, 400000, 0

The difference depend of the coordonate

Have you ever seen this king of compression to transmit high value with less bit ?

Thanks

ericlangel commented 2 years ago

Did you had a look the Site of Alex K.? https://sites.google.com/site/sbus2diy/home/sbus2protocol-part2/sbus2protocol-part3

grafik

The SBS-02G could be the same Format as SBS-01G

Please give us more informations: how much slots? where is altitude, vario and preassure located? did you have a SBS-02G for decoding?

magnum3131 commented 2 years ago

Hi Eric,

Yes i have a SBS-02G for testing, i use your library to view the data in each slot. The SBS use 8 slot Slot 0 = Date not display on radio, i didn't work on it yet Slot 1 & 2 = 26 bit for latitude + 1 bit for pole(0 North, 1 South) + 4bit of longitude + 1bit i don't know Slot 3 & 4 = 23bit for longitude (27 total with slot 1&2) + 1 bit for pole + 8 bit of speed Slot 5 & 6 & 7 = Mix for Speed, Pressure, Alti and Vario

I already done the code for the pressure, alti & vario and it's working on 18MZ

I'm not to my home this evening, i don't have access to my detail note with the detail of each bit

Thanks

magnum3131 commented 2 years ago

Hi,

Here the detail of slot

Slot 1 Latitude 16384 8192 4096 2048 1024 512 256 128 | 64 32 16 8 4 2 1 ?

Slot 2 Latitude 8 4 2 1 Pole 55554432 27577216 13588608 | 6594304 3297152 1448576 524288 262144 131072 65536 32768 Longitude

Slot 3 Longitude 524288 262144 131072 65536 32768 16384 8192 4096 | 2048 1024 512 256 128 64 32 16

Slot 4 Longitude 128 64 32 16 8 4 2 1 | Pole 111508864 55554432 27577216 13588608 6594304 3297152 1448576 Speed

Slot 5 Speed 1024 512 256 128 64 32 16 8 | 4 2 1 ? ? ? 256 ? Pressure

Slot 6 Pressure 4096 2048 1024 512 256 128 64 32 | 16 8 4 2 1 8192 4096 2048 Altitude

Slot 7 Altitude ? 2048 1024 512 256 128 64 32 | 16 8 4 2 1 32768 16384 8192 Vario

ericlangel commented 2 years ago

it's hard to understand your coding

try to make it readable in a Table

Slot Number High Byte Low Byte Comment
Slot 0 Time/Date Time/Date no work done
Slot 1 LAT Bit 8-15 ? LAT Bit 0-7 Slot 1 should contain a Date Time Bit in High Byte
Slot 2 LAT Bit 16-23? LON Bit 0-4 ; Pole ; LAT Bit 24 -26 not sure
Slot 3
Slot 4
Slot 5
Slot 6
Slot 7

could you try it this way?

and it would be good to have a Log of the Sensor Which Bytes are in the Slots? And what is displayed to the 18MZ?

The SBS-01G and SBS-02G are strange. But maybe we could get it decoded together

magnum3131 commented 2 years ago

Hi Eric,

I'll do that ASAP

tschneider1 commented 2 years ago

I'm willing to help as well. I am also attempting to decode the data off an SBS-02G. I have the GPS module attached to an r7008sb which is talking to a T14SG. Happy to post some logs and write some code.

UTC is pretty straight forward. There was a comment on Jerry Chapman's blog (http://sbustelemetrysensors.blogspot.com) that described it clearly. Here is what that looks like:

static const uint8_t pSrc[24] = {0x13,0x53,0x1A, 0x93,0x71,0xD0, 0x53,0xDE,0xE2, 0xD3,0xAF,0xD7, 0x33,0xBF,0x00, 0xB3,0x2E,0x30, 0x73,0xBC,0xBB, 0xF3,0xE2,0xAE};
uint32_t seconds = pSrc[1] | (pSrc[2]<<8) | ((pSrc[4]&0x01)<<16);
uint32_t hours = 0.5 + floor(float(seconds) / 3600.0);
seconds -= 3600 * hours;
uint32_t minutes = 0.5 + floor(float(seconds)/60.0);
seconds %= 60;
printf("utc time: %02d:%02d:%02d\n", hours, minutes, seconds);

utc time: 20:04:35

I've had trouble parsing out his lat/lon though. He says his location is N 41:07.8440, W110:34.3932. Which should be buried in that array; however, I cannot seem to pull it out using Alex's table.

magnum3131 commented 2 years ago

Hi,

Here the detail of SBS02G slot <html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40">

Slot Number | High Byte |   |   |   |   |   |   |   | Low Byte |   |   |   |   |   |   |   -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | --   | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 2 | 2 | 1 0 | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? 1 | LAT 16384 | LAT 8192 | LAT 4096 | LAT 2048 | LAT 1024 | LAT 512 | LAT 256 | LAT 128 | LAT 64 | LAT 32 | LAT 16 | LAT 8 | LAT 4 | LAT 2 | LAT 1 | ? 2 | LON 8 | LON 4 | LON 2 | LON 1 | LAT Pôle 0 = N 1 = S | LAT 55554432 | LAT 27577216 | LAT 13588608 | LAT 6594304 | LAT 3297152 | LAT 1448576 | LAT 524288 | LAT 262144 | LAT  131072 | LAT 65536 | LAT  32768 3 | LON 524288 | LON 262144 | LON  131072 | LON 65536 | LON  32768 | LON 16384 | LON 8192 | LON 4096 | LON 2048 | LON 1024 | LON 512 | LON 256 | LON 128 | LON 64 | LON 32 | LON 16 4 | SPEED 128 | SPEED 64 | SPEED 32 | SPEED 16 | SPEED 8 | SPEED 4 | SPEED 2 | SPEED 1 | LON Pôle 0 = E 1 = W | LON 111508864 | LON 55554432 | LON 27577216 | LON 13588608 | LON 6594304 | LON 3297152 | LON 1448576 5 | Pressure 1024 | Pressure 512 | Pressure 256 | Pressure 128 | Pressure 64 | Pressure 32 | Pressure 16 | Pressure 8 | Pressure 4 | Pressure 2 | Pressure 1 | ? | GPS SIGNAL | GPS SIGNAL | Set 1 For Speed | SPEED 256 6 | Alti 4096 | Alti 2048 | Alti 1024 | Alti 512 | Alti 256 | Alti 128 | Alti 64 | Alti 32 | Alti 16 | Alti 8 | Alti 4 | Alti 2 | Alti 1 | Pressure 8192 | Pressure 4096 | Pressure 2048 7 | ? | Vario 2048 | Vario 1024 | Vario 512 | Vario 256 | Vario 128 | Vario 64 | Vario 32 | Vario 16 | Vario 8 | Vario 4 | Vario 2 | Vario 1 | Pressure 32768 | Pressure 16384 | Pressure 8192

Here a begining of function that work with Speed, Vario, altitude, Pressure, GPS signal (Full 3 bar) I put slot latitude and longitude slot with generic value that display on T18 Latitude = N 70°05.3425 Longitude = E 1°27.6435

Slot 9 bytes[1] = 0x62; bytes[2] = 0x5E; Slot 10 bytes[1] = 0x03; bytes[2] = 0x35; Slot 11 bytes[1] = 0xF9; bytes[2] = 0xD5;

Here the code SBUS2.h void send_SBS02G(uint8_t port, int16_t pressure, int16_t alti, int16_t vario, int16_t speed, int32_t latitude, int32_t longitude);

SBUS2.cpp `void send_SBS02G(uint8_t port, int16_t pressure, int16_t alti, int16_t vario, int16_t speed, int32_t latitude, int32_t longitude){ int16_t value = 0;

uint8_t bytes[SBUS2_TEL_DATA_SIZE] = {0x03, 0x40, 0x00 }; uint8_t bytes9[SBUS2_TEL_DATA_SIZE] = {0x03, 0x40, 0x00 }; uint8_t bytes10[SBUS2_TEL_DATA_SIZE] = {0x03, 0x40, 0x00 };

bytes[1] = 0xFF; bytes[2] = 0xFF; //bytes[1] = 0x0B; //bytes[2] = 0x9A; SBUS2_transmit_telemetry_data( port , bytes);

bytes9[1] = 0x62; bytes9[2] = 0x5E; bytes10[1] = 0x03; bytes10[2] = 0x35;

SBUS2_transmit_telemetry_data( port+1 , bytes9);
SBUS2_transmit_telemetry_data( port+2 , bytes10);

bytes[1] = 0xF9; bytes[2] = 0xD5; SBUS2_transmit_telemetry_data( port+3 , bytes);

bytes[1] = 0x00; bytes[2] = speed; SBUS2_transmit_telemetry_data( port+4 , bytes);

//PRESSURE value = pressure; speed = speed >> 8; //speed = speed << 1; bytes[1] = value << 5;// >> 8; bytes[1] = bytes[1] | speed; bytes[1] = bytes[1] | 0x0E; //signal GPS
bytes[2] = pressure >> 3; SBUS2_transmit_telemetry_data( port+5 , bytes);

pressure = pressure >> 8; pressure = pressure << 2; pressure = pressure & 0xE0; pressure = pressure >> 5;

//ALTITUDE alti = (alti + 700); value = alti; bytes[1] = value << 3; bytes[1] = bytes[1] | pressure; bytes[2] = alti >> 5; SBUS2_transmit_telemetry_data( port+6 , bytes); alti = alti >> 13;

//VARIO value = (vario + 1500); bytes[1] = value << 3; bytes[1] = bytes[1] | alti; value = (vario + 1500); bytes[2] = value >> 5; bytes[2] = bytes[2] | 0x80; SBUS2_transmit_telemetry_data( port+7 , bytes); }`

Exemple of call send_SBS02G(8, (int16_t)10084,(int16_t)100,(int16_t)25,(int16_t)300,(int32_t)(0),(int32_t)(0));

Julien

tschneider1 commented 2 years ago

Hi Julien,

Can you confirm that higher MSB's of latitude and longitude are non powers of two? That seems strange.

For instance:

Bit 4 of slot 2 is a power of two (524288); however, Bit 5 of slot 2 is not (1448576)

Tom

ericlangel commented 2 years ago

Thats something i dont understand in juliens table and text's

what are these Numbers?

normally we need a table like this

Slot x Bit 0 = LAT Bit 6 Slot x Bit 1 = LAT Bit 7 and so on

a number like 262144 ....is 2^18 -> so does that mean its Bit 18?

magnum3131 commented 2 years ago

Hi,

On the table i gave the name and number represent the field and the value display by the radio.

For example: Slot 2 Bit 16 display a Longitude E 0°00.0008 on the radio

Tom, yes Higher MSB on latitude and longitude are not a power of 2

Latitude on 26 bit : 55554432, 27577216, 13588608, 6594304, 3297152, 1448576, 524288, 262144, 131072, 65536, 32768, 16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1

Longitude on 27 bit : 111508864, 55554432, 27577216, 13588608, 6594304, 3297152, 1448576, 524288, 262144, 131072, 65536, 32768, 16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2,1

I tried to make a fonction to convert value with this bit but the radio display different value. Depending on the case i have the following difference between the send value and the display. 2400000, 2000000, 1600000, 1200000, 800000, 400000, 0

Julien

tschneider1 commented 2 years ago

Hi Julien,

I think I am starting to understand. Are you fuzzing the transceiver and monitoring the output of the display? You're saying you're sending all zeros except for slot 2 bit 16 and the longitude displays E 0°00.0008?

Tom

magnum3131 commented 2 years ago

Hi Tom,Yes this is how i decode the trameJulienLe 18 mars 2022 14:20, tschneider1 @.***> a écrit :

Hi Julien,

I think I am starting to understand. Are you fuzzing the transceiver and monitoring the output of the display? You're saying you're sending all zeros except for slot 2 bit 16 and the longitude displays E 0°00.0008?

Tom

—Reply to this email directly, view it on GitHub, or unsubscribe.Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you authored the thread.Message ID: @.***>

tschneider1 commented 2 years ago

Got it, I suspect you are rolling the scaling value into the table.

Can you do a little fuzzing and let us know what the display says? Let's start by trying to figure out the latitude...

Tom

ericlangel commented 2 years ago

maybe this helps:

// coordinates Berlin TV Tower = Degree Minutes = Decimal Degrees = Degree Minutes Seconds int32_t latitude = 52312499; // = N 52° 31.2499 = N 52.520833 = N 52° 31' 14.9988" int32_t longitude = 13245658; // = E 13° 24.5658 = E 13.409430 = E 13° 24' 33.9480"

This coordinates are exactly the same position, but they are expressed in different formats

The other decoded gps sensor uses degreeminutes as input type, but displays as degree minutes seconds

magnum3131 commented 2 years ago

Hi,

Can you send all zeros except for a one in slot 2 bit 11 and tell us what the display reads? => N 55°55.4432 Can you send all zeros except for a one in slot 2 bit 10 and tell us what the display reads? => N 27°57.7216 Can you send all zeros except for a one in slot 2 bit 5 and tell us what the display reads? => N 0°52.4288

Julien

tschneider1 commented 2 years ago

It looks like the data is stored in decimal degree and the scale is 0.000001666667

N 55°55.4432 = 55.924050 (bit 26, 33554432) N 27°57.7216 = 27.577216 (bit 25, 16777216) N 13°58.8608 = 13.981 (bit 24, 8388608) N 6°59.4304 = 6.9905 (bit 23, 4194304) N 3°29.7152 = 3.49525 (bit 22, 2097152) N 1°44.8576 = 1.747617 (bit 21, 1048576) N 0°52.4288 = 0.8738 (bit 20, 524288)

bit 26 asserted (33554432 0.000001666667 = 55.924050) bit 25 asserted (16777216 0.000001666667 = 27.577216) .... bit 20 asserted ( 524288 * 0.000001666667 = 0.873813508)

I'm off for the rest of the weekend. I'll post on Monday with pseudo code for converting from SBUS to latitude.

tschneider1 commented 2 years ago

Hi Julien,

I'm back at my computer, do you mind doing a little more fuzzing for me? I have utc, latitude and longitude figured out:

static const uint8_t pSrc[24] = {0x13,0x53,0x1A, 0x93,0x71,0xD0, 0x53,0xDE,0xE2, 0xD3,0xAF,0xD7, 0x33,0xBF,0x00, 0xB3,0x2E,0x30, 0x73,0xBC,0xBB, 0xF3,0xE2,0xAE};
uint32_t seconds = pSrc[1]|(pSrc[2]<<8)|((pSrc[4]&0x01)<<16);
uint32_t hours = 0.5 + floor(float(seconds) / 3600.0);
seconds -= 3600 * hours;
uint32_t minutes = 0.5 + floor(float(seconds)/60.0);
seconds %= 60;
/* latitude/longitude scaling factor */
static const float latLonScale = 0.0000001/0.06;
/* decode latitude/longitude */
float latitude = latLonScale*(((pSrc[8]&0x07)<<23)|(pSrc[7]<<15)|(pSrc[5]<<7)|(pSrc[4]>>1));
bool isSouth = pSrc[8]&0x08;
float longitude = latLonScale*(((pSrc[13]&0x7f)<<20)| (pSrc[11]<<12) | (pSrc[10]<<4) | (pSrc[8]>>4));
bool isWest = pSrc[13]&0x80;
printf("utc time: %02d:%02d:%02d; lat/long: (%.07f%s, %.07f%s)\n", hours, minutes, seconds, latitude, isSouth?"S":"N", longitude, isWest?"W":"E");

Now we need decode speed, alititude and vario:

Speed:

Altitude:

Vario:

Tom

magnum3131 commented 2 years ago

Hi Tom,

Thanks a lot for your code, i'll try it asap. For the Speed, altitude, vario and pressure i have already implement it, at the end of this post https://github.com/BrushlessPower/SBUS2-Telemetry/issues/42#issuecomment-1071404064

Julien

tschneider1 commented 2 years ago

Hi Julien,

Are speed, altitude and vario displaying correctly with your code? Jerry mentioned that the scaling factor for altitude is 1/80th of a meter. You're adding 700 to the input value. Which one is correct?

Is there anyway you can fuzz the inputs like we did for latitude? It'd be a nice confirmation that we have all the logic corrrect. After you do that, I can write the _send_SBS02G_ function.

Tom

magnum3131 commented 2 years ago

Hi Tom,Yes for me speed, altitude, pressure and vario work with the code i postedI am off for the rest of the Day, i'll try to do more test tomorowJulienLe 21 mars 2022 15:51, tschneider1 @.***> a écrit : Hi Julien, Are speed, altitude and vario displaying correctly with your code? Jerry mentioned that the scaling factor for altitude is 1/80th of a meter. You're adding 700 to the input value. Which one is correct? Is there anyway you can fuzz the inputs like we did for latitude? It'd be a nice confirmation that we have all the logic corrrect. After you do that, I can write the send_SBS02G function. Tom

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you authored the thread.Message ID: @.***>

tschneider1 commented 2 years ago

Got it. I suspect that the offset of 700 might yield the correct answer for your current altitude; however, it might just be a coincidence.

magnum3131 commented 2 years ago

Hi,

The 700 is for in case you flight under your altitude of start. According the Futaba SBS02 manual the maximum is -700m. The first altitude send is the 0 for the radio, the altitude is calculated with the difference of the 1st altitude and actual

Julien

magnum3131 commented 2 years ago

Hi,

For being sure, if my GPS (Tiny GPS++) give me the decimal value of latitude and longitude. What i have to do in order to convert it for sending via BUS2 ?

Thanks Julien

BrushlessPower commented 2 years ago

For the F1675 GPS Sensor i had made different Input Types for Degree Minutes, Decimal Degrees and Degree Minutes Seconds.

i would do the same for SBS-02G

tschneider1 commented 2 years ago

That's what I was thinking as well. Multiple different function signatures to support the different representations.

Julien, I'll need you to fuzz the altitude if we want to get that right. I suspect that it's not as straight forward as subtracting 700. I've seen notes that it is stored in 1/80th of a meter and I would like to confirm that.

tschneider1 commented 2 years ago

I'm just realizing that this might be difficult to fuzz as the device only gives you a delta from what it thinks it's origin is. You probably have to send a valid lat/lon/alt. Then follow up with same lat/lon with a different altitude.

magnum3131 commented 2 years ago

Hi,

If there is no offset for altitude you can't have negative value for altitude. I use 700 because of Futaba datasheet

[Speed] About 0km/h~500km/h (~311mph) [Altitude] About -700m~+5,500m (-766yard~+6015yard) ---sensor spec [Vario meter] About -150m/s~+150m/s(-336mph~+336mph)

I'll make a video this evening to show the result, In my test there is no ratio for altitude 1 = 1m

For the DMS conversion to degre decimal i don't the same value with these online converter https://www.latlong.net/degrees-minutes-seconds-to-decimal-degrees N 55°55.4432 = 55.924050 (bit 26, 33554432) => 57.14777778

Julien

tschneider1 commented 2 years ago

There are three standard formats for lat/lon:

  1. Degrees, Minutes, Seconds (DDD° MM' SS.S")
  2. Degrees and Decimal Minutes (DDD° MM.MMM')
  3. Decimal Degrees (DDD.DDDDD°)

The format the handset displays is Degrees and Decimal Minutes; however, you're trying to convert from Degrees, Minutes, Seconds to Decimal Degrees.

Try this calculator: https://boulter.com/gps/#N%2055%B055.4432%20E%2013%B0%2024%27%2033.9480

magnum3131 commented 2 years ago

Hi, I remove the offset when i transmit 8191 the radio display 819.1m, according the table this is the max altitude. I have to check because it's seem to be low

Julien

ericlangel commented 2 years ago

just some more or less known facts

The Temp Sensor SBS01 is specified for 125°C or 200°C (depends on version). With the SBUS2 protocol you can transmit 16383°C and this Value is displayed. So i wont belive the Specs of the Sensor.

And for the GPS Sensor F1675 and both Varios the altitude is calculated in the radio handset. when you transmit 3000m from the first SBUS2 Frame -> your Hanset will display 0m when you later transmit 3100m -> your handset will display 100m

When you want to decode it you should send all zero's for the first 20,50,100 frames (no idea, maybe the first frame is enough) and after that you can test the single Bits.

for the 700m from the Spec: i belive this is jus a spec on the barometer chip. that it can't measure less than -700m (or the factor in pressure) if you send 3000m from the very first frame, and send later 1000m (or 0m) it think the handset would Display -2000m (or -3000m), because its just a math funktion. but i never tested it. GPS and altitude are sensors which i never needed

tschneider1 commented 2 years ago

Finally got around to coding this up. The pull request is there. Enjoy!

ericlangel commented 2 years ago

@tschneider1 Thank you for your work. I have merged the PR. I'll try to test the Sensor and close the issue.

@magnum3131 If you test the Sensor please leave a comment

magnum3131 commented 2 years ago

Hi,

Sorry for the answer, i haven't tested the code merged, i'll do a report ASAP

Thanks

Julien