Using While loop correctly...

Hello, basic problem (I assume since I run into it every damn time I try to learn this stuff…)

I want to trigger loops with serial commands
e.g. I send “s” and it loops until I CHANGE that serial command,

What it does, is loop once and exit (Serial.read returns a blank space and ends my loop?)

or if I tweak it slightly, it never checks for the while condition again and just runs forever :frowning:

#include <Servo.h>   //PLZ dont whine about formatting the crap up top that works fine
Servo servo_9;Servo servo_10;Servo servo_8;Servo servo_7;
void setup()
{Serial.begin(19200); servo_9.attach(9);servo_10.attach(10);servo_8.attach(8);servo_7.attach(7);
servo_9.write(90);servo_10.write(90);servo_8.write(90);servo_7.write(90);
  delay(1000);   Serial.println("1st Boot or RESET caused");
  }   //ONE paragraph of code is a LOT easier to quickfix than 5 pgs of empty brackets

void loop()
{ if (Serial.available() > 0) {
    char ch = Serial.read();  //read incoming byte (How do we read a command string from processing?)

   
   while (ch=='s'){      
    Serial.println(ch);
    
     servo_9.write(0);
  servo_10.write(0);
  delay(650);
  servo_9.write(180);
  servo_10.write(180);
  delay(650);
  
   Serial.println("end of S");   
   if (Serial.available() > 0) { //once ANY NEW SERIAL DATA, END WHILE LOOP
      ch = Serial.read();       Serial.println(ch);
    break;    
   }
   } 
 


  }}

Serial available returns a blank space

Nope, try again.

Please use the autoformat tool on code before posting.

(There was a question mark at the end of that sentence :p)

I think serial.read returns a blank space because if I add another read and then Serial.println(ch);
it spews a blank line or two, implying it read.serial and found a space rather than a char?

(the same Code after auto format tool)

//servos MUST have their own power source, if run off arduino, they WILL cause resets

#include <Servo.h>   //SOLO LINE
Servo servo_9; Servo servo_10; Servo servo_8; Servo servo_7;
void setup()
{ Serial.begin(19200); servo_9.attach(9); servo_10.attach(10); servo_8.attach(8); servo_7.attach(7);
  servo_9.write(90); servo_10.write(90); servo_8.write(90); servo_7.write(90);
  delay(1000);   Serial.println("1st Boot or RESET caused");
}
void loop()
{ if (Serial.available() > 0) {
    char ch = Serial.read();  //read incoming byte (How do we read a command string from processing?)


    while (ch == 's') {   //while it's S  OR blank
      Serial.println(ch);

      servo_9.write(0);
      servo_10.write(0);
      delay(650);
      servo_9.write(180);
      servo_10.write(180);
      delay(650);

      Serial.println("end of S");
      if (Serial.read() > 0) {
        break;
      }
    }

  }



}
}

MOF, There! Bare-bones code so it doesn’t get picked apart like every time I ask for help after hours of research and trial and error just to get:
“Did you read blink without delay?”

void setup()
{
}
void loop()
{ if (Serial.available() > 0) {
    char ch = Serial.read();  //read incoming byte (How do we read a command string from processing?)

    while (ch == 's') {   //while it's S  OR blank
      Serial.println(ch);

      delay(650);


      Serial.println("end of S");
      if (Serial.read() > 0) {
        break;
      }
    }

  }



}

Serial monitor by default sends two extra characters: '\r' and '\n' when you hit Enter.

Jack777:
MOF, There! Bare-bones code so it doesn't get picked apart like every time I ask for help after hours of research and trial and error just to get:
"Did you read blink without delay?"

...

while (ch == 's') {  //while it's S  OR blank
      Serial.println(ch);

delay(650);

}

Apparently not.

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data.

...R

IN addition to reading Robin2's excellent tutorial, you need to separate the reading of serial data from using the last value(s) read. The simplest way is with a function to read data, a function to process the data, and a function to use the latest serial data.

void loop()
{
   getNewData();
   if(newData)
   {
      parseNewData();
   }

   useTheData();
}

On every pass through loop(), there may, or may not be serial data to read. On every pass through loop(), the serial data that was read may, or may not, have completed a packet, so it may, or may not need parsing.

On every pass through loop(), there WILL be data to use. So, use it.