1

The documentation on Arduino's website shows SoftwareSerial::read() as returning a char. (link)

The header shows that the method returns an int. (link)

The cpp definition shows SoftwareSerial::read() returning the value from a buffer array of uint8_t values. (link)

Given all of this:

  1. Why would the interface return an int instead of a uint8_t?
  2. Why do the Arduino docs show it as returning a char?
  3. Is it safe to send/receive 8-bits at a time using this library?

For (3) I'm using an HC-06 if that matters.

3
  1. You'll see in the code just above your third link that the function can return a value of -1 if there is no data present. Thus a 16-bit value is used to cover the range of 8-bit uint8_ts, plus one extra value to show 'no valid data available'.

  2. For simplicity, I guess.

  3. Yes. This is what it's designed for.

In short, for all intents and purposes, only an 8-bit value is returned, but if you were to read into an int, you couldn't differentiate between a valid and invalid value.

  • Ah awesome! The -1 value makes sense. So assuming I gate the read() invocation w/ available(), it sounds like I can read it into a uint8_t directly and work with it as a true byte. – retrohacker Jul 22 at 4:19
  • All the applications I've seen (for all stream type objects) is if(available()){read();}. The code you linked to reads the data from the ring buffer into a temporary uint8_t before returning into an int, so you're not going to lose any data that way – user85471 Jul 22 at 6:15
  • 4
    The actual answer to number 2 is "Because, as in many instances, the Arduino documentation is complete garbage." – Majenko Jul 22 at 9:58
  • 1
    I'm a bit surprised no-one mentioned the fact that it's the exact same reason why getchar() and friends return an int in standard C. – ilkkachu Jul 22 at 16:19
4

The documentation on Arduino's website shows SoftwareSerial::read() as returning a char.

No it doesn't. There is nothing in the documentation that tells you the return type. There is only an example where the returned value is assigned to a char variable. That doesn't mean that it returns a char - it just means that whatever data type it does return can be invisibly cast to a char by the compiler.

The header shows that the method returns an int.

Indeed it does. That is because that is what it returns.

The cpp definition shows SoftwareSerial::read() returning the value from a buffer array of uint8_t values.

Yes, because the valid data that it deals with is 8 bits in size. Just because it handles 8 bit "valid" data doesn't mean that that's all it ever wants to return. The "no data available" return value of -1 is obviously not something that is stored in the data. It's a status, not data.


Why would the interface return an int instead of a uint8_t?

Because a uint8_t cannot encompass all the functionality stated in the "Returns" section:

the character read, or -1 if none is available

You can't return -1 in a uint8_t.

Why do the Arduino docs show it as returning a char?

It doesn't - as I mentioned above. It makes no claims at all about the returned data type.

Is it safe to send/receive 8-bits at a time using this library?

Yes. It performs serial data transfers using 8-N-1 by default. That's 8 data bits, no parity, and one stop bit.


It's this kind of confusion with return types and bytes and integers and things that make people ask why they keep getting ÿÿÿÿÿÿ on the serial monitor. That's -1 cast as a char. I.e., "no data available" but they ignore that and treat everything returned as a char - most probably because the Arduino documentation shows an overly simplified example that ignores the possibility of a -1 being returned and treats everything as a char.

IMHO much of the Arduino documentation is somewhat sub-par and should not be taken literally - only as a rough guide for what is available. The same goes for much of their example code and projects.

  • There is hope though, as it seems the Arduino documentation is in the process of being refactored. The documentation for Serial.read(), which comes from the new GitHub-hosted ASCII doc-based repository, clearly states “Data type: int.” The documentation for SoftwareSerial is still in the old format and has presumably not been migrated yet. – Edgar Bonet Jul 22 at 10:23
  • @EdgarBonet That's promising. Maybe they'll do the same with all the bad schematics and example projects... – Majenko Jul 22 at 10:32
0

Stream declares read as returning int (look in hardware/arduino/avr/cores/arduino/Stream.h). SofrtwareSerial inherits from Stream, so they have to override that declaration, otherwise there would be two read() methods, one returning int and one returning uint8_t. Since SoftwareSerial::read() would onlyreturn an int between 0 and 255, which would fit in a uint8_t, there is no problem.

As for the Arduino docs, you get what you pay for :)

  • many words, no answer. the reason of int is to return -1 meaning "no data to return". – Juraj Jul 22 at 4:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.