How to use Serial.read in loop function

I am trying to trigger an if condition by reading serial port. Its not working. Where am I going wrong? See below my lines of code. I am writing to serial port by typing 1 in serial monitor and pressing enter.

void loop() 
{
  buttonState1 = digitalRead(buttonPin1);
  if (((buttonState1 == HIGH) || (Serial.available() && Serial.read() == 1) ) || (OperationStarted == true))
  {
    /*stuff happens*/
  }
}

Try

 (Serial.available() && Serial.read() == "1") 

and select No Line Ending at the bottom of the monitor

1 Like

Or, try
(Serial.available() && Serial.read() == '1')

you're looking at the difference between the integer value 1 in your first comparison, and the int returned by Serial.read(), which will be the ASCII character 1, value 0x31, because that's what you're typing.

1 Like

This works - tested.

void loop() 
{
  buttonState1 = digitalRead(buttonPin1);
  if (((buttonState1 == HIGH) || (Serial.available() && Serial.parseInt() == 1) ) || (OperationStarted == true))
  {
    /*stuff happens*/
  }
}
1 Like

This is a democode that goes beyond comparising a single character.
It uses the SafeString-Library which can be installed with the library-manager of the arduino-ide.

The demo-code shows how commands build from multiple characters can be used to execute actions.

// SafeStringReader_Cmds.ino
//
// Example of NON-Blocking read commmands from the Arduino Monitor input and acts on them
// the available commands are start stop
// See the SafeStringReader_CmdsTimed.ino for an example using a struct to hold the commands and their functions
//
// Commands are delimited by space dot comma NL or CR
// If you set the Arduino Monitor to No line ending then the last command will be ignored until it is terminated by a space or ,
//  Use the settings Newline or Carrage Return or Both NL & CR
//
// These commands can be picked out of a line of user input
// start  stop
// The input line can be as long as you like 100's of Kb long, but only two small buffers need to parse the commands
//
// download and install the SafeString library from
// www.forward.com.au/pfod/ArduinoProgramming/SafeString/index.html
#include "SafeStringReader.h"

// create an sfReader instance of SafeStringReader class
// that will handle commands upto 5 chars long
// delimited by space, comma or CarrageReturn or NewLine
// the createSafeStringReader( ) macro creates both the SafeStringReader (sfReader) and the necessary SafeString that holds input chars until a delimiter is found
// args are (ReaderInstanceName, expectedMaxCmdLength, delimiters)
createSafeStringReader(sfReader, 5, " ,\r\n");

bool running = true;
unsigned long loopCounter = 0;

void setup() {
  Serial.begin(115200);
  Serial.println( F("Setup-Start") );

  Serial.println();
  Serial.println( F(" Commands are 'stop' 'start'") );
  Serial.println( F(" Set the Arduino IDE monitor to Newline, or Carriage return or Both NL & CR") );
  Serial.println( F(" See the SafeStringReader_CmdsTimed.ino for an example using a struct to hold the commands and their functions.") );

  SafeString::setOutput(Serial); // enable error messages and SafeString.debug() output to be sent to Serial
  if (running) {
    Serial.println( F(" Counter Started"));
  }
  sfReader.connect(Serial); // where SafeStringReader will read from
  sfReader.echoOn(); // echo back all input, by default echo is off
}

void handleStartCmd() {
  running = true;  
  Serial.println(); 
  Serial.print( F("> start at Counter:") ); 
  Serial.println(loopCounter);
}

void handleStopCmd() {
  running = false; 
  Serial.println(); 
  Serial.print( F("> stop at Counter:") ); 
  Serial.println(loopCounter);
}

void loop() {
  if (sfReader.read()) {
    if (sfReader == "start") {
      handleStartCmd();
    } 
    else if (sfReader == "stop") {
      handleStopCmd();
    } // else ignore unrecognized command
  } // else no delimited command yet

  // rest of code here is executed while the user typing in commands
  if (running) {
    loopCounter++;
    if ((loopCounter % 100000) == 0) { // print the current counter every now and again
      Serial.print(F("Counter:")); Serial.println(loopCounter);
    }
  }
}

best regards Stefan

Using the parseInt() function to read a one-digit code is not a good advice because the internal delay of the parseInt() method.

Just read the char and compare it with '1' , as @camsysca advised - it is much faster and more efficient

1 Like

And, this is also necessary, unless you build in traps for the line ending characters.

There is no reason to call Serial.available(), Serial.read() will return an integer value of -1 if no character has been received.

@camsysca this works. But I am not able to stop the process initiated (the process is printing data to serial) by the following code.

if (((buttonState1 == HIGH) || (Serial.available() && Serial.read() == '1') ) || (OperationStarted == true))
  {
    /*stuff (serial prints) happens*/
  }
else if ((Serial.read() == '0'))
  {
      /*stuff (prints to serial) is topped from happening*/
  }

Can you elaborate why this is necessary? I would be eventually communicating via a desktop application, I would like to know what additional settings I'll need to apply in that application.

@StefanL38 thanks for sharing this. So one needs to just put the /stuff happens/ part of the code here?

void handleStartCmd() {
  running = true;  
  /*stuff Happens*/
}

Your description "stuff happends" is too unprecise.

Shall the stuff happen only ONCE per serial command
or
Shall the stuff happen CONTINIOUSLY ALL THE TIME until you send a stop-command?

There is analog data being printed to serial continuously for 30-50 seconds. But I'd like to have the ability to stop it whenever I want, hence my attempt at writing stop command along with start command.

ok resolved. I should have triggered if statement in both cases, not else if.

do please clarify this

Every time that you type a '1', then hit enter, your character is followed by either a carriage return, a line feed, both, or neither, depending upon that setting.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.