What data type is a latitude and longitude?

Hi all!
I need a variable to hold a latitude or a longitude. Anyone know one that would work? GPS coordinates have lots of values after the decimal point to get very accurate location data, so I don't know what to use. Anyone, any ideas?
Thanks!

I assume you're using a GPS library? Which one? Did you look at its source code to see what datatypes the functions return?

What processor/board are you using? Different ones support different floating point precision (thus number of decimals...). There are not enough digits in the AVR implementation to fully represent a GPS coordinate so some libraries use fixed point long integers instead.

gfvalvo:
I assume you’re using a GPS library? Which one?

Yes, TinyGPS++.

gfvalvo:
Did you look at its source code to see what datatypes the functions return?

No, I didn’t think of that. Thanks for the suggestion. I’ll take a look.

aarg:
What processor/board are you using?

I’m using the D1-Mini. A ESP8266 breakout board.

I'm still having issues. The TinyGPS++ library, uses float, but I tried that and it doesn't seem to be working. Lets say I have a value of 45.19403824. If I specify it as float, it only shows 45.19 on the serial monitor. Are the rest of the numbers there? But just not being displayed? I tried multiplying the latitude/longitude by 100000000, so I end up with 4519403824.00 instead. But that didn't work either. Is it how I'm using the data? I'm trying to send the lat/long via LoRa with the LoRa library found here: LoRa - Arduino Referencehttps://www.arduino.cc › reference › libraries › lora
Could I send the lat/long as String?
I'm just confused. Any help?
Thanks.

If I specify it as float, it only shows 45.19 on the serial monitor.

And when you specify that you want to print more places…?

If I specify it as float, it only shows 45.19 on the serial monitor.

Serial.print(aFloat);

defaults to 2 decimal places but they are all there

Try

Serial.print(aFloat, 6);

and spot the difference

When in doubt, consult the reference Serial.print() - Arduino Reference

Thanks @UKHeliBob. That’s exactly what I was asking. Thanks for the answer! Do you know if sending the data with LoRa is messing up the large numbers?

I just found this in the LoRa library:
virtual size_t write(uint8_t byte);
virtual size_t write(const uint8_t *buffer, size_t size);

I have been using the top one, which only transmits a byte (0 - 255). So if I use the bottom one, it should work? How would I use it? Example?
Thanks.

Whatever you posted it is unreadable due to the HTML tags.

Please try again

Fixed it.
Can a float be negative?

kgray9:
Fixed it.
Can a float be negative?

How difficult is it to test?

I'm working on the test setup right now. I looked here: https://forum.arduino.cc/index.php?topic=623739.0 and this is what I figured out:
LoRa.write((uint8_t *)(&Latitude), sizeof(Latitude));

Test setup is complete. Still not working. I used the function in my previous post and the receiver side is reading 163.00 as the latitude. The sender is saying the latitude is 43.42******. Same way with the longitude, course, and speed. They're all floats that aren't being read correctly on the receiver side.

Complete code would probably be helpful at this point. Both TX and RX side.

Transmitter:

#include <SPI.h>
#include <LoRa.h>
#include <TinyGPS++.h>
#include <SoftwareSerial.h>

#define SS 5
#define rst 0
#define dio0 4

static const int RXPin = D4, TXPin = D8;
static const uint32_t GPSBaud = 9600;
int counter = 0;

TinyGPSPlus gps;
SoftwareSerial ss(RXPin, TXPin);

byte msgCount = 0;
float Latitude;
float Longitude;
float Speed;
float Course;
byte localAddress = 0xBB;
byte destination = 0xFF;

void setup() {
  Serial.begin(115200);
  ss.begin(GPSBaud);
  Serial.println("LoRa Sender");
  LoRa.setPins(SS, rst, dio0);  
  if (!LoRa.begin(433E6)) {//915e6
    Serial.println("Starting LoRa failed!");
    while (1);
  }
  LoRa.setTxPower(14);
  Serial.println("LoRa Initializing OK!");
}

void loop() {
  while (ss.available() > 0)
    gps.encode(ss.read());
    
  if (gps.location.isUpdated())
  {
    Serial.print("Sending packet: ");
    Serial.println(msgCount);
    Latitude = gps.location.lat();
    Longitude = gps.location.lng();
    Course = gps.course.deg();
    Speed = gps.speed.mph();
    Serial.print("Latitude: ");
    Serial.println(Latitude);
    Serial.print("Longitude: ");
    Serial.println(Longitude);
    
    String outgoing = String(Latitude) + String(Longitude) + String(Course) + String(Speed);
    LoRa.beginPacket();
    LoRa.write(destination);
    LoRa.write(localAddress);
    LoRa.write(msgCount);
    LoRa.write(outgoing.length());
    LoRa.write((uint8_t *)(&Latitude), sizeof(Latitude));
    LoRa.write((uint8_t *)(&Longitude), sizeof(Longitude));
    LoRa.write((uint8_t *)(&Course), sizeof(Course));
    LoRa.write((uint8_t *)(&Speed), sizeof(Speed));
    LoRa.endPacket();
    msgCount++;
    delay(2000);
  }
}

Receiver:

#define BLYNK_PRINT Serial

#include <SPI.h>
#include <LoRa.h>
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <BlynkSimpleEsp8266.h>

const char* ssid = "********************";
const char* password = "***********";
const char* auth = "****************************";

#define ss 5
#define rst 0
#define dio0 4

byte localAddress = 0xFF;
int recipient;
String incoming;
byte sender;
byte incomingMsgId;
byte incomingLength;
float Latitude;
float Longitude;
float Course;
float Speed;
float latitude;
float longitude;
int led;
BLYNK_WRITE(V0){
  led = param.asInt();
}

BLYNK_WRITE(V1){
  GpsParam gps(param);
  if ( Latitude != 0 && Longitude != 0){
    calcDist(gps.getLat(), gps.getLon(), Latitude, Longitude);
  }
  else {
    digitalWrite(V7, 7777);
  }
}

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("Connection Failed! Rebooting...");
    delay(5000);
    ESP.restart();
  }
  OTAStart();
  Blynk.config(auth);
  Serial.println("LoRa Receiver");
  LoRa.setPins(ss, rst, dio0);  
  if (!LoRa.begin(433E6)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
}

void loop() {
  ArduinoOTA.handle();
  int packetSize = LoRa.parsePacket();
  if (packetSize != 0){// return;
    recipient = LoRa.read();
    sender = LoRa.read();
    incomingMsgId = LoRa.read();
    incomingLength = LoRa.read();
    Latitude = LoRa.read();
    Longitude = LoRa.read();
    Course = LoRa.read();
    Speed = LoRa.read();
    
    Blynk.virtualWrite(V2, Speed);
    Blynk.virtualWrite(V3, Course);
    Blynk.virtualWrite(V10, LoRa.packetRssi());
    Blynk.virtualWrite(V21, LoRa.packetSnr());
    Blynk.virtualWrite(V22, LoRa.packetFrequencyError());
    Blynk.virtualWrite(V11, 1, Latitude, Longitude, "Skier");
    Blynk.run();
    
    incoming = String(Latitude) + String(Longitude) + String(Course) + String(Speed);
    //if (incomingLength != incoming.length()) {
    //  Serial.println("error: message length does not match length");
    //  return;
    //}
    if (recipient != localAddress) {
    Serial.println("This message is not for me.");
    return;
    }
    Serial.println("********************************************");
    Serial.println("Received from: 0x" + String(sender, HEX));
    Serial.println("Sent to: 0x" + String(recipient, HEX));
    Serial.println("Message ID: " + String(incomingMsgId));
    Serial.println("Message length: " + String(incomingLength));
    Serial.println("Latitude: " + String(Latitude));
    Serial.println("Longitude: " + String(Longitude));
    Serial.println("Course: " + String(Course));
    Serial.println("Speed: " + String(Speed));
    Serial.println("RSSI: " + String(LoRa.packetRssi()));
    Serial.println("Snr: " + String(LoRa.packetSnr()));
    Serial.println("");
    delay(500);
  }
}

void OTAStart(){
  // Port defaults to 8266
   ArduinoOTA.setPort(8266);
  // Hostname defaults to esp8266-[ChipID]
   ArduinoOTA.setHostname("SkiESP");
  // No authentication by default
   ArduinoOTA.setPassword((const char *)"skiing");

  ArduinoOTA.onStart([]() {
    Serial.println("Start");
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
    else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
    else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
    else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
    else if (error == OTA_END_ERROR) Serial.println("End Failed");
  });
  ArduinoOTA.begin();
  Serial.println("Ready");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}

float calcDist(float CurrentLatitude, float CurrentLongitude, float SavedLatitude, float SavedLongitude)
{
// HaverSine version
    const float Deg2Rad = 0.01745329252;               // (PI/180)  0.017453293, 0.0174532925
    //const double EarthRadius = 6372.795;              //6372.7976 In Kilo meters, will scale to other values
    const float EarthRadius = 20908120.1;              // In feet  20908128.6
    float DeltaLatitude, DeltaLongitude, a, Distance;

    // degrees to radians
    CurrentLatitude = (CurrentLatitude + 180) * Deg2Rad;     // Remove negative offset (0-360), convert to RADS
    CurrentLongitude = (CurrentLongitude + 180) * Deg2Rad;
    SavedLatitude = (SavedLatitude + 180) * Deg2Rad;
    SavedLongitude = (SavedLongitude + 180) * Deg2Rad;

    DeltaLatitude = SavedLatitude - CurrentLatitude;
    DeltaLongitude = SavedLongitude - CurrentLongitude;

    a =(sin(DeltaLatitude/2) * sin(DeltaLatitude/2)) + cos(CurrentLatitude) * cos(SavedLatitude) * (sin(DeltaLongitude/2) * sin(DeltaLongitude/2));
    Distance = EarthRadius * (2 * atan2(sqrt(a),sqrt(1-a)));
    Blynk.virtualWrite(V7, Distance);
    return(Distance);
}

Is your problem simply that you’re not printing enough places of the float values you’re receiving?

I don't think so. Here is the receiver serial monitor:

Received from: 0xbb
Sent to: 0xff
Message ID: 247
Message length: 21
Latitude: 161.00
Longitude: 173.00
Course: 45.00
Speed: 66.00
RSSI: -80
Snr: 9.75

Latitude and longitude is really wrong, I think course is wrong, because I'm not moving, and speed should be very close to 0.

LoRa.write(outgoing.length()); Why?

I was using that to make sure I received the whole message on the rx side. The receiver adds up the length of all the received data, and compare it to that number to see if all the data was received correctly.