serial input with parsing

This is Tom Igoe’s code which I have tried to mess about with. I am fairly new to this, and I have read Serial Input Basics. However, this seems to offer a simpler solution to separating out data sent over serial - and it worked - occasionally, then not at all. Could someone tell me what the problem is with this code?

int w1 = 0;
int w2 = 0;
int w3 = 0;
int q1 = 0;
int q2 = 0;
int q3 = 0;


void setup() {
 Serial.begin(9600);
}

void loop() {
 // Assumes a string in from the serial port like so:
 // for example: "w5,200, 5 \n":


  if (Serial.find("q")) {
   q1 = Serial.parseInt(); // parses numeric characters before the comma
   q2 = Serial.parseInt();// parses numeric characters after the comma
   q3 = Serial.parseInt();
   // print the results back to the sender:
   Serial.print("q1: " );
   Serial.print(q1);
   Serial.print(" q2: ");
   Serial.print(q2);
   Serial.print(" q3: ");
   Serial.println(q3);
 } 
 else if (Serial.find("w")) {
   w1 = Serial.parseInt(); // parses numeric characters before the comma
   w2 = Serial.parseInt();// parses numeric characters after the comma
   w3 = Serial.parseInt();
   // print the results back to the sender:
   Serial.print("w1: " );
   Serial.print(w1);
   Serial.print(" w2: ");
   Serial.print(w2);
   Serial.print(" w3: ");
   Serial.println(w3);
 }
 
}

SerialNumericParser.ino (1.34 KB)

Well, for starters it’s not in code tags…The code tags make the code look

like this

when posting source code files. It makes it easier to read, and can be copied with a single mouse click. Also, if you don’t do it, some of the character sequences in the code can be misinterpred by the forum code as italics or funny emoticons.
If you have already posted without using code tags, open your message and select “modify” from the pull down menu labelled, “More”, at the lower left corner of the message. Highlight your code by selecting it (it turns blue), and then click on the “</>” icon at the upper left hand corner. Click on the “Save” button. Code tags can also be inserted manually in the forum text using the code and /code metatags.

Unless the sketch is too large, it’s better if you post your code, rather than attach it. When it’s attached, we have to download it, create a folder then open your code in our IDE. And afterwards, the folder remains unless we navigate to the “Temp” folder and manually remove it. It’s much easier to just view the code in your post.

You also haven’t told us any details about what worked/didn’t work.

Thank you for pointing the code tags out to me.

The code is supposed to print to the serial monitor with the prefix w or q the data (X3) input previously with that prefix - comma separated.

It prints the first serial.find (eg q1, q2, q3)
and then seems to hang sometimes, recognizing no more data input.

Sometimes it doesn't though, and prints more input. Occasionally it has printed both q and w data.

I hoped that what I was doing was obviously wrong in some way!

burned_copper:
However, this seems to offer a simpler solution to separating out data sent over serial - and it worked - occasionally, then not at all.

To the best of my knowledge Serial Input Basics "just works"

...R

I think its worth understanding why your code doesn't work all the time, but after that I suggest you go back to the examples already linked.

  if (Serial.find("q")) { ... } 

 else if (Serial.find("w")) { ... }

These "find" commands will block and eventually timeout, basically ping-ponging back and forth, so you don't know which "find" the hardware will be in when you happen to send your string down.

bDeters:

  if (Serial.find("q")) { ... } 

else if (Serial.find("w")) { ... }

Also, those two find() functions will act on completely different sets of incoming data. They will NOT look for a 'q' and, if not found, go back through the same data looking instead for a 'w'

...R

Thanks for the explanation, bDeters. Just for the asking, how can you know that serial.find times out and returns false? What makes it time out?

And thanks also for your second answer. I don't know why what you say is true, but I'm sure it is, so I'd better go back to stuff that "just works".

Because Serial.find("q") discards anything that isn't a "q". There may have been a "w" or something else useful but you don't know and you can't go back and recover that lost data.

(That must be a very old example. Robin's Serial Input Basics is up-to-date.)

burned_copper:
Thanks for the explanation, bDeters. Just for the asking, how can you know that serial.find times out and returns false? What makes it time out?

If the target aint in the input buffer and never arrives within a given amount of time, it returns false (usually by returning -1 or 0, but I don't know which it is for this specific function).

Thanks Morgan. Goes in my list of things I've learned today!

burned_copper:
Just for the asking, how can you know that serial.find times out and returns false? What makes it time out?

RTFM :slight_smile:

...R

I did rtfm! It said: The function returns true if target string is found, false if it times out.

I asked when and how does it time out.

Which as far as I can tell isn't in tfm!

Thanks for your excellent Serial Input basics, which I am working my way through now.

Serial.setTimeout does not explicitly mention it works for find, but I'm guessing it does through a wrapper of readBytesUntil

Sorry to keep this going, but I had to see where my ignorance would lead.

And guess what, this now works. Would you mind having a look and telling me why this may not be as good as I think it is?

The idea is I want to control two items with two parameters each. This gives me the following. What am I missing?

ITEM2: parameter1: 8 parameter2: 7
ITEM1: parameter1: 3 parameter2: 4

int q1 = 0;
int q2 = 0;
int q3 = 0;

void setup() {
  Serial.begin(9600);
}

void loop() {
  // Assumes a string in from the serial port like for example: "q5,200, 5 \n":
  if (Serial.find("q")) {
    q1 = Serial.parseInt(); // parses numeric characters before the comma
    q2 = Serial.parseInt();// parses numeric characters after the comma
    q3 = Serial.parseInt();

    switch (q1)
    case 1: {
      Serial.print("ITEM1: ");
      Serial.print("parameter1: ");
      Serial.print(q2);
      Serial.print("\tparameter2: ");
      Serial.println(q3);
      break;
    case 2:
      Serial.print("ITEM2:");
      Serial.print("\tparameter1: ");
      Serial.print(q2);
      Serial.print("\tparameter2: ");
      Serial.println(q3);
      break;
    }
  }
}

What else do you want to do with these parameters? Something useful I’m wagering!

The main issue you may see when you want the chip to do more than this one thing is that the Serial.find() and parseInt will STOP everything else from happening until it sees the “q” message or until it times out after 1 second. This means the speed at which you can do other things is gated by the speed you receive (or dont receive) these messages.

DP, is that all?

I can live with that as there will not be massive amounts of data or industrial useage.

TBH I don't know exactly what I'm making yet - I teach learners with special needs of various kinds, and I'm looking for some simple logic patterns that can produce sexy results. Also that I can understand!

This could for example drive a two wheeled robot, or some kind of crane contraption I'm thinking.

Thanks for your help!

burned_copper:
This gives me the following. What am I missing?

If I was expecting to receive

// Assumes a string in from the serial port like for example: "q5,200, 5 \n":

I would use the 3rd example in Serial Input Basics and set the start-marker as 'q' and the end-marker as '\n'

And then use the concepts in the parse example to pick out the parts.

One of the advantages of doing it like that is that it makes it possible to view the received data before it is parsed in case things are not working properly.

Another advantage is that it won't try to parse a partial message and get stuck when the rest does not arrive.

...R

burned_copper:
DP, is that all?

I can live with that as there will not be massive amounts of data or industrial useage.

TBH I don't know exactly what I'm making yet - I teach learners with special needs of various kinds, and I'm looking for some simple logic patterns that can produce sexy results. Also that I can understand!

This could for example drive a two wheeled robot, or some kind of crane contraption I'm thinking.

Thanks for your help!

A robot, as opposed to a remote control toy, usually needs to sense its environment and react. It may have a sensor that stops it running into walls, for example. If it is waiting for a 'q' with that method then it will hit the wall.

Buy one of the hackable robot chassis like the ones Pololu sells. It will cost a hundred bucks or more. But the mechanics are all sorted out for you and there is example code so your kids can have it zipping across the desk in half an hour instead of spending all semester with no movement.