I need some help. Im trying to parse a string of coordinates that I received from the Serial. What im trying to do is take the data and convert it into waypoints (pair of coordinates) in order to create a route.
I have a python script that takes a large string of coordinates and parses out pairs and sends those pairs to the Arduino and adds a "\n" to the end of them like this:
33.660571,-111.889232,33.660594,-111.889114\n
I have no idea if I'm approaching this correctly, C programming is not my forte.
Here is the code I wrote, the parseCommand() gets the Serial data and parses it. Then it sends the set of coors to the getWaypoint() where it sets the first waypoint.
I need help figuring out why its not setting all the coordinates correctly. Right now it missing one of the four. I guess i wanted to make sure I'm approaching this correctly or does my code have issues.
This is what the Arduino is producing.
33.660572
-111.889228
0.000000
-111.889099
using strtok() and atof() it reads the string OK, e.g.
// strtok example - parse tokens into float values
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
char str[] ="33.660571,-111.889232,33.660594,-111.889114"; // text to tokenise
char * pch; // pointer to tokens
Serial.print("Splitting string ");
Serial.print(str);
Serial.println(" into tokens:");
pch = strtok (str,","); // get first token
while (pch != NULL)
{
Serial.print("string found ");
Serial.println(pch); // print it
float x=atof(pch); // conver to float
Serial.print(" float ");
Serial.println(x); // print float
pch = strtok (NULL, ","); // get next token
}
}
void loop() {}
serial monitor displays
Splitting string 33.660571,-111.889232,33.660594,-111.889114 into tokens:
string found 33.660571
float 33.66
string found -111.889232
float -111.89
string found 33.660594
float 33.66
string found -111.889114
float -111.89
Note that Serial.println(x,6); will print a float with 6 decimal places.
Note also that Arduino floats are only good for about 6-7 significant figures, so that inputs like -111.889232 are only stored to 3-4 decimal places, like -111.889228
@horace thank you for the help! Your suggestion seems be working, but is there a way I can get the entire coordinate value? Right now it is just giving me two spaces after the decimal. How could I do this using double? I need the coordinates to be accurate.
right now the console show this:
setting destination:
33.66
-111.89
33.66
-111.89
changed to using a double (atof() returns a double) and printing to six digits after decimal point
// strtok example - parse tokens into float values
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.print("size of double ");
Serial.println(sizeof(double));
char str[] ="33.660571,-111.889232,33.660594,-111.889114"; // text to tokenise
char * pch; // pointer to tokens
Serial.print("Splitting string ");
Serial.print(str);
Serial.println(" into tokens:");
pch = strtok (str,","); // get first token
while (pch != NULL)
{
Serial.print("string found ");
Serial.println(pch); // print it
double x=atof(pch); // conver to double
Serial.print(" double ");
Serial.println(x,6); // print
pch = strtok (NULL, ","); // get next token
}
}
void loop() {}
running on a Node MCU ESP8266 where doubles are 8 bytes (16 to 17 significant digits)
size of double 8
Splitting string 33.660571,-111.889232,33.660594,-111.889114 into tokens:
string found 33.660571
double 33.660571
string found -111.889232
double -111.889232
string found 33.660594
double 33.660594
string found -111.889114
double -111.889114
the program of post 10 compiles and run on my UNO OK - the serial monitor output is
size of double 4
Splitting string 33.660571,-111.889232,33.660594,-111.889114 into tokens:
string found 33.660571
double 33.660572
string found -111.889232
double -111.889228
string found 33.660594
double 33.660591
string found -111.889114
double -111.889106
note that doubles on a UNO are the same as float being 4 bytes giving 6 to 7 significant digits
no idea where your error message comes from as the program does not use strtod()
ugh, my fault, i didn't save the edit, i re-ran and error is gone.
How would I go about assigning (x, 6) to the wapypoint array? Currently it only assigns 33.66
and -111.89. We can Serial print them in the form I need but can we assign them to the array with the same length?
Please post code which compiles, uses the waypoint array, and includes the corrections you have made to your original posting. Explain with comments what you are trying to assign where.
you can print six digits after the decimal point, e.g.
Serial.println(x,6); // print
however you are using a UNO where double and float only use 4 bytes which limits real numbers to 6 or 7 significant digits - any more digits you print will be meaningless
for example your value has 9 digits
111.889232
when stored as a double or float on a UNO the last two digits will be lost
if you require 9 significant digits you will have to move to a microcontroller where doubles use 8 bytes giving 16 or 17 significan digits, e.g. an ESP32
It is possible do 9 significant digits on an uno with `long int' representing microdegrees, but the parsing, handling and printing is more complicated.
The OP could also manage the integer component and the fractional component of each values separately, given that it's initially being parsed from a string anyway. But ultimately, that would be a very clunky and error-likely approach.
@horace oh no, definitely not what I wanted to hear. So if I wanted to stay in the Arduino world and not have to re write my code for a different microcontroller, what are my options? A MEGA?
the Mega is the same family of microcontrollers as the UNO and floats and doubles are 4 bytes (6/7 significant digits), e.g. run of program from post 10 on a Mega
size of double 4
Splitting string 33.660571,-111.889232,33.660594,-111.889114 into tokens:
string found 33.660571
double 33.660572
string found -111.889232
double -111.889228
string found 33.660594
double 33.660591
string found -111.889114
double -111.889106
I would suggest moving to an ESP32 far more powerful than UNO and has plenty of IO facilities
the UNO uses 5V logic the ESP32 uses 3.3V logic so you need to check your sensors, LCD, etc will work with 3.3V logic