Help with using Serial.Read

Hi everyone,

I'm still pretty knew to Arduino and am trying to understand the serial.read command. I have read through a lot of the information online, but still do not understand why my code doesn't work correctly. Specifically, it correctly displays in the serial monitor the ASCII value of the key that was entered. However, the if statement doesn't correctly function and any key triggers the tone. Im a at a loss on how to fix this. All advice is appreciated! Thanks!

int input=0; //input character

void setup() // Built in initialization block
{
 Serial.begin(9600); // Set data rate to 9600 bps
 
 while(input!=114) //if the r key hasnt been pressed, keep going
 {
   while(Serial.available()==0){}
   input = Serial.read();
   Serial.println(input);

   if (input=117) //if the user put u, stop the servo from moving
    {
      tone(9, 2000, 700);
    }
 }
}

void loop() 
{}

You're testing to see if the Serial object is closed, not open. Normally you would see something like:

  • while (Serial.available() > 0) {*

when you are trying to read from the serial object.

Load up the IDE and use the following menu sequence:

File --> Examples -->04. Communiactions --> ReadASCIIString

to load an example of reading an ASCII string using the Serial object.

if (input=117)

You're also setting the variable input to the value 117. There's nothing syntactically wrong with this but it doesn't do what you want.

For equality compares, use "==":

if (input == 117)

Just a bit of nitpicking, but would your code not be more readable when you actually put the letters in instead of numbers?
e.g

while(input!='r')

If you crank up the warning levels in the IDE (file -> preferences -> compiler warnings -> all), you will get a warning in the output window that indicates that there might be something wrong with your if statement (see Blackfin's comment above).

C:\Users\sterretje\AppData\Local\Temp\arduino_modified_sketch_991178\sketch_sep28a.ino: In function 'void setup()':

C:\Users\sterretje\AppData\Local\Temp\arduino_modified_sketch_991178\sketch_sep28a.ino:14:20: warning: suggest parentheses around assignment used as truth value [-Wparentheses]

     if (input = 117) //if the user put u, stop the servo from moving

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

...R

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

...R

And/or use a serial transfer library

Power_Broker:
And/or use a serial transfer library

I don't want to spend 30 minutes reading code to find out, does the library contain blocking code?

If you enter r from the InputBox of the Serial Monitor (Fig-1), what action (you say) your Arduino UNO should take.

If you enter u from the InputBox of the Serial Monitor (Fig-1), what action (you say) your Arduino UNO should take.
SerialMonitor.png
Figure-1: Serial Monitor of Arduino IDE

Remember that when you enter a character (Say: r) in the InputBox of the Serial Monitor and then click on the Send button, it is received by UNO and is saved in a FIFO type Buffer. So at the UNO side, your first job would be to check if any character has arrived in the FIFO Buffer and then read/store it in a char type variable. To do this task, I usually execute the following codes:

void loop()
{
   byte n =Serial.available();
   if (n != 0)                          //there is at least one character in the FIFO Buffer
   {
        char x = Serial.read();   //x contains r (ASCII code of r = 0x72 = 114) if r was entered
        if( x == 'r')                   //r has come from the InputBox
        {
             //do this
             Serial.print(x);         //received character goes back to OutputBox of Serial Monitor 
        }
        if(x == 'u')                   //u has arrived from the InputBox
        {
             //do this
        }
   }
}

SerialMonitor.png

GoForSmoke:
I don't want to spend 30 minutes reading code to find out, does the library contain blocking code?

Absolutely not :smiley:

I wrote it for communication between a custom Arduino hand controller and Arduino RC airplane, so speed, reliability, and "non-blockingness" was integral to the library design

Here is how I handle incoming data as proof:

/*
 int8_t SerialTransfer::available()
 Description:
 ------------
  * Parses incoming serial data, analyzes packet contents,
  and reports errors/successful packet reception
 Inputs:
 -------
  * void
 Return:
 -------
  * int8_t - Error code
*/
int8_t SerialTransfer::available()
{
	if (port->available())
	{
		while (port->available())
		{
			uint8_t recChar = port->read();

			switch (state)
			{
				case find_start_byte://///////////////////////////////////////
				{
					if (recChar == START_BYTE)
						state = find_overhead_byte;
					break;
				}

				case find_overhead_byte://////////////////////////////////////
				{
					recOverheadByte = recChar;
					state = find_payload_len;
					break;
				}

				case find_payload_len:////////////////////////////////////////
				{
					if (recChar <= MAX_PACKET_SIZE)
					{
						bytesToRec = recChar;
						state = find_payload;
					}
					else
					{
						state = find_start_byte;
						return PAYLOAD_ERROR;
					}
					break;
				}

				case find_payload:////////////////////////////////////////////
				{
					if (payIndex < bytesToRec)
					{
						rxBuff[payIndex] = recChar;
						payIndex++;

						if (payIndex == bytesToRec)
						{
							payIndex = 0;
							state = find_checksum;
						}
					}
					break;
				}

				case find_checksum:///////////////////////////////////////////
				{
					uint8_t calcChecksum = findChecksum(rxBuff, bytesToRec);

					if (calcChecksum == recChar)
						state = find_end_byte;
					else
					{
						state = find_start_byte;
						return CHECKSUM_ERROR;
					}
				
					break;
				}

				case find_end_byte:///////////////////////////////////////////
				{
					state = find_start_byte;

					if (recChar == STOP_BYTE)
					{
						unpackPacket(rxBuff, bytesToRec);
						return NEW_DATA;
					}

					return STOP_BYTE_ERROR;
					break;
				}

				default:
				{
					Serial.print("ERROR: Undefined state: ");
					Serial.println(state);
					state = find_start_byte;
					break;
				}
			}
		}
	}
	else
		return NO_DATA;

	return CONTINUE;
}

Very good and I see that it will work with blocking code due to that while available loop even though -it- does not block. My stuff is not so robust, it expects sketches to stay ahead of every available char.