+393398979963 info@openvironment.net

GPS recievers usually output (or can be setup to output) their data in plain text NMEA 0183 sentences and the coordinates are expressed as geographic coordinates, i.e. latitude and longitude. More in depth the format for the latitude is ddmm. mmmm and for the longitude it is dddmm. mmmm where d=degrees and m=minutes. In an other post we will see how to convert these coordinates in decimal degrees. But what if we would like to have the coordinates expressed as projected ones?
Projected coordinates are more “readable” as they are expressed in terms of cartesian coordinates: the y is the N/S coordinate and the x is the W/E coordinate. In simple terms the earth is subdivided in 60 fuses of 6° each (6° x 60 = 360°) that are projected on a cartesian plane (after the pojection the fuses are called zones). The first thing that we have to know is in what zone and band we are: e.g. 32T means that we are in the fuse 32,  band T (I live in Tuscany, see picture below).

The second thing we have to know are the x and y (Easting and Northing) coordinates: these are the distances (expressed in meters in the UTM projection) from the equator for the y coordinate and the distance (plus a false east of 500.000 m in order to avoid negative coordinates) from the central meridiane of the fuse (zone) for the x coordinate.
Now we go back to the first question: why should we use projected coordinates instead of geographic coordinates? For example because most of the trekking maps have a printed UTM grid on it and it is much more easier to find out our position on the map if our handheld GPS is set to output UTM coordinates. The pictures below is clear:

For a more in depth explanation see the MapTools link  where the above pictures were taken from. Also from MapTools a very good video.

Now let’s go back to our code: the first thing I had to do was to find the formulas to pass from geographic coordinates to projected coordinates. Here is a very good explanation. Anyway a did find an Excel file that is downlodable here and did implement the formulas in C using the Arduino IDE.

https://www.legallandconverter.com/p44.html

double polarradius = 6399593.626;
double ei2 = 0.006739497;
double alti;
double lati;
double longi;
double latrad;
double lonrad;
int fuse;
int centmer;
double deltalambda;
double A;
double Xi;
double Eta;
double Ni;
double Zeta;
double An1;  //actually it is A1 but this is reserved for anlalog pin A1
double An2;  //actually it is A2 but this is reserved for anlalog pin A2
double J2;
double J4;
double J6;
double Alfa;
double Beta;
double Gamma;
double Bfi;
double EastX;
double NorthY;
double SouthY;
String band;
String Hemisphere;
String GPSSentence;

void setup() {
  Serial.begin(9600);
  delay(2000);
  Serial.println("Please enter your coordinates in decimal degrees ...");
  Serial.println("use a CSV format with hemisphere (N or S), latitude, longitude. e.g.: N,43.773833,11.294507 ");
}

void loop() {
  //Serial.println("please enter your coordinates in decimal degrees ...");
  if (Serial.available() > 0) {
    GPSSentence = Serial.readStringUntil('\r\n');  //read until newline and carriage return
    GPSSentence.trim();
    //}
    if (GPSSentence.length() > 6) {
      int SentenceLength = GPSSentence.length();
      int comma_n_1 = GPSSentence.indexOf(',');
      int comma_n_2 = GPSSentence.indexOf(',', comma_n_1 + 1);

      Hemisphere = GPSSentence.substring(0, comma_n_1);

      String LAT = GPSSentence.substring(comma_n_1 + 1, comma_n_2);
      lati = LAT.toFloat();

      String LON = GPSSentence.substring(comma_n_2 + 1, SentenceLength);
      longi = LON.toFloat();

      Serial.print("Latitude is: ");
      Serial.println(lati, 5);
      Serial.print("Longitude is: ");
      Serial.println(longi, 5);

      Calculations();

      Serial.print("UTM East (X) is: ");
      Serial.println(EastX, 0);
      if (Hemisphere == "N") {
        Serial.print("UTM North (Y) is: ");
        Serial.println(NorthY, 2);
      } else {
        Serial.print("UTM South (Y) is: ");
        Serial.println(SouthY, 2);
      }
      Serial.print("Fuse and band are: ");
      Serial.print(fuse);
      Serial.println(band);
    }
  }
}