Is there a way to determine if new input has come from the serial monitor?

I want to design a loop that reads a string from the serial monitor input, parses it into values and then calls functions based upon those values.

This means the functions are called all the time even if no new input comes in.

Is there a way to ignore execution of those functions unless there is a new input?

I can’t use if X != 0 because 0 can be one of the inputs.

Serial input basics

PerryBebbington:
Serial input basics

I read it and many other articles .... couldn't find the answer. I was wondering if there is a boolean True/False set every time the loop goes over the input routine and sets it to true if new input is received.

That tutorial explains what you need so if you have read it and don't understand then I don't know a better way to tell you, sorry. Maybe someone else can explain better but I can't.

Serial.available()?

I read it and many other articles … couldn’t find the answer

Maybe brush-up on comprehension skills?

Report closed NFA

cosmicone:
I read it and many other articles .... couldn't find the answer. I was wondering if there is a boolean True/False set every time the loop goes over the input routine and sets it to true if new input is received.

Yes, again, that is Serial.available(). It returns a boolean exactly as you describe.

aarg:
Yes, again, that is Serial.available(). It returns a boolean exactly as you describe.

Thank you. I am studying that.
I have a while Serial.available ()> 1 loop .... it means I'll have to put all the code that ensues inside that while loop - if they are outside, the code will run regardless of whether there is input or not. Am I correct?

Am I correct?

The beauty of Arduino is that you can determine this for yourself.

Write the code, test it and if you run into problems that you can't solve by further reading, post again.

If you do, be sure to post the new code (using code tags), along with any error messages.

cosmicone:
Thank you. I am studying that.
I have a while Serial.available ()> 1 loop .... it means I'll have to put all the code that ensues inside that while loop - if they are outside, the code will run regardless of whether there is input or not. Am I correct?

No. In order to do that, you should use an 'if' statement and allow loop() to run both the Serial 'if' block and any other "outside the block" code that's inside loop().

Never use 'while' with any conditions that don't guarantee a rapid exit, inside the loop() function. It will delay cooperative multitasking.

jremington:
The beauty of Arduino is that you can determine this for yourself.

Write the code, test it and if you run into problems that you don’t understand, post again.

If you do, post the new code, using code tags, along with any error messages.

Thank you! The whole sketch is >20K bytes so I can’t post it. Here is the relevant portion that I just modified. (Just the loop)
An array has already been defined with 6 positions.
(I have not written the functions for M3, M4, M5 and M6 yet)

void loop() {

  // Give serial input as "m1 m2 m3 m4 m5 m6 <Space> and then <Enter>"
  while (Serial.available() > 0) {
    int inChar = Serial.read();
    if (isDigit(inChar) || inChar == '-' || inChar == '.') {
      // convert the incoming byte to a char and add it to the string:
      inString += (char)inChar;
    }
    if (inChar == ' ') {
      pos[motor++] = inString.toFloat();
      inString = "";
    }
    if (inChar == '\n') {
      inString = "";
      motor = 0;
    }
delay(100);

  User_InputM1 = pos[0];
  User_InputM2 = pos[1];
  User_InputM3 = pos[2];
  User_InputM4 = pos[3];
  User_InputM5 = pos[4];
  User_InputM6 = pos[5];

 
  moveM1();
  moveM2();
    
  }

}

aarg:
No. In order to do that, you should use an 'if' statement and allow loop() to run both the Serial 'if' block and any other "outside the block" code that's inside loop().

Never use 'while' with any conditions that don't guarantee a rapid exit, inside the loop() function. It will delay cooperative multitasking.

Please explain.
Do you mean something like this?
void loop () {
if Serial.available() >0 {
Get the input and parse it
Assign values to variables
Do something with variables
}
}
Or some other way? I really appreciate your help

cosmicone:
I read it and many other articles .... couldn't find the answer. I was wondering if there is a boolean True/False set every time the loop goes over the input routine and sets it to true if new input is received.

If you look at the examples in Serial Input Basics you will see that there is a boolean variable called newData which is set to true when a new message has arrived and which is used by the other parts of the program to decide whether, for example, the received data should be printed.

That seems to me exactly the sort of thing you are looking for.

...R

Serial has a function for that: “Serial.parseFloat()”. It skips over any characters that don’t look like a ‘float’ and then gathers the characters that DO look like a ‘float’ until it hits a non-float character or no character has arrived for the timeout period (default: one second). Then it returns the value of the float.

const byte NumberOfMotors = 6;
float pos[NumberOfMotors];


void loop()
{
  if (Serial.available())
  {
    // At least one character is available to read
    for (byte motor = 0; motor < NumberOfMotors; motor++)
    {
      if (Serial.peek() == '\r')
        return;  // OUT OF SYNC!  Re-start loop().


      pos[motor] = Serial.parseFloat();
    }


    // Do stuff here to act on the new input
    
    User_InputM1 = pos[0];
    User_InputM2 = pos[1];
    User_InputM3 = pos[2];
    User_InputM4 = pos[3];
    User_InputM5 = pos[4];
    User_InputM6 = pos[5];


    moveM1();
    moveM2();
  }


  // Do stuff here that doesn't need new input


}

johnwasser:
Serial has a function for that: “Serial.parseFloat()”. It skips over any characters that don’t look like a ‘float’ and then gathers the characters that DO look like a ‘float’ until it hits a non-float character or no character has arrived for the timeout period (default: one second). Then it returns the value of the float.

const byte NumberOfMotors = 6;

float pos[NumberOfMotors];

void loop()
{
 if (Serial.available())
 {
   // At least one character is available to read
   for (byte motor = 0; motor < NumberOfMotors; motor++)
   {
     if (Serial.peek() == ‘\r’)
       return;  // OUT OF SYNC!  Re-start loop().

pos[motor] = Serial.parseFloat();
   }

// Do stuff here to act on the new input
   
   User_InputM1 = pos[0];
   User_InputM2 = pos[1];
   User_InputM3 = pos[2];
   User_InputM4 = pos[3];
   User_InputM5 = pos[4];
   User_InputM6 = pos[5];

moveM1();
   moveM2();
 }

// Do stuff here that doesn’t need new input

}



Perfect! Thank you so much. Documentation can only take one so far ... a good teacher is priceless.
I really appreciate your help.

johnwasser:
Serial has a function for that: “Serial.parseFloat()”. It skips over any characters that don’t look like a ‘float’ and then gathers the characters that DO look like a ‘float’ until it hits a non-float character or no character has arrived for the timeout period (default: one second). Then it returns the value of the float.

const byte NumberOfMotors = 6;

float pos[NumberOfMotors];

void loop()
{
  if (Serial.available())
  {
    // At least one character is available to read
    for (byte motor = 0; motor < NumberOfMotors; motor++)
    {
      if (Serial.peek() == ‘\r’)
        return;  // OUT OF SYNC!  Re-start loop().

pos[motor] = Serial.parseFloat();
    }

// Do stuff here to act on the new input
   
    User_InputM1 = pos[0];
    User_InputM2 = pos[1];
    User_InputM3 = pos[2];
    User_InputM4 = pos[3];
    User_InputM5 = pos[4];
    User_InputM6 = pos[5];

moveM1();
    moveM2();
  }

// Do stuff here that doesn’t need new input

}




I tested it and it works beautifully -- however, there is one minor issue that I cannot determine why.

I gave as input 1.1 to 6.6 to determine the parsing. It parsed them correctly and displayed them on the monitor.

However, without me doing anything, a few seconds later, it displayed 0.00 for all the inputs and then it stopped.

This is the monitor output:

1.10
2.20
3.30
4.40
5.50
6.60
0.00
0.00
0.00
0.00
0.00
0.00

Why would it do a second parse without any input and how do I stop it? 
I posted my code in another post.
const byte NumberOfMotors = 6;
float pos[NumberOfMotors];


void loop()
{
  if (Serial.available())
  {
    // At least one character is available to read
    for (byte motor = 0; motor < NumberOfMotors; motor++)
    {
      if (Serial.peek() == '\r')
        return;  // OUT OF SYNC!  Re-start loop().


      pos[motor] = Serial.parseFloat();
    }


    // Do stuff here to act on the new input
    
    User_InputM1 = pos[0];
    User_InputM2 = pos[1];
    User_InputM3 = pos[2];
    User_InputM4 = pos[3];
    User_InputM5 = pos[4];
    User_InputM6 = pos[5];


    moveM1();
    moveM2();
  }


  // Do stuff here that doesn't need new input


}

It has a bit of a problem when there are characters left after the last number. It sees them in the buffer and starts parsing floats. If a float doesn't arrive in a second, .parseFloat() will return 0.0.

One way to fix it is purge characters after the last number until a '\r' is reached:

      pos[motor] = Serial.parseFloat();
    }

// add this part:
    if (Serial.available())
    {
      char c = Serial.read();
      if (c == '\r')
        break;  // Found the end of the line so no need to purge more

      Serial.print("Skipping character: '");
      Serial.print(c);
      Serial.println("'");
    }

johnwasser:
It has a bit of a problem when there are characters left after the last number. It sees them in the buffer and starts parsing floats. If a float doesn’t arrive in a second, .parseFloat() will return 0.0.

One way to fix it is purge characters after the last number until a ‘\r’ is reached:

      pos[motor] = Serial.parseFloat();

}

// add this part:
   if (Serial.available())
   {
     char c = Serial.read();
     if (c == ‘\r’)
       break;  // Found the end of the line so no need to purge more

Serial.print(“Skipping character: '”);
     Serial.print(c);
     Serial.println("’");
   }

Where do I add it? right after

 if (Serial.available())
    {

?

cosmicone:
Where do I add it? right after

 if (Serial.available())

{


?

You add the "// add this part:" part right after the part that says:

     pos[motor] = Serial.parseFloat();
    }