Reading and parsing serial input

I’d like to read a string of incoming digits, and convert them into a usable integer. I’m not sure how (if) to do this. So far, the best I can come up with is to read the incoming bytes one at a time, and stuff each subsequent byte into an array. I use the ASCII @ (at) sign as an escape character, discarding that and any non-numerics.

So far the best I could do is. Perhaps there is a better way, hopefully someone could enlighten a beginner:

char incoming; // incoming serial data
char outbound[80];
int i=0;

void setup() {
  Serial.begin(9600);
  Serial.println("init");
}

void loop() {

  i=0; // reset the array index

while (Serial.available()) {
  incoming = Serial.read();  
  if (incoming == 64) break; // escape character is @ 
  if ((incoming < 48) or (incoming > 57)) break; // discard non-numerics
  outbound[i]=incoming; //copy the serial byte to the array
  i++; // increase the array index
  Serial.print(i);
  Serial.println(incoming);
  }
  
  if (i !=0) Serial.println(outbound); //if the array is not zero, there is data
  
}

Which doesn’t work the way I want. If my next string of digits contains less than the prior string, the array still contains the old data:

init
19 ← type in 987; the numbers 1, 2 and 3 are the index i and the 9, 8 and 7 are the actual digits
28
37
987 ← far so good
11 ← type in 10; the numbers 1 and 2 are the index i and the 1 and 0 are the actual digits
20
107 ← oops, leftover data

Hey azog–

You almost got it. In C, a string is terminated by a 0. Serial.println prints all characters of the string until it reaches the 0. When you filled up your buffer with ‘9’, ‘8’, ‘7’, the ‘7’ was still there the second time around and was therefore printed. There are any number of ways to correct this; one is:

if (i != 0)
{
  [b]outbound[i] = 0; // terminating character[/b] <- add this line
  Serial.println(outbound);
}

Another suggestion for readability is to change the constants in your code from their numeric to equivalent character values. These have the same value but are much more readable in this context. For example, instead of

if (incoming == 64) break; // escape character is @ 
  if ((incoming < 48) or (incoming > 57)) break; // discard non-numerics

use

 if (incoming == '@') break; // escape character is @ 
  if ((incoming < '0') or (incoming > '9')) break; // discard non-numerics

Best,

Mikal

Hi Mikal,

Thank you for the timely and courteous reply. Your suggestion did the trick!