I currently have some code which returns GPS co-ordinates in GNSS NEMA format which i have found a function to convert this. The issue i have is my understanding of C is limited and i don’t know how to call this and looking for advice.
I have the following variables correctly populating;
Gga gga = Gga(_gps);
if (gga.parse()) {
utcTime = gga.utcTime;
longitude = gga.longitude;
latitude = gga.latitude;
}
Rmc rmc = Rmc(_gps);
if (rmc.parse()) {
utcTime = rmc.utcTime;
longitude = rmc.longitude;
latitude = rmc.latitude;
}
What i want to do is modify the longitude and latitude values using the following function but i am not sure how i modify my code above to actually call this?
Any help or guidance would be much appreciated
float conv_coords(float in_coords) {
//Initialize the location.
float f = in_coords;
// Get the first two digits by turning f into an integer, then doing an integer divide by 100;
// firsttowdigits should be 77 at this point.
int firsttwodigits = ((int)f)/100; //This assumes that f < 10000.
float nexttwodigits = f - (float)(firsttwodigits*100);
float theFinalAnswer = (float)(firsttwodigits + nexttwodigits/60.0);
return theFinalAnswer;
}
Not sure why you set your three variables twice. The second assignment to each of them will overwrite the previous value - so either Gga or Rmc should be used, not both IMO.
BTW, I already advised in another thread to not write it this way but rather
Rmc rmc(_gps);
for reasons explained in that thread.
However, not exactly sure why you would want to convert the data that way.
Can you explain what you actually want with that? Then we might be able to advise how to do it “better”.
You need to consider that float cannot store any arbitrary number exactly. So even when you calculate the value correctly, you may not actually get that exact result back when you return it.
Also the .longitude and .latitude values you get from that library are of type String so you’d need to convert that first (better into double rather than float).
Hi thanks for the reply, i do plan on fixing those before i finalise things but as it was currently working i was going to come back and change this later.
I think i need to step back as i am missing the north and west indicators.
To work out my values i cam going to need to create a function that will convert them as follows, so for latitude and longitude these will also come along with indicator for N and W which i am currently missing these variables!
The function will take in the variables for each indicator and and latitude value in format of ddmm.mmmmm. Then strip it out as below;
You can either use the sign of that value to select N/E or S/W and multiply by -1 for the latter or you take the abs() of the value and use rmc.northSouthIndicator and rmc.eastWestIndicator from the library object.
Thank you so much - i have also just updated my code with all of your other suggestions and all seems to be working as expected - i really appreciate your help you have given me!
OK i have tried this just for longitude at the moment and ignoring the positive/negative part for now. I’ve added in a new ‘test’ variable just to store the value that is being passed to new function. The value for longitude passed is 5553.8194.
What i am finding is that the value 0 is now being passed…
Could this be due to the positioning of the function? I have added this part in after i initialised my variables at the beginning.
// This #include statement was automatically added by the Particle IDE.
#include <MPU6050.h>
#include "Particle-GPS.h"
//GPS Setup
// ***
// *** Create a Gps instance. The RX an TX pins are connected to
// *** the TX and RX pins on the electron (Serial1).
// ***
Gps _gps(&Serial1);
// ***
// *** Create a timer that fires every 1 ms to capture
// *** incoming serial port data from the GPS.
// ***
Timer _timer(1, onSerialData);
// MPU variables:
MPU6050 accelgyro;
int16_t ax, ay, az;
int16_t gx, gy, gz;
//GPS Variables
String utcTime ="";
String latitude;
String northSouthIndicator ="";
String longitude ="";
String test ="";
String eastWestIndicator ="";
bool ledState = false;
void toggleLed() {
ledState = !ledState;
digitalWrite(ledPin, ledState);
}
int analogvalue; //declaring the integer variable
String data = ""; //Used to send value to the cloud
double decDegFromDMMmm(const char* coord) { //coord as DDDMM.mmmmmm
int iDeg = atol(coord) /100;
int dMin = atof(coord) - 100 * iDeg;
return iDeg + dMin / 60.0;
}
void setup() {
delay(2000);
Wire.begin();
Serial.begin();
_gps.begin(9600);
_timer.start();
//Declare a Particle.variable() for access values in the cloud
Particle.variable("analogvalue", &analogvalue, INT);
// The following line will wait until you connect to the Spark.io using serial and hit enter. This gives
// you enough time to start capturing the data when you are ready instead of just spewing data to the UART.
//
// So, open a serial connection using something like:
// screen /dev/tty.usbmodem1411 9600
//while(!Serial.available()) SPARK_WLAN_Loop();
//Serial.println("Initializing I2C devices...");
accelgyro.initialize();
// Cerify the connection:
//Serial.println("Testing device connections...");
//Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
}
void loop() {
// *** Get the Antenna Status ($PGTOP).
Gga gga(_gps);
if (gga.parse())
{
utcTime = gga.utcTime;
test = gga.latitude;
//double latitude = decDegFromDMMmm(gga.latitude);
latitude = gga.latitude;
northSouthIndicator = gga.northSouthIndicator;
longitude = gga.longitude;
eastWestIndicator = gga.eastWestIndicator;
}
Rmc rmc(_gps);
if (rmc.parse())
{
utcTime = rmc.utcTime;
test = rmc.latitude;
//double latitude = decDegFromDMMmm(rmc.latitude);
latitude = rmc.latitude;
northSouthIndicator = rmc.northSouthIndicator;
longitude = rmc.longitude;
eastWestIndicator = rmc.eastWestIndicator;
}
// read raw accel/gyro measurements from device
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
//Serial.print("a/g:\t");
analogvalue = analogRead(ax);
data = analogvalue;
if (analogvalue > 5000)
{
digitalWrite(ledPin, HIGH);
delay(1000);
}
// create JSON ojects set ups
char buf[622];
memset(buf, 0, sizeof(buf));
JSONBufferWriter writer(buf, sizeof(buf)-1);
writer.beginObject();
addToJSON(writer);
writer.endObject();
//Particle.publish("JSON", buf, PRIVATE);
Particle.publish("Potholes", (buf), PRIVATE);
delay(10000);
}
// function to add to JSON object
void addToJSON(JSONBufferWriter &writer){
writer.name("ax").value(String(ax));
writer.name("ay").value(String(ay));
writer.name("az").value(String(az));
writer.name("gx").value(String(gx));
writer.name("gy").value(String(gy));
writer.name("gz").value(String(gz));
writer.name("utcTime").value(utcTime);
writer.name("latitude").value(latitude);
writer.name("test").value(test);
writer.name("northSouthIndicator").value(northSouthIndicator);
writer.name("longitude").value(longitude);
writer.name("eastWestIndicator").value(eastWestIndicator);
}
void onSerialData() {
_gps.onSerialData();
}
Note i had to comment the new lines out just so it doesn’t break elsewhere but i would have this uncommented with the line under it removed;
latitude = gga.latitude;
You have two variables latitude one globally defined as String latitude and the other local double latitude.
When you assigne to the one you are not also assigning to the other.
And you are still setting the variables twice when only the last of the two will ever prevail.
BTW, it’s usually better to keep the binary/numeric representation of your values instead of storing them as String. The JSON writer can do the conversion on the fly just fine, without you wrapping the values in String(...)
Thank you! I have tried the updated code, unfortunately for some reason this brings all the accelarometer readings over ax, ay… as zeros. However, for the GPS latidude and longitude i am getting over the first whole number. So my results are
latitude = 55, longitude = 3. What i am missing is the decimal values after the whole number.
Someone in other thread had pointed to using TinyGPS++ which i also tried as i think looking at the filmware it would give what i need, however, this isn’t supported on the particle device.
Hi i am not sure what i changed from your version but i put my old version back on and only changed the double latitude and its coming over correct now as 55.8833! So you code does work.
Thank you so much for your help on all of this it has been much appreciated, i’ve certainly learned a few things!