problem receiving serial data into an array

Hi,

I am using this code to load some fields received from the serial port into an array.
Now instead of receiving 5 fields i receive a random number of fields from 1 to 5 and as such the data also goes to random positions on the matrix, hence useless.

Any ideas what i have wrong here?

const int NUMBER_OF_FIELDS = 5; // how many space-separated fields we expect
int fieldIndex = 0; // the current field being received
int values[NUMBER_OF_FIELDS]; // array holding values for all the fields

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

void loop()
{
 if( Serial.available())
      {
      char ch = Serial.read();
      if(ch >= '0' && ch <= '9') // is this an ascii digit between 0 and 9?
      {
      // yes, accumulate the value
      values[fieldIndex] = (values[fieldIndex] * 10) + (ch - '0'); 
      }
      else if (ch == (" ") ) // space is our separator, so move on to the next field
      {
      [b]if(fieldIndex < NUMBER_OF_FIELDS-1)
      fieldIndex++; // increment field index[/b] // error is likelly here
      }
      else
      {
      // any character not a digit or space ends the acquisition of fields
      // in this example it's the newline character sent by the Serial Monitor
      
      tft.setTextSize(2);
      tft.setCursor(50, 120);
      tft.print( fieldIndex +1);
      tft.println(" fields received:");
      for(int i=0; i <= fieldIndex; i++)
      {
      tft.println(values[i]);
      values[i] = 0; // set the values to zero, ready for the next message
      }
      fieldIndex = 0; // ready to start over
      }
      }
}

Your comment claims the fields are comma separated yet the code looks for a space separator. Can you post sample input and output?

Changed the comments.

This is the line that looks for a space

else if (ch == (" ") ) // space is our separator, so move on to the next field

Any difference if you change to this?

else if (ch == ' ')

EDIT made the change and it tests OK (having changed TFT to Serial)

Hackscribble:
Any difference if you change to this?

else if (ch == ' ')

EDIT made the change and it tests OK (having changed TFT to Serial)

Same thing happens.

I have a few decimal values (10.69). I am suspecting the program is jumping out of the loop when it receives the “dot”

Im going to change this

if(ch >= '0' && ch <= '9') // is this an ascii digit between 0 and 9?

with this

if(ch >= '0' && ch <= '9' || ch == '.') // is this an ascii digit between 0 and 9 or a dot?

Ah, you did not say you were inputting floats :)

Your new conditional needs to OR the dot character rather than AND it.

But even if it accepts the dot character, your calculation of "ten times current value plus new value" won't work as it stands.

And your values array is declared as int.

This thread has code for reading different variable types from Serial.

http://forum.arduino.cc/index.php?topic=236162.0

Hackscribble: Ah, you did not say you were inputting floats :)

Good point, let me start my array as float

Hackscribble: Your new conditional needs to OR the dot character rather than AND it.

You've beat me into that one ;) I was just changing the code!

No Change.

In fact, I didnt want to start the array as float. If possible i would rather ignore the dot from the serial port and have an integer. Example, instead of 23.98 I could receive 2398.

Changing to float yeld the received results as xx.xx. but hasnt solved my problem

This is what i send 420 15 1023 545 565 (/CR)

This is what i receive 1 fields received 420

1fields received 15

1fields received 1023 and so on...

Ive found the problem.

Aparently if I write

if(ch >= '0' && ch <= '9' || ch =='.') // is this an ascii digit between 0 and 9 or a dot?

I get all sorts of strange values on the data received

for example

128 - received 128.00
128.98 - received 1278983.00
65.35 - received 55835.00

however if I write

if(ch >= '0' && ch <= '9') // is this an ascii digit between 0 and 9?

the dot acts as /CR so the device prints whatever its got UP TO the decimal point and starts again

Any advice?

instead of 23.98 I could receive 2398.

Go back to previous code which worked for integers, with value array declared as integer.

Then add another else if branch to your if statement to ignore the dot character but not terminate the value

else if (ch == '.')
{
    // do nothing
}
else
{
    // your existing branch to display value and reset variables
    ...

Hackscribble: Go back to previous code which worked for integers, with value array declared as integer.

Then add another else if branch to your if statement to ignore the dot character but not terminate the value

else if (ch == '.')
{
    // do nothing
}

Tried that already. Prints any digit received. Example

420 510...

1 Field received 4

1Field received 2

1Field received 0

...

Any way i could modify the textFinder library to work with spaces instead of commas?

Tried that already. Prints any digit received.

Please post your latest code.

Hackscribble,

Thank you very much for taking the time.

I decided it would be best to just use the textFinder function and apparently it does do what i need.

For those looking to do the same here’s an example of the code (I changed the tft to serial)

#include <TextFinder.h>

TextFinder finder(Serial);
const int NUMBER_OF_FIELDS = 5; // how many comma-separated fields we expec
int fieldIndex = 0; // the current field being received
float values[NUMBER_OF_FIELDS]; // array holding values for all the fields

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

void loop()
{
  for(fieldIndex = 0; fieldIndex < 5; fieldIndex ++)
{
values[fieldIndex] = finder.getFloat(); // get a numeric value
}

Serial.print(fieldIndex);
Serial.println(" fields received:");
for(int i=0; i < fieldIndex; i++)
{
Serial.println(values[i]);
}
fieldIndex = 0; // ready to start over
}

and here is a link I used as reference to get the floats working (works fine without them too, simply ignores anything after the decimal point!)