serial read

I’m trying to make a function with parameter, that when I send ‘u’ as serial input the loop waits me until I send a number (I will always send a positive number) then it will call the function (called u) and adds the number as parameter then the function will output the (parameter,parameter-1, …, 0).
I wrote this code but it gives me a crazy output !!!
could anyone help me?

char seriall;
int v;

void setup() {
  Serial.begin(38400);

}

void loop() {
  if (Serial.available() > 0) {
   seriall = Serial.read();
   
    if(seriall =='u'){
      v=0;
      while (true){
        
        v=Serial.read();
        if(v>0){
        break;
        }
      }
      u(v);
      }
  }
}

void u(int x){
  for (int i=0;i<x;i++){
Serial.println(i+1);
  }
  Serial.println("");

}

For example this is the output when I send: u then u5 (BTW I’m sure that the baud rate is correct in the monitor)

dd
d





u“¯
“¯
¯


dd
d


5

uˆ³
ˆ³
³


×·
×·
·






è







Å

Ä

À

Á

Â

Æ


u
u5

u
u5

 "u
u5

)+u
u5

3u
u5

u
u5


u5

u5

5

When you send u, the program waits for the next byte to arrive, and then assumes that the byte is a meaning integer value. When you then send u5, 'u' has a value of 117, so that is the value passed to u(). I can't imagine what you expect that function to do with that value.

What are you using to send the serial data to the Arduino? If you are using the Serial Monitor app, what line ending do you have selected?

thanks dear for reply,
when I send u and then for example send 5 I want to the code to call the function u(5); then the function outputs

1
2
3
4
5

could you correct my code mistakes.
regards,,

One of the changes you could make is to this line if (Serial.available() > 0).

The change I'd make is if (Serial.available() >= 1). With that change you can be sure that a complete byte of data is received before trying to retrieve it.

bool bRcveDone = false;

String sPi;

void setup()
{
 sPi.reserve(50);

} // setup()


void loop()
{
  char chrOne;

if (Serial2.available() >= 1)
  {
    while ( Serial2.available() )
    {
      chrOne = Serial2.read();
      if ( (chrOne != '\n') )
      {
        //Serial.println(sPi);
        sPi.concat( chrOne );
        // Serial.println(sPi + " char" );
        digitalWrite( 40, LOW );
      } // if ( (chrOne != '\n') )
      else
        //      if ( (chrOne == '\n') )
      {
        bRcveDone = true;
        // Serial.println( "bRcveDone set true" );
        break;
      } // if ( (chrOne != '\n') ) else
    } // while ( Serial2.available() )
  }  //  serial available
  }

.

When the function is done put bool bRcveDone = false; and only try to call a function when bool bRcveDone == true

when I send u and then for example send 5

The point is that THAT is NOT what you are sending. You are sending ‘u’ and ‘5’. ‘5’ is NOT the same as 5.

You obviously know how to use Serial.print(). So, use it more, with identification of what you are printing. What is actually in v?

Where are the answers to the questions I asked?

With that change you can be sure that a complete byte of data is received before trying to retrieve it.

Nonsense. The data in the serial buffer can only be complete bytes.

Greater than 0 and greater than or equal 1 are the same thing.

Oh sorry I forget to answer the second question,
I'm using the arduino IDE serial monitor.
aha I got your idea, then how to read the number as digit not character?

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

And there is this clever idea if you just want to check for single characters.

...R

then how to read the number as digit not character?

Look at an ASCII table. The relationship between the digit n and the character 'n' is a constant.

   int nAsInt = nAsChar - '0';

Thank you all.
I will do your suggestions.

Idahowalker:
One of the changes you could make is to this line if (Serial.available() > 0).

The change I'd make is if (Serial.available() >= 1). With that change you can be sure that a complete byte of data is received before trying to retrieve it.

Serial.available() is defined to return integers. It can never return 0.5. So there is no difference between the two lines.

Additionally, the Serial hardware does not let you know if half a byte has been received. It only allows you to see the byte once it is complete.

MorganS:
Serial.available() is defined to return integers. It can never return 0.5. So there is no difference between the two lines.

Additionally, the Serial hardware does not let you know if half a byte has been received. It only allows you to see the byte once it is complete.

I completely understand the theory behind the Serial.Available() 0 thingy and on a Arduino Uno and a Pro Mini and a Mega, I never once had an issue with using the Serial.Available() 0 thingy. Then I ran into a project I did on the Due and the Serial.Available() 0 thingy did not work 100%. I changed to using the Serial.Available() 1 thingy and that does the 100% job. I changed my Uno, Mini Pro, and Mega projects to use theSerial.Available() 1 and, whiles they worked fine before they work fine now. And the Due works 100%.

Thus there is a theory to the whole Serial.Available() thingy but in practice, it can fail. So when the OP posted some prints of blank lines and other erroneous prints, I made choice to post the Serial.Available() 1 thingy.

And whiles the documentation reads one way, the Due, for me, has proven the documentation wrong in reality.

Well, the Due is the read-headed step-child of the family. On initial release it had no serial buffers at all. That did get fixed more than 5 years ago though.

Do you have any example code you could share which shows the issue?

MorganS:
Well, the Due is the read-headed step-child of the family.

Or red-headed...