I've got an RN-XV wifi module in an Xbee shield, and I've created a winsock client on my computer communicating with my arduino. I've noticed something odd though, why is the Serial.read function returning a signed integer when the data is clearly a single byte? Does it try to preserve the signed status across the byte change or the bit pattern and add an empty byte? IE:
will it turn a received 1010 0100 (-92) into 1111 1111 1010 0100 (-92 in 2 bytes), or will it turn it into 0000 0000 1010 0100 (+164 in 2 bytes)?
Also, is analogWrite designed to take by value or by bit pattern? For example, if I give it a char with a value of 1010 0100 (-92), will it ignore the signed and give it the +164? Or try to do something with the 92? Possibly clamp it at 0?
AWOL:
Did you read the documentation about Serial.read?
You really should, before declaring 'nonsense'
That's a rather rude post, and slightly hypocritical considering the documentation answers none of the questions mentioned in my post, unless you are not referring to Serial.read() - Arduino Reference (in which case, what should I be reading other than this), all that page states is that it is indeed grabbing a single byte of data and storing it in a 2 byte signed integer, and nothing about why it would store a single byte in 2 bytes of memory etc (see my post)
I meant replying to say I just hadn't read the documentation, when if you'd read my post, the documentation is what I'd found unclear. It's pretentious to say the least, clearly I just wanted some clarification on how it treated the transfer of bits between the two datatypes and why it was chosen to return a datatype twice the size of the data it's receiving. I honestly don't know why you thought I was referring to the documentation that was rude.
Elspin:
Does it try to preserve the signed status across the byte change or the bit pattern and add an empty byte? IE:
will it turn a received 1010 0100 (-92) into 1111 1111 1010 0100 (-92 in 2 bytes), or will it turn it into 0000 0000 1010 0100 (+164 in 2 bytes)?
Also, is analogWrite designed to take by value or by bit pattern? For example, if I give it a char with a value of 1010 0100 (-92), will it ignore the signed and give it the +164? Or try to do something with the 92? Possibly clamp it at 0?
In case you somehow missed it, here is the question again. If you don't know the answer, perhaps someone else does. I can just test this I suppose but I was under the impression that this would have been a quick and easy question.
0xA4 is a single byte value, serial.read responds with a two byte signed integer. That is the question, if it would return 0x00A4 or 0xFFA4 to preserve the signed bit.
**Edit Note:Replaced 0x80A4 with 0xFFA4, 0x80A4 was a typo.
Well the questions essentially over, aside from me still wondering why they chose to set the return type of a 1 byte value to a 2 byte integer, but for the purpose of clarification for anyone reading this thread: the value 0xA4 (if you are treating the data as signed, which is the default in C/C++) is a negative value (which can be determined from the highest bit). You can obtain what it means in positive terms by doing the two's compliment. I didn't mean 0x80A4 by the way, I meant 0xFFA4, it was a typo.
If you want to set two variable types equal, say a signed character to a signed integer - you can't just take the lower half and copy it in, ie copying a signed char into an int:
char: 0xA4 (negative)
int:0x00A4 (this would now be positive, incorrect equating)
You also need to set the proper bits in the upper half to keep the signed state:
int:0xFFA4.
C++ does this automatically, but my question involved whether or not arduino's serial library does this. Here's an example program to demonstrate what I am talking about.
#include <iostream>
#include <conio.h>
using namespace std;
int main ()
{
char test = -64;
signed int seven = test;
std::cout << "The integer is:" << seven << "\n";
getch();
return 0;
}
The output will be -64, proving that C++ is padding the signed integer with F's.
OP - you're overthinking this - the value on the wire is an unsigned byte from 0-255. The problem is that if you invoke Serial.read, there may be nothing to receive, so it returns a signed int so that you can distinguish between nothing there (-1) and the 0-255 data.
wildbill:
OP - you're overthinking this - the value on the wire is an unsigned byte from 0-255. The problem is that if you invoke Serial.read, there may be nothing to receive, so it returns a signed int so that you can distinguish between nothing there (-1) and the 0-255 data.
I know, I completely understand this (why is it no one thinks that maybe the poster understands, he just disagrees?). I Just figure that seeing as we have a Serial.available that the -1 functionality is slightly redundant and it would be more efficient to remove that case and have it return a char. Same answer to AWOL.
AWOL:
There was nothing in your original post to suggest that you did understand why a signed value would be needed - you didn't mention 'available.
That's exactly what I mean ... despite a function existing that meant the -1 return value was not really necessary, you assumed that I had just not read the documentation and didn't understand anything. Can you not see how that's a bit silly? There's only like 6 functions in the library, of course I know it's there. It's even mentioned in the same documentation page that read is on.
returning (int)-1 for "no data" when the data size is known to be smaller than an int maintains compatibility with about a gazillion "getc()" like calls from other operating environments, going back to the dawn of time.
I Just figure that seeing as we have a Serial.available that the -1 functionality is slightly redundant and it would be more efficient to remove that case and have it return a char.
The problem with this approach is that not everyone uses Serial.available() to determine that there really is some data to read. Therefore, the Serial.read() function needs some way to say "Hey, there's nothing here!".
On a PC, Serial.read() could be designed to throw an exception if there were no data to read. On the Arduino, that isn't possible.