Go Down

Topic: while (!Serial.available()) (Read 25914 times) previous topic - next topic

pedro_delmonde

Hi
I use while (!Serial.available()) to wait for serial input at the start of a sketch. So I can configure all my stuff before I hit the key and start the program

I would like to do this in the main loop but it doesn't work
Code: [Select]
void loop() {
  timer = micros();
  for (uint32_t x = 0; x < 19999; x++) {
    mySerial.write(0X41);
  }
  timer = micros() - timer;
  delay(1000);
  Serial.flush();
 
  Serial.println("\nSend any character to begin test: ");
  while (!Serial.available());
  Serial.print(timer);
}

It just loops ignoring the (!Serial.available()) which I hoped would make it wait until I enter more text to the serial monitor.

Does anyone know how I can do this?

Cheers

PaulS

Quote
It just loops ignoring the (!Serial.available()) which I hoped would make it wait until I enter more text to the serial monitor.
Serial.available() does not return a boolean. Stop treating it as though it does.

The Serial.flush() call waits for the outgoing serial buffer to be empty. It has NOTHING to do with the incoming serial buffer. Once you receive a character, it is ALWAYS in the buffer, waiting to be read, because you never read it.

pedro_delmonde

Thanks, I've been rushed through this so not had much time to appreciate what anything means !!!!! so serial.available() returns a !bool. great . I'll look it up thanks man big help.When your drowning I'll if I'm there with a life saver I'll remember to say "hey bro you need to swim"


Knob

-dev

Quote
Serial.available() does not return a boolean. Stop treating it as though it does.
This is not a problem.  This statement:

  while (!Serial.available()); 

...is equivalent to:

  while (Serial.available() == 0);

Although I prefer the former (it has been valid for decades), I can't object to a stylistic choice one way or another.

I do object to the suggestion that this is a problem.  The only problem was not calling Serial.read().

Cheers,
/dev
Really, I used to be /dev.  :(

GolamMostafa

#4
Apr 05, 2017, 10:29 pm Last Edit: Apr 05, 2017, 10:31 pm by GolamMostafa
Explanation of the validity of @/dev's conclusion: The only problem was not calling Serial.read().

1. Given the codes:
Code: [Select]
while(!Serial.available())   //while(Serial.available() == 0x00)
  ;

2. Because no command has yet come from Serial Monitor, the control keeps waiting around the
   given codes. There is nothing in the receive buffer except 0x00.

3. When command comes from Serial Monitor, the function Serial.available() returns a non-zero
   (0x01 = one character) value.

4. Because, the int x1 = Serial.Read() function is not included, the receiver buffer is not
   emptied.

5.  In the next iteration, the MCU still finds a character (the previous one) in the receive buffer; the
    condition of the while() loop is not satisfied; the MCU does not wait; it goes for the next
    iteration; it keeps going like that.

6. The proposition of Step-5 has been tested.
Code: [Select]
#include <SoftwareSerial.h>
 int timer, x1;
void setup()
{
  // put your setup code here, to run once:
   Serial.begin(4800);
}

void loop()
{
  timer = micros();
  for (uint32_t x = 0; x < 2; x++)
  {
    Serial.write(0X41);
  }
  timer = micros() - timer;
  delay(1000);
  Serial.flush();
 
  Serial.println("\nSend any character to begin test: ");
  while (!Serial.available())
     ;
//  x1=Serial.read();
  Serial.print(timer);
}

     
   

GolamMostafa

#5
Apr 06, 2017, 10:35 am Last Edit: Apr 06, 2017, 11:44 am by GolamMostafa
@/dev

Please make comments on the following at your convenience:

1. I have thought that:
Code: [Select]
while (Serial.available() == 0x00)
  ;


2. could be replaced by:
Code: [Select]
while (bitRead(UCSR0A, 7) !=HIGH) //Bit-7 of UCSR0A assumes LH when the receiver gets data
  ;


3. The codes of Step-2 do not work.

//----------------------------------------
4. (a)  In UART mode operation, data transfer occurs byte-by-byte (control character or ASCII). So,
         the receiver (UDR0 register) will hold only one character (data byte). If the user does not
         read the data before the arrival of the next character, it will be lost.

   (b)  The Serial.availble() function can contain a value from 0x00 - 0x40. Where is this receiver
         buffer? How does it accumulate so many data bytes? How is it related with UDR0 register of
         ATmega328?
 

-dev

Quote
Please make comments on the following...
The Serial variable is an instance of the C++ class, HardwareSerial.  It handles the hardware registers directly, sometimes in an Interrupt Service Routine (ISR).  I would never suggest direct registor manipulation, because it is not the same register name on all Arduino boards (it is not "portable").

You should read the HardwareSerial.H and CPP files, in the Arduino installation directory.  They are in a subdirectory, probably something like hardware/arduino/avr/cores/arduino.

The HardwareSerial class copies each received character from the UART register to a RAM byte array (an input buffer).  Serial.available() simply returns the number of bytes in the array (up to its size, 64).  Serial.read() removes one byte from that array and reduces the count.
Really, I used to be /dev.  :(

Go Up