NeoGPS - convert lat/lon to HEX value

I am using the NeoGPS library with a Quectel L80 GPS module.
The following code gets the fix with no problem.

  while (gps.available( gpsSerial )) {
    gps_fix fix = gps.read(); // save the latest

    Serial.print("Latitude:");
    Serial.println( fix.latitude(), 6);
    Serial.print("Latitude String:");
    String latTx = (String(fix.latitudeL()));
    latTx = latTx.substring(1, 9);
    Serial.println(latTx);

this works great and the Log is:

Latitude:-25.856170
Latitude String:25856170

I must now convert the value in the "Latitude String" to HEX in order to send via Sigfox.
So, "25856170" must be "018A88AA"

I have been banging my head and tried numerous examples from Granny Google, but all in vain.
Can anyone please point me in the right direction?

char buffer[9];
sprintf(buffer, "%8LX", fix.latitudeL());

My best guess is:

  char buffer[9];
  unsigned long LatL = fix.latitudeL();
  if (LatL < 0)
    LatL = -LatL; 
  sprintf(buffer, "%08lx", LatL);
  Serial.println(buffer);

This returns:

 Latitude:-25.856647
Latitude String:25856646
 Lat HEX: f09696bd

Where "f09696bd" is decimal value is 4036400829 and not 25856646

With:

    char buffer[9];
    unsigned long LatL = fix.latitudeL();
    if (LatL < 0)
      LatL = -LatL;
    sprintf(buffer, "%08lx", LatL);
    Serial.print("Lat HEX: ");
    Serial.println(buffer);

I get the same result:

Latitude:-25.856864
Latitude String:25856863
Lat HEX: f0968e47

Where "f0968e47" is decimal value 4036398663 and not 25856863

I don't believe so. The "X" I used in the format string would return a hex representation where the letters "A"-"F" are upper-case, not lower-case as your result shows. So whatever code produced that result, I don't think it's the code I suggested.

The format string should have been "%08lX" to produce leading zeroes, I forgot the "0", and the "l" should be lower case and the "X" upper case.

@johnwasser spotted that sprintf() won't print negative hex numbers, so the code he suggested to check for negative values is important.

Yes, I saw that.
With both "I" and "X" in uppercase, I get nothing.

Nothing at all? Before, you were getting a value, but it was not the correct value. Now it prints nothing?

Please post the latest complete code.

With the following code, I change the value to a string and use substring to parse "25856175" from the original "( fix.latitude(), 6)".
I am not concerned about negative values as I take care of this on the backend.

    Serial.print("Latitude:");
    Serial.println( fix.latitude(), 6);
    Serial.print("Latitude String:");
    String latTx = (String(fix.latitudeL()));
    latTx = latTx.substring(1, 9);
    Serial.println(latTx);

I then need to change the resultant String "25856175" to a HEX string of "018A88AF".

Running this code:

    char buffer[9];
    sprintf(buffer, "%08lX", fix.latitudeL());
    Serial.print("Lat HEX: ");
    Serial.println(buffer);

I get:

Lat HEX: F096ABB4

Where "F096ABB4" give me a decimal value of "4036406196".
This should be "018A886E" which is decimal value of "25856110"

Bearing in mind I am using the NeoGps library.
Prior to this I parsed the GPS data myself with:

          // Get Latitude
          char gpsLat[10];
          //char latHex[9];
          strncpy(gpsLat, gpsResponse + 17, 4);
          strncpy(&gpsLat[4], gpsResponse + 22, 4);
          gpsLat[8] = '\0';

          sprintf(latHex, "%08lX", atol(gpsLat));
          Serial.print("Lat HEX: ");
          Serial.println(latHex);
          delay(50);

and this worked fine

Where "F096ABB4" give me a decimal value of "4036406196".
This should be "018A886E" which is decimal value of "25856110"

This is the correct output. You didn't put in 25856110, you put in -25856110 which is F096ABB4 in hex.

Yes, I see that - thanks
If I run:

    char buffer[9];
    sprintf(buffer, "%08lX", 25856110);
    Serial.print("Lat HEX: ");
    Serial.println(buffer);

Output is:

Lat HEX: 018A886E

This is correct.
Do I need to change the String "25856110" to a Long or int?

Many thanks to all for your input.
This works:

    Serial.print("Latitude:");
    Serial.println( fix.latitude(), 6);
    Serial.print("Latitude String:");
    String latTx = (String(fix.latitudeL()));
    latTx = latTx.substring(1, 9);
    Serial.println(latTx);
    long myLat = latTx.toInt();
    Serial.print("myLat: ");
    Serial.println(myLat);

    char latHex[9];
    sprintf(latHex, "%08lX", myLat);
    Serial.print("Lat HEX: ");
    Serial.println(latHex);

Output is:

Latitude:-25.856161
Latitude String:25856161
myLat: 25856161
Lat HEX: 018A88A1

Which is correct.

1 Like

Just looking back through the thread. I think this code which you used to remove the negative number didn't work:

unsigned long LatL = fix.latitudeL();
if (LatL < 0)
LatL = -LatL;

You've stored the value in an unsigned long, which can't hold a negative number so when you check if LatL is less than zero it will always be false - an unsigned long can't be less than zero.

I think if you go back to this code but store it as a long then use the same method to convert negative number to positive it should work?

Oops! I should have used 'long', not 'unsigned long':
long LatL = fix.latitudeL();

Because I used 'unsigned' the 'if (LatL < 0)' test fails and the negative number is not turned positive.

Simplifying:

    Serial.print("Latitude:");
    Serial.println( fix.latitude(), 6);

    long myLat = abs(fix.latitudeL());
    Serial.print("myLat: ");
    Serial.println(myLat);

    char latHex[9];
    sprintf(latHex, "%08lX", myLat);
    Serial.print("Lat HEX: ");
    Serial.println(latHex);

Many thanks - all sorted and have added above Simplifying code.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.