Strings

First of all I want apologise for the question I am rising here, but, I am a beginner in the Arduino environment, in spite of follow this forum a while ago. I was more dedicated making small programs in assembly, but, I decided to go a step further.

I am trying to use the “Arduino GPS” Sketch at http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1267027090/8#8 . I tried to compile it but I got a lot of errors. I removed the “#include <WString.h>” because I read in a post that the last IDE versions have already included the library "<WString.h>. After compiling it again I had only 2 errors:

"class string has no member named ‘append’ " and
"class string has no member named ‘capacity’ "

One error was at “chkStr.append(inByte);” and the other “if (dataStr.length() == dataStr.capacity())”

I replaced the “append” by “concat” of the String functions but I do not know what can replace the “capacity”.

Your help is appreciated
thanks,
Manuel

The String class that is part of 0021 resizes the String when you concat a String onto it. So, it's capacity is infinite. You can delete that whole if test. There will be room in the String for the additional data, unless the Arduino runs out of memory, which that test is not ensuring, anyway.

PaulS, thanks for your help.

Let me paraphrase you. The "concat" I understand very well, is just adding a character to the string. The test

"if (dataStr.length() == dataStr.capacity()) {
break;
} else {
inByte = gps.read();
dataStr.append(inByte);"

can it be to limit the length of the NMEA msg that is coming in. Can it the replaced by:

"
if (dataStr.length() == 65 {
break;
}
else {
inByte = gps.read();
dataStr.concat(inByte);"

I say "65" because the lenght defenition of the "String dataStr = String(65);"

Thanks again for your opinion.
Manuel

Can it the replaced by:

It could. But, when you concat two strings, a new String is created. It has some maximum capacity, but that capacity is private. In any case, it doesn't matter, because when you add another character, the new String instance will be able to hold it.

All you need form the snippet you posted is:

inByte = gps.read();
dataStr.append(inByte);"

but replace append with concat.

PaulS. thanks again. I understood your point.Today is already too late for me, but tomorrow, I will do some changes to adapt it to my DOG_LCD and see how it runs. I will let you know tomorrow.

regards,
Manuel

I am trying to use the "Arduino GPS sketch below, but, due the no availability of the <WString.h> library and also due it is already included in the last ARDUINO IDE versions, I replaced in the code below the “append” by “concat” and the “dataStr.capacity()” by 65 that is the length of the “GPRMC” NMEA msg, but even with those changes it doesn’t work.

I did also other changes but without any result. I tried also to find in the sentence the “*” before the checksum but also didn’t work.

As I already told I am a beginner in the Arduino environment and C programing, so, my knowledge is very limited. Your help in solving this problem is appreciated.

Thanks and regards,
Manuel

#include <WString.h>
#include <LiquidCrystal.h>
#include <NewSoftSerial.h>

NewSoftSerial gps(8, -1);

String chkStr = String(5);
String dataStr = String(65);
String returnStr = String(12);

LiquidCrystal lcd(12, 11, 6, 5, 4, 3);

char chkByte;
char inByte;
int i = 5;
int page = 1;

void setup() {
  lcd.begin(16, 2);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("--Arduino  GPS--");
  lcd.setCursor(0, 1);
  lcd.print("------v2.1------");
  attachInterrupt(0, button, RISING);
  gps.begin(4800);
}

void loop() {
  chkStr = '\0';
  if (gps.available() > 0) {
    chkByte = gps.read();
    while (chkByte == '

) {
     if (i > 0) {
       if (gps.available() > 0) {
         inByte = gps.read();
         chkStr.append(inByte);
         i–;
       }
       else {
         waitForByte();
       }
     }
     else {
       i = 5;
       break;
     }
     while (chkStr.equals(“GPRMC”)) {
       if (gps.available() > 0) {
         if (dataStr.length() == dataStr.capacity()) {
           break;
         }
         else {
           inByte = gps.read();
           dataStr.append(inByte);
         }
       }
       else {
         waitForByte();
       }
       if (dataStr.length() == dataStr.capacity()) {
         if(dataStr.charAt(12) == ‘A’) {
           lcd.clear();
           if (page == 1) {
             printLat(0);
             printLon(1);
             resetData();
             break;
           }
           else if (page == 2) {
             printSpeed(0);
             printHeading(1);
             resetData();
             break;
           }
           else if (page == 3) {
             printTime(0);
             printDate(1);
             resetData();
             break;
           }
         }
         else {
           lcd.clear();
           aquiringFix();
           resetData();
           break;
         }
       }
     }
   }
 }
}

void waitForByte() {
 while (true) {
   if (gps.available() > 0) {
     break;
   }
   else {
     continue;
   }
 }
}

void aquiringFix() {
 lcd.setCursor(0, 0);
 lcd.print("----Aquiring----");
 lcd.setCursor(0, 1);
 lcd.print("------Fix!------");
}

void button() {
 if (page >= 3) {
   page = 1;
 }
 else {
   page++;
 }
}

void dataParse(int section) {
 char nextChar;
 int commas = 0;
 resetReturn();
 for (int x = 0; x <= dataStr.length(); x++) {
   nextChar = dataStr.charAt(x);
   if (nextChar == ‘,’) {
    commas++;
    continue;
   }
   if (commas == section) {
      returnStr.append(nextChar);
   }
   else if (commas > section) {
     break;
   }
 }
}

void printLat(int row) {
 lcd.setCursor(0, row);
 lcd.print("Lt: ");
 dataParse(4);
 lcd.print(returnStr);
 lcd.print(’ ‘);
 dataParse(3);
 lcd.print(‘0’);
 lcd.print(returnStr.charAt(0));
 lcd.print(returnStr.charAt(1));
 lcd.print(’ ');
 lcd.print(returnStr.charAt(2));
 lcd.print(returnStr.charAt(3));
 lcd.print(returnStr.charAt(4));
 lcd.print(returnStr.charAt(5));
 lcd.print(returnStr.charAt(6));
 lcd.print(returnStr.charAt(7));
}

void printLon(int row) {
 lcd.setCursor(0, row);
 lcd.print("Ln: ");
 dataParse(6);
 lcd.print(returnStr);
 lcd.print(’ ‘);
 dataParse(5);
 lcd.print(returnStr.charAt(0));
 lcd.print(returnStr.charAt(1));
 lcd.print(returnStr.charAt(2));
 lcd.print(’ ');
 lcd.print(returnStr.charAt(3));
 lcd.print(returnStr.charAt(4));
 lcd.print(returnStr.charAt(5));
 lcd.print(returnStr.charAt(6));
 lcd.print(returnStr.charAt(7));
 lcd.print(returnStr.charAt(8));
}

void printSpeed(int row) {
 lcd.setCursor(0, row);
 dataParse(7);
 lcd.print("Speed: ");
 lcd.print(returnStr);
 lcd.print(“Kts”);
}

void printHeading(int row) {
 lcd.setCursor(0, row);
 dataParse(8);
 lcd.print("Heading: ");
 lcd.print(returnStr);
}

void printDate(int row) {
 lcd.setCursor(0, row);
 dataParse(9);
 lcd.print(“Date: “);
 lcd.print(returnStr.charAt(0));
 lcd.print(returnStr.charAt(1));
 lcd.print(”-”);
 lcd.print(returnStr.charAt(2));
 lcd.print(returnStr.charAt(3));
 lcd.print("-");
 lcd.print(returnStr.charAt(4));
 lcd.print(returnStr.charAt(5));
}

void printTime(int row) {
 lcd.setCursor(0, row);
 dataParse(1);
 lcd.print(“Time: “);
 lcd.print(returnStr.charAt(0));
 lcd.print(returnStr.charAt(1));
 lcd.print(”:”);
 lcd.print(returnStr.charAt(2));
 lcd.print(returnStr.charAt(3));
 lcd.print(":");
 lcd.print(returnStr.charAt(4));
 lcd.print(returnStr.charAt(5));
}

void resetData() {
 dataStr = ‘\0’;
 gps.flush();
}

void resetReturn() {
 returnStr = ‘\0’;
}

but even with those changes it doesn't work.

I just want to scream every time someone posts something like this. What doesn't work?

Start simple. Just Serial.print() everything that comes from the GPS. Do you get data?

Then, define what you want to do with that data. There is a library, TinyGPS that already exists to parse two kinds of GPS output. Does this do what you want? If so, why aren't you using it? If not, then you'll need to parse the other kinds of sentences that the GPS returns.

PaulS, looking for your number of posts we can see that you are really an expert. I apologize If I have offended you for the questions I raised. I know I'm dumb (and too old to change now), as well as an absolute zero in terms of C language and Arduino.

I know the existence of TinyGPS library, and it works, but looking to the sketch is too much complicated for me. The sketch I posted seems simpler to. I just want to put it working for later modify it (adapt) to use in an aeromodel and sent GPS data Down.

If you or some one can and tell me were I can find the information for (equivalence) of the "capacity" in the context of the above sketch "if (dataStr.length() == dataStr.capacity())"
I will appreciated. I am asking this because IMHO I tink it here the problem.
Thanks,
Manuel

I’m not offended by your questions, and I respect the decisions you are making.

With the previous string class, a String object could contain a maximum number of characters. So, it was necessary to check it’s capacity to make sure that it could hold another character.

With the new version of String, the concat() method invokes the += operator. The += operator checks that there is room in the current object for the data to be added. If there is not, it allocates a new buffer large enough to hold the existing data and the new data, copies the existing data to the new buffer, and adds the new data to the buffer. It then frees the old buffer.

So, capacity is no longer an issue.

If it makes you feel better, though, you CAN modify your copy of the WString.h and WString.cpp files, and create a method called capacity() that returns the private member _capacity. The files are located in \hardware\arduino\cores\arduino.

PaulS, thanks again, your explanation is much clear now. What I need to do, is look for the last character of the $GPRMC sentence. I am going to try to modify the sketch by the method of trial and error and see what happens.

According to what I read in the Arduiniana.org, the "NewSoftSerial" library was written base on interrupts instead of pulling. My question is: Can I start execute the NewSoftSeial code only when the data is in, like a external interrupt execution? I asking this because I have already a sketch that reads a pressure sensor to measure the vertical speed, another that reads the air speed, RPM (interrupt driven) and cell voltage. I am afraid the if the serial read is not interrupt driven I may miss data.

Can you please give me some clues on how to solve this?

Thanks in advance.
Regards,
Manuel