Serial.parseInt() inputs in FOR loop

Hi,

Thanks ahead of time for any and all asssitance!!!

I'm trying to capture 10 Terminal inputs (int) into an Array.

ISSUE: Each time enter one int (single or multiple digits) and press enter the Serial.parseInt() appears to go through TWO cycles... it appears to read more than one input

What could be causing this?

Code:

#include <Streaming.h>
  String termtext;
  int i;
  int SensorLimits[] = {
   1,2,3,4,5,6,7,8,9,10};                   //ARRAY to hold 10 int's

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

void loop() {
  if(Serial.available() > 0)  {                               //looks for Serial input
    String termtext = Serial.readStringUntil('\n');     
    if(termtext == "edit"){                                   //checks if input is correct
      Serial << "ready to accept new inputs" << endl;
      for (i = 1; i < 11; i++) {
        Serial << "Input for Sensor " << i << "?" << endl;    //prompt for input
        while (Serial.available() == 0) {}                    //Stops program to wait for user input
        SensorLimits[i] = Serial.parseInt();                  //Reads user input into array
      } 
    }
  }
  printSensorlimits ();
  while (Serial.available()==0); {}  
}

void printSensorlimits () {
  for (i = 0; i < 10; i++) {
    Serial <<"Value for Sensor " << i << " = "<< SensorLimits[i] << endl;             //Prompt User for input
  }
  Serial << endl;
}

TERMINAL OUTPUT AFTER entering one int into the terminal
(It should be prompting for Sensor 2 input and not Sensor 3)

ready to accept new inputs
Input for Sensor 1?
Input for Sensor 2?
Input for Sensor 3?

well... this seems to work...

SensorLimits = (Serial.readStringUntil('\n').toInt());

TERMINAL OUTPUT AFTER entering one int into the terminal
(It should be prompting for Sensor 2 input and not Sensor 3)

The Serial monitor is set for NL & CR.

Set the monitor for no line ending and the original program works.

cattledog:
The Serial monitor is set for NL & CR.

Set the monitor for no line ending and the original program works.

Thanks! I didn't think of changing the terminal parameters. I figured there was a way to flush whatever was left over after the parseInt. I tried Serial.flush(); but it didn't work.

Thanks again!!!

Serial.flush() only flushes OUTPUT (to make sure the output buffer is all sent).

To flush the input and get ONE integer:

  while (Serial.available()) Serial.read(); // Throw away anything in the input buffer
  while (!Serial.available()); // Wait for another character to arrive
  int input = Serial.parseInt();  // Accept the next set of digits.

Thank you John! That helps.

SensorLimits = (Serial.readStringUntil('\n').toInt());

For future reference, that line of code has 2 problems in terms of writing good, robust and responsive code. First is the use of the String class. Unless used with care, the String class can cause memory fragmentation (with the subsequent hard to track down errors) and the String class uses a lot of precious SRAM. Another problem is that the readStringUntil() function is a blocking function. Once called that function will sit and wait till the '\n' comes in (or the function times out) to the exclusion of all other processes. It would be better to use the methods in the serial input basics tutorial to read the data as it arrives into a null terminated character array (string).

For future reference, that line of code has 2 problems in terms of writing good, robust and responsive code.

The code assumes that the string will be the string representation of an int. Not a good idea.

The code assigns the single value to a variable with a plural name. Not a good idea.

So, that one line of code has FOUR problems.

groundFungus:

SensorLimits = (Serial.readStringUntil('\n').toInt());

For future reference, that line of code has 2 problems in terms of writing good, robust and responsive code. First is the use of the String class. Unless used with care, the String class can cause memory fragmentation (with the subsequent hard to track down errors) and the String class uses a lot of precious SRAM. Another problem is that the readStringUntil() function is a blocking function. Once called that function will sit and wait till the '\n' comes in (or the function times out) to the exclusion of all other processes. It would be better to use the methods in the serial input basics tutorial to read the data as it arrives into a null terminated character array (string).

The code is setup using a Request/Reply method to simplify the inputting of new parameters by the User. This was first done mainly for testing and development benefit. I like your suggestion because it would allow for the program to be dynamically responsive to new parameters being inputted while not being hostage to the process.

I've looked over the Serial tutorial a few times and might need more assistance though!

My initial concern is figuring out how to identify WHAT parameter the user input is meant to change? Would the Input need a unique prefix? I'm thinking ahead to a BT app for the phone where the User can invoke a new Parameter as desired. Just some planning ideas.

What do you think?

I've looked over the Serial tutorial a few times and might need more assistance though!

As well as the regular members who are familiar with the methods in the tutorial the author of that tutorial, Robin2, is a frequent user of these forums if you have questions.

PaulS:
The code assumes that the string will be the string representation of an int. Not a good idea.

The code assigns the single value to a variable with a plural name. Not a good idea.

So, that one line of code has FOUR problems.

Agreed on the first point.

Can you help me understand the second point about variable names shouldn't be 'plural'?

Can you help me understand the second point about variable names shouldn't be 'plural'?

Do you know what plural means? Vs. singular, that is?

A scalar variable can store a single value, or ONE sensor limit. An array can store multiple values, or the upper and lower limits of a sensor.

pin = 4; // makes sense
pins = 4; // does not.

My initial concern is figuring out how to identify WHAT parameter the user input is meant to change? Would the Input need a unique prefix? I'm thinking ahead to a BT app for the phone where the User can invoke a new Parameter as desired. Just some planning ideas.

I would send a packet containing a parameter, value pair. Something like <G,5.5> could mean increase gain by 5.5. The serial input basics example #5 shows how to read and parse a packet like that.

PaulS:
Do you know what plural means? Vs. singular, that is?

A scalar variable can store a single value, or ONE sensor limit. An array can store multiple values, or the upper and lower limits of a sensor.

pin = 4; // makes sense

pins = 4; // does not.

Yes. I know the difference between 'plural' and 'singular'... (not sure what gave you the impression from my writing that I wouldn't.)

The variable name was (cut-paste from project code for the purpose of this post) for an ARRAY... that's something that holds more than one piece of information.

PaulS:
So, that one line of code has FOUR problems.

That code of line suffers from another problem -- the identifier/variable 'SensorLimits' should be written as 'sensorLimits' as the convention/style of Arduino says: if the variable is formed out-of-many words (a compound word) then use small letters for the first word and capital letter only for the first characters of the remaining words. For example: Number Of Element ----> numberOfElement.

Thanks for the 'variable' info GolamMostafa. I'll admit being weak on that discipline...