Pages: [1] 2   Go Down
Author Topic: trying to split a char  (Read 1578 times)
0 Members and 1 Guest are viewing this topic.
Virginia, USA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 93
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am working with a GPS using a software serial port and putting each character into a char array. I need to split all the data such as latitude, longitude, date and time and put them into variables so I can parse the data individually. I am using the strtok() function to separate the comma delimited data. From there I run a loop to separate the tokens and populate the variables. This works great and I get all the data properly. Now I am trying to work with the date variable which is stored as a char but I cant figure out how.The date comes in format HhMmSs (Ex. 062317) and  I need to split it into int hours, int minutes, int seconds. Can I split a char like this? If not how can I grab the data differently in order to split it?Here is code for how I am getting the data for the date variable.

Code:
char date;
char delimiters[] = ",";
char* valPosition;

void GPRMC(){
  valPosition = strtok(GPRMCC, delimiters);
  i = 0;
  while(valPosition != NULL || i < 11){
    i++;
    valPosition = strtok(NULL, delimiters);
    if(i==9){
      date = *valPosition;
      Serial.print(F("date = "));
      Serial.println(date);
    }
Logged

Scottsdale
Offline Offline
Newbie
*
Karma: 0
Posts: 27
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Here's a tip:

If you are trying to use GPS with arduino, consider using the TinyGPS library. It has a reasonably small footprint and seems relatively easy to use. I am going to use it when I get my GPS hooked up with my autopilot software. Should make things much easier than having to manually parse the data string.

Side note: For some reason, the TinyGPS website is sometimes down... or it might be slow loading.

Zachary
Logged

RadarProject - Arduino Autopilot for RC http://radarproject.wordpress.com/

Virginia, USA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 93
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I appreciate that. I have used both tinyGPS library and the sketch from the playground and they both work well. I am trying to write my own in order to learn as well as develop some features for my project that would impossible without a lot of modification to the library.
Logged

France
Offline Offline
Edison Member
*
Karma: 38
Posts: 1012
Scientia potentia est.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello, an easy solution is to use sscanf
Code:
uint8_t h, m, s;
sscanf( date, "%2hhu%2hhu%2hhu", &h, &m, &s );

//or if you really need int..
int h, m, s;
sscanf( date, "%2d%2d%2d", &h, &m, &s );

Another solution..
Code:
int
  h = ((date[0] - '0') * 10) + (date[1] - '0'),
  m = ((date[2] - '0') * 10) + (date[3] - '0'),
  s = ((date[4] - '0') * 10) + (date[5] - '0');
« Last Edit: December 11, 2012, 04:09:39 am by guix » Logged

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I would avoid sscanf(): like printf(), it is one of those first things they teach you not to do in embedded programming 101.

The 2nd approach is what I would use, probably through a macro to structure it a little bit more.

Logged

Virginia, USA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 93
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have tried to split the char as if it were an array but I get an error when I try to compile. For example if I do this it throws as error.

Code:
char time;
int hour;

hour = time[0];

I am not sure how to get grab the data other than using a char so I have been stuck using that. Can I convert a char to a char array and then use the suggested method?
 
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 644
Posts: 50524
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I am not sure how to get grab the data other than using a char
It would help if you'd use standard terminology as reflected in the names of the methods/functions you are using. There is no class that has a grab() method, that I know of, and there is no grab() function on the Arduino.

You can only read characters from the serial port. There are methods in the HardwareSerial class that allow you to read more than one character, but, underneath, they read one character at a time. You have to store those characters in an array if you want to deal with more than one of them.

Trying to use array notation on a scalar variable WILL cause the compiler to laugh at you.
Logged

Virginia, USA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 93
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

PaulS- fair enough, I will try to be more accurate with my terminology. I read each incoming byte on a software serial port and put it into a char array. I split the data using strtok() and use atoi, atol and atof to populate the variables. All of this is working well and I have successfully split all the data based on the comma delimiter and populated all my variables. If all I needed was to print the time variable I would be good. However, I need to do some math with the hours, minutes and seconds and to the best of my knowledge this requires an int. I did not use atol because if the time is 000517 it would populate the time as 517 and drop all the zeros. If it drops the zeros I am not sure what index number represents HhMmSs. Because of this I decided to put the time variable as a char which keeps the zero(s) as a place holder. Now I need to somehow split the char and make int hours, int minutes, int seconds.

Code:
valPosition = strtok(GPGGAC, delimiters);
  i = 0;
  while(valPosition != NULL || i < 10){
    i++;  
    valPosition = strtok(NULL, delimiters); //Here we pass in a NULL value, which tells strtok to continue working with the previous string
    if(i==1){
      //time = atol(valPosition); //drops the zeros so I don't know how to split it like this
      time = *valPosition; //saves as a char but I dont know how to split it and change to int
      Serial.print(F("time = "));
      Serial.println(time);
    }
  

« Last Edit: December 11, 2012, 09:53:18 am by fbriggs4 » Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 644
Posts: 50524
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
time = *valPosition; //saves as a char but I dont know how to split it and change to int
valPosition is a pointer. Pointers and arrays are so closely related that you can, for the most part, says that they are the same thing. For your purpose, valPosition and someArray[6] are the same thing.

Code:
char hrStg[3], mnStg[3], scStg[3];

hrStg[0] = valPosition[0];
hrStg[1] = valPosition[1];
hrStg[2] = '\0';

mnStg[0] = valPosition[2];
mnStg[1] = valPosition[3];
mnStg[2] = '\0';

seStg[0] = valPosition[4];
seStg[1] = valPosition[5];
seStg[2] = '\0';

int hour = atoi(hrStg);
int min = atoi(mnStg);
int sec = atoi(seStg);
Logged

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12630
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I need to do some math with the hours, minutes and seconds and to the best of my knowledge this requires an int.

Guix has already given you some code to convert a string containing hhmmss format into integer hours, minutes and seconds.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Virginia, USA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 93
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

PaulS- that worked perfectly, thank you.

PeterH- I did not use the scanf() because I have read here (and elsewhere) that it is not a wise thing to do. I don't know exactly why but I am sure there is good reason why people caution against its use. The second example uses a char array and I didn't have an array so I was not able to make it work.
Logged

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
The second example uses a char array and I didn't have an array so I was not able to make it work.

You do.

guix's code is small and faster.
Logged

Virginia, USA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 93
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

dhenry- Can you please explain this to me because I really don't get it and I would like to learn. I was storing the variable as char time;,  my understanding is that it is not an array. When I tried to treat the variable time like an array I got a compile error.
Code:
char time;
int hour;

hour = time[0]; //this gives a compile error for reasons that PaulS described below

The solution that PaulS provided helped me to store the hours, minutes and seconds as char arrays which allows me to split the data and create the int's. Since I was not storing the data as an array I am not clear on how I could make the example by guix work.
Logged

France
Offline Offline
Edison Member
*
Karma: 38
Posts: 1012
Scientia potentia est.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes sorry mistake in my code, if you replace all "date" by "valPosition" then it should work smiley

And sscanf is bad only if you need to take care about your memory usage, the first time you use it your code will grow by almost 3 kB, but then you can use it many times, it will NOT grow 3 kB each time you use it. If you use a Arduino Mega then no problem you can use it because it will take only like 1-2 % of the available program memory...

But if you can do something without the need to use sscanf, then do it smiley-wink
« Last Edit: December 11, 2012, 01:13:30 pm by guix » Logged

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12630
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I was storing the variable as char time;,  my understanding is that it is not an array. When I tried to treat the variable time like an array I got a compile error.

That is correct. Your code was wrong because you were trying to store a 'C' string in a single character. It would have to be a char array in order to hold a string, and once the variable is declared correctly you can manipulate the string held in it using any of the techniques that guix and PaulS showed you.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Pages: [1] 2   Go Up
Jump to: