Error on parsing a string from serial

Dear forum members,

I'm pretty new to arduino programming. I did a few obstacle avoiding robots in the past and would like to build a drawbot that sends and receives coordinates over serial. So I am building a machine that can move within a square and send its coordinates and put a dot wherever it wants. But before that's finished, I would like to check if the arduino can actually send and receive data. I have a working sketch in Processing and i am trying to write a sketch for the arduino.

For this I use a piece of code that I got from here.

And I believe it should work. However, it doesn't compile and I get the error message

'class String' has no member named 'parseInt'

So I think the IDE says that parseInt doesn't belong to a string. But according to the reference it should!

So does anybody have an idea on how to solve this?
I will post both my both my arduino and processing sketches down here.

So here's the arduino code (that doesn't compile)

unsigned int xPos ;           //this integer sets the X position of the robot
unsigned int yPos   ;         //this integer sets the Y position of the robot
unsigned int xGoal  ;        //this integer sets the X location of the pixel where the mothership thinks the robot is. If the Robot is in position, it can put a dot.
unsigned int yGoal   ;       //this integer sets the X location of the pixel where the mothership thinks the robot is. If the Robot is in position, it can put a dot.
unsigned int GreyValue ;    
char val;
int CanvasWidth = 182;
int CanvasHeight = 263;
String received ;

void setup() {
  
  Serial.begin(9600);                             //Serial communication, we are using it


  goHome();        //move to the 0,0 position.
}



void loop() {
  
  
Serial.print(xPos);
Serial.print(",");
Serial.println(yPos);

 
// The mothership (The Processing sketch on the pc) will receive this data 
// and look up the corresponding pixel in a bitmap.
// Then it will send that data back in de form of "xxx,yyy,grevvalue,L", 
// where L is our termination char of choice.

  if( Serial.available() )  // if data is available to read
  {
    val = Serial.read();    // read it and store it in 'val'
    if( val != 'L' ) {      // if not an 'L'
      received+=val;            // add it to the received string
    } 
    
    else {
      // if 'L' was received (our designated termination char)  
         
     int XGoal = received.parseInt(); //the first series of characters before a ","
     int YGoal = received.parseInt(); //the next series of characters before a ","
     int GreyValue = received.parseInt(); //the final series of characters before a "L"
     String received = "";                // Flush the string so we can receive new data
     }} 
 else {
  delay (100); // wait a bit and try again
  }
 }

if (xGoal == xPos) {
  if (yGoal == yPos){
  MoveOn();
}}


void MoveOn() //this subroutine tells the robot how to move to the next position.
{
if (xPos != CanvasWidth) {   //if we are not at the end of the x axis
   xPos = xPos +1;           //and adjust x position by increasing by one
}
else if (yPos != CanvasHeight) { //if we are not at the end of the y axis
  xPos = xPos - CanvasWidth;           //and adjust x position to its starting value
  yPos = yPos+1;                    //and adjust y position by increasing by one
}
else {
 delay(1)                       //Do nothing. This will make the robot print the last pixel over and over again.
}}




void goHome() //this subroutine tells the robot how to move to position 0,0
{
while (xPos != 0) {         //if we are not x position 0
   xPos = xPos -1;           //and adjust x position by increasing by one
                            //this will repeat until we are at position x=0
}

while (yPos != 0) {         //if we are not x position 0
    yPos = yPos -1;           //and adjust x position by increasing by one
}}

And for the sake of completeness, my processing sketch:

import processing.serial.*; //import the Serial library
 
Serial myPort;  //the Serial port object
String strIn = "";  //Declare a string with name strIn, this will store the coordinates received from the arduino
String strOut = "";  //Declare a string with name strOut, this will store the coordinates and corrseponding geryvalue of a pixel in the bitmap.
String portName = "";  //apparently this is necessary
String coordinates;
int locX= 0;
int locY= 0;

PImage img;

void setup()
{
  
  size(182,262);  //This is the size of the canvas and the range of the printer //<>//
  // Make a new instance of a PImage by loading an image file
  img = loadImage("parel.jpg");
  tint(255,100);
  image (img,0,0);
  String portName = Serial.list()[0];
  myPort = new Serial(this, portName,9600);
} //<>//


void draw()
{ 
  while (myPort.available() > 0) {                 // If data is available,
  strIn = myPort.readStringUntil('\n');         // read it and store it in a string called strIn
  } 
  String[] coordinates = split(strIn, ",");    //<>//
  //This should cut the strIn string in two integers, separated by a comma
  //and called coordinates. We expect a message coming in something like "XXX YYY"
  int locX = int(trim(coordinates[0]));        //This says that the first integer is an integer called LocX
  int locY = int(trim(coordinates[1]));       //This says that the first integer is an integer called LocX
  color pix = img.get(locX, locY);
  stroke(pix);
  point(locX, locY);
  strOut = locX + "," + locY + "," + pix + "L" + "\n";  //here all the needed values are integrated into the string strOut
  myPort.write(strOut);    //which we send over the serial port to the arduino to parse
}

It's telling you the String object does not contain a method named "parseInt" because.... Well, because the String object does not contain a method named "parseInt".

Regards,
Ray L.

Dirruk:
So I think the IDE says that parseInt doesn't belong to a string. But according to the reference it should!

Can you point us to the reference that said String had a method called parseInt? As far as I know that is a method of the Stream class.

There are other issues, too. My guess is that this code block:

if (xGoal == xPos) {
  if (yGoal == yPos) {
    MoveOn();
  }
}

probably belongs inside the loop() function, but currently it is not. Also, I would get rid of the String object received and replace it with a char array (e.g., char received[]). Strings are convenient, but chew up more memory than the alternatives.

Also, give us a test example of what will the Serial input is expected to look like.

So does anybody have an idea on how to solve this?

The easy answer is don't us parseInt. I've never used it and it may impact what the rest of the code is doing. I just posted a possible solution in another discussion below. To the point, figure out the best way to decode the data you will send, then send the data in that format.

http://forum.arduino.cc/index.php?topic=362444.msg2498970#msg2498970

Okay, so my mistake was that parseInt only goes with a stream, not with a string. I'll try it using Zoomkat's option.

And Econjack, thanks for pointing that mistake out.

@Dirruk, have a look at the examples in Serial Input Basics. They are simple, reliable non-blocking ways to receive data. There is also a parse example.

...R

I managed to get my code working. Now Processing is giving me problems, but that is for another forum :wink:

I'll put the working code here in case people run into a similar problem.

unsigned int xPos ;           //this integer sets the X position of the robot
unsigned int yPos   ;         //this integer sets the Y position of the robot
unsigned int xGoal  ;        //this integer sets the X location of the pixel where the mothership thinks the robot is. If the Robot is in position, it can put a dot.
unsigned int yGoal   ;       //this integer sets the X location of the pixel where the mothership thinks the robot is. If the Robot is in position, it can put a dot.
unsigned int GreyValue ;    
char val;
int CanvasWidth = 182;
int CanvasHeight = 263;
String received ;

void setup() {
  
  Serial.begin(9600);                             //Serial communication, we are using it


  goHome();        //move to the 0,0 position.
}



void loop() {
  
Serial.print(xPos);
Serial.print(",");
Serial.println(yPos);

  if( Serial.available() )  // if data is available to read
  {
    val = Serial.read();    // read it and store it in 'val'
    if( val != 'L' ) {      // if not an 'L'
      received+=val;            // add it to the received string
    } 
    
    else {
      // if 'L' was received (our designated termination char)  
      //Look for the location of the first comma
      int commaIndex = received.indexOf(',');
       //  Search for the next comma just after the first
      int secondCommaIndex = received.indexOf(',', commaIndex+1);

      String firstValue = received.substring(0, commaIndex);  //the first series of characters before the first comma
      String secondValue = received.substring(commaIndex+1, secondCommaIndex);   //the next series of characters between the first and second comma
      String thirdValue = received.substring(secondCommaIndex); //the final series of characters before the L that we didn't add to the "received" string

      int xGoal = firstValue.toInt();
      int yGoal = secondValue.toInt();
      int GreyValue = thirdValue.toInt();

     String received = "";                // Flush the string so we can receive new data
     }} 
 else {
  delay (100); // wait a bit and try again
  }
 

if (xGoal == xPos) {
  if (yGoal == yPos){
  MoveOn();
}}}


void MoveOn() //this subroutine tells the robot how to move to the next position.
{
if (xPos != CanvasWidth) {   //if we are not at the end of the x axis
   xPos = xPos +1;           //and adjust x position by increasing by one
}
else if (yPos != CanvasHeight) { //if we are not at the end of the y axis
  xPos = xPos - CanvasWidth;           //and adjust x position to its starting value
  yPos = yPos+1;                    //and adjust y position by increasing by one
}
else {
 delay(1);                       //Do nothing. This will make the robot print the last pixel over and over again.
}}




void goHome() //this subroutine tells the robot how to move to position 0,0
{
while (xPos != 0) {         //if we are not x position 0
   xPos = xPos -1;           //and adjust x position by increasing by one
                            //this will repeat until we are at position x=0
}

while (yPos != 0) {         //if we are not x position 0
    yPos = yPos -1;           //and adjust x position by increasing by one
}}

With your code and the cursor in the IDE source window, use Ctrl-T to reformat your code. I think you'll find it easier to read using standard C formatting.