[ solved ] split the content of one big char into segments

hi,
i kindly ask for your help on the following problem.
I send a chars from one arduino to another who receives this char by char and makes a big char again from it.

this char contains gps data --> "1234.56N78912.34E+123*456"

my problem is now that i want to split this char into certain portions.

1234.56N should be one seperate char
78912.34E should be a seperate char
123 should be a seperate char
and 456 also

the length of this char is always fixed.
is there a smart possibility to count the characters within this char to split it ?
or is there any other method to do this?

thank you and best regards

Roman

Take a look at the string searching functions described here: <cstring> (string.h) - C++ Reference

or is there any other method to do this?

Send a delimiter between data items and use strok() to split up the string after receiving it

You should also read Serial input basics - updated

this char contains gps data → “1234.56N78912.34E+123*456”

That is NOT a char. That data may be stored in a char ARRAY, which is something completely different. Try to sound like you know what you are talking about by using the correct terminology.

[/rant]

Serial Input Basics

evenmars → this is axactly the axample I used. And it works. but this gives one chunk og char ARRAY - sorry for my lack of profession…

the “Serial.println(receivedChars)” of the Serial Input Basics sketch is one “chunk” and this I need to split

thank you for your help

best regards
Roman

@PaulS: I thought this forum is for all arduino users and not just for professional programmers. Your comment is just an offense and does not help in any way

ftf74:
@PaulS: I thought this forum is for all arduino users and not just for professional programmers. Your comment is just an offense and does not help in any way

This forum IS for all levels of users. But, we can only communicate if we agree on the meaning of all collections of letters. Obviously, the collection of letters "char" means something completely different to you than what it means to the rest of us. So, we are not going to be able to communicate effectively.

Pick some field where you consider yourself an expert, or at least an advanced user. Think about how difficult it is to communicate with people that are beginners when they use the terms you are familiar with, to mean something that you KNOW is wrong, and who won't use the term(s) correctly. Don't you get frustrated?

I tried to explain my problem as good as I can.
and you are that clever that you understood it.
thank you Paul

What happened to the commas in the original GPS sentence? Can you show your code which sends this?

If you are just sending GPS data, then try to preserve the original NMEA format. Then you could use a standard library like TinyGPS on the receiving end.

If you are adding to the GPS data then make your own sentence and send both sentences.

@PaulS I usually spell "array" lowercase. Is there something special about "ARRAY" which is different?

ftf74:
I tried to explain my problem as good as I can.
and you are that clever that you understood it.
thank you Paul

Well, he does have a point though. He merely pointed out, that the terminology you used was wrong. I doubt that it was meant in an offensive way.

ftf74:
this char contains gps data --> "1234.56N78912.34E+123*456"

my problem is now that i want to split this char into certain portions.

1234.56N should be one seperate char
78912.34E should be a seperate char
123 should be a seperate char
and 456 also

the length of this char is always fixed.

Are the segments you want to extract always the same length? If not, to extract the first one, use strtok to look for a 'N'. It'll replace the 'N' with a '\0' though. The "78912.34E" is a bit easier, because you can use strtok with '+'. The other two are easy as well.

char* data = "1234.56N78912.34E+123*456" ;

void setup() {

  Serial.begin(9600);
  Serial.println(data);
  // put your setup code here, to run once:
  char* northSegment = strtok(data, "N");
  char* eastSegment = strtok(NULL, "+");
  char* thirdSegment = strtok(NULL, "*");
  char* fourthSegment = strtok(NULL, "\0");

  
  Serial.println(northSegment);
  Serial.println(eastSegment);
  Serial.println(thirdSegment);
  Serial.println(fourthSegment);
}

This will give you (on the serial monitor):

1234.56N78912.34E+123*456
1234.56
78912.34E
123
456

Please note however, that this solution might result in undefined behaviour, if 'N', '+' or '*' are not present or the supplied pointer does not point to a null terminated string.

As @MorganS said, if you send the original GPS sentence with its delimiters, the job is easy. If you must have a custom string, then create it with proper delimiters.

Hi,
the design is based from 2 Arduino Pro Mini.
the first one is getting APRS datas from an DRA818
this Arduino is very timing sensitive (the used libAPRS LibAPRS is timing sensitive) and because of this there is a second Arduino which has an OLED display attached, and a GPS.
The First Arduino sends the APRS Data to the second one which calculates some additional things and displays all on the OLED display.
but I do also want to send APRS data which is mainly GPS data in NMEA Format, altitude and speed information.
So I send these gps datas back from the second arduino to the first one, which is the char array I already mentioned.

the last thing I still need to do is to extract this char array on the first arduino (the timing sensitive one) to fill 2 parameters with 1234.56N as LAT information and 78912.34E as LON information and the Altitude and speed information.

so the "N" from 1234.56N and the "E" from 78912.34E are absolutely mandatory.

but to get this datas split I need your help please.

I changed now the char array to this format - with comma seperated
1234.56N,78912.34E,567,891

ftf74:
I changed now the char array to this format - with comma seperated

Now it's straight forward. Use strtok with comma as the delimiter.

ftf74:
Hi,
the design is based from 2 Arduino Pro Mini.
the first one is getting APRS datas from an DRA818
this Arduino is very timing sensitive (the used libAPRS LibAPRS is timing sensitive) and because of this there is a second Arduino which has an OLED display attached, and a GPS.
The First Arduino sends the APRS Data to the second one which calculates some additional things and displays all on the OLED display.
but I do also want to send APRS data which is mainly GPS data in NMEA Format, altitude and speed information.
So I send these gps datas back from the second arduino to the first one, which is the char array I already mentioned.

So:

  1. Arduino:
  • Receive APRS data via DRA-818
  • Relay that information to second arduino
  • Receive Position data from second arduino
  • Send position data via DRA-818
  1. Arduino:
  • Receive ARPS packet
  • Decode APRS packet
  • Display data on OLED
  • Send extracted GPS information to first arduino

?

ftf74:
I changed now the char array to this format - with comma seperated
1234.56N,78912.34E,567,891

Now it is pretty easy to extract the segments (as @gfvalvo already said):

char* lat = strtok(data, ",");
char* lon = strtok(NULL, ",");
char* num1 = strtok(NULL, ",");
char* num2 = strtok(NULL, ",");

OK. Not the most flexible library out there. It must have an 8-character latitude and it must be presented to the library in a null-terminated string.

The thing that stands out in the library is the inclusion of the freeMemory() function. That is a big fat warning sign saying "You will have memory problems. Here is a short stick to poke at the problems."

If you already made sure that the sender is sending the correct number of characters then just index into the string directly:

cont int indexLongitude = 9;
  APRS_setLon(&recievedChars[indexLongitude]);

You can do it with pointer arithmetic but I prefer to use the location-of operator to make it clear we're sending the location of the 9th character.

  1. Arduino:
  • Receive APRS data via DRA-818
  • Decode APRS packet
  • Relay that information to second arduino
  • Receive Position data from second arduino
  • encodes own gps position with APRS library and sends it via DRA-818 on air
  1. Arduino:
  • Receive decoded APRS data
  • Display data on OLED
  • calculates “distance to APRS sender” etc.
  • Send extracted GPS information to first arduino

I think I inserted your suggestions but now I do not see any char array from the second arduino.

ok on the first arduino my loop is just

void loop()
{
  processPacket(); //decodes received APRS data
  receiveWithStartEndMarkers(); //receives char array from second arduino "1234.56N,78912.34E,567,891"
  parseData();
  showParsedData();

}
void receiveWithStartEndMarkers()
{

  static boolean recvInProgress = false;
  static byte ndx = 0;
  char startMarker = '<';
  char endMarker = '=';
  char rc;
  while (SecondArduinoSerial.available() > 0 && newData == false)
  {
    rc = SecondArduinoSerial.read();

    if (recvInProgress == true)
    {
      if (rc != endMarker)
      {
        receivedChars[ndx] = rc;
        ndx++;
        if (ndx >= numChars)
        {
          ndx = numChars - 1;
        }
      }
      else
      {
        receivedChars[ndx] = '\n';
        recvInProgress = false;
        ndx = 0;
        newData = true;
      }
    }
    else if (rc == startMarker)
    {
      recvInProgress = true;
    }
  }
}
void parseData()   // split the data into its parts
{

  char* northSegment = strtok(receivedChars, ",");
  char* eastSegment = strtok(NULL, ",");
  char* thirdSegment = strtok(NULL, ",");
  char* fourthSegment = strtok(NULL, "\0");

}
void showParsedData()
{
  if (newData == true)
  {
    Serial.println(northSegment);
    Serial.println(eastSegment);
    Serial.println(thirdSegment);
    Serial.println(fourthSegment);
    newData = false;
  }
}

gfvalvo:
Now it's straight forward. Use strtok with comma as the delimiter.

It is NOT necessarily straightforward, or even possible, to parse NMEA data with strtok. A sentence can have multiple delimiters in a row, when the GPS has no data to put in the field. strtok() can not return a pointer to an empty string, so it can't tell you that there are adjacent delimiters. It consumes as many adjacent delimiters as it can, and then returns a pointer to the next token.

OP: Look at how TinyGPS++, for instance, parses NMEA data, without using strtok(). Hint: You have to fund the commas individually, which is NOT hard.

MorganS:
OK. Not the most flexible library out there. It must have an 8-character latitude and it must be presented to the library in a null-terminated string.

The thing that stands out in the library is the inclusion of the freeMemory() function. That is a big fat warning sign saying "You will have memory problems. Here is a short stick to poke at the problems."

If you already made sure that the sender is sending the correct number of characters then just index into the string directly:

cont int indexLongitude = 9;

APRS_setLon(&recievedChars[indexLongitude]);




You can do it with pointer arithmetic but I prefer to use the location-of operator to make it clear we're sending the location of the 9th character.

this sounds interresting but how do I limit this for APRS_setLat and APRS_setLon ?

PaulS:
It is NOT necessarily straightforward, or even possible, to parse NMEA data with strtok.

It’s important to read posts carefully. OP’s string is NOT a NMEA sentence. Go back and read Reply #12.