I was wondering if there is an Arduino built-in function that can read hexadecimal bytes directly. For instance, the number 0x7e should by read as one single byte. Actually Serial.read(); doesn't read bytes as hexadecimal values instead, every character takes 1 byte so 0x7e would be represented as 2 bytes of ASCII values. I searched the net and haven't found any such thing, so I came up with my own function and I named it readByte(); Check it out:
Actually Serial.read(); doesn't read bytes as hexadecimal values
That's nonsense... If you send 0x7E as a byte (ie that actual number) then read will read it as a byte. If you send ascii then you need multiple reads (4 if you also sent the 0x) and parse the input - so wait until bytes arrive to read them as they come in - see Serial.available()
Yes, I have. delay(1); is so important when calling Serial.read(); multiple times. In my case, I set the serial communication rate to 9600 baud per second which's equivalent to 1.2 KB per second, so it takes less than 1 ms for the incoming byte to be read. so delay(1) just waits for the next byte..
Genius:
Yes, I have. delay(1); is so important when calling Serial.read(); multiple times. In my case, I set the serial communication rate to 9600 baud per second which's equivalent to 1.2 KB per second, so it takes less than 1 ms for the incoming byte to be read. so delay(1) just waits for the next byte..
How can you possibly know how long it will take for the next byte to arrive? It's the sending device that controls the timing, not the receiving device (your program).
When printing 0x7e in the serial monitor, Serial.read() only takes the first character which's 0 in this case. I don't understand how you would go on doing this using Serial.available() !!
Genius:
When printing 0x7e in the serial monitor, Serial.read() only takes the first character which's 0 in this case. I don't understand how you would go on doing this using Serial.available() !!
Serial.begin(9600); // This sets the data rate to 9600 baud per second..
// It's a protocol that both the transmitter and the receiver agree about
That does not specify anything about inter-character timing. When two characters are back to back, a start bit can immediately follow a stop bit. But there can be an unspecified delay between them, it could be microseconds to years. This is asynchronous communication.
Also, "baud per second" is not a valid expression.
The baud rates defines how fast bits arrive not how long the wait between two chars could be (Imagine someone typing on a keyboard, the delay between two consecutive key press is under the user control. Your program cannot assume I'll type at a constant perfect rate or send a full sentence in one go.)
If you want to deserve your pseudo, listen a bit and read what's proposed to you...
This article still doesn't solve our problem. We want the data to be stored in a SINGLE byte.. I can't find a simple way to achieve this using Serial.read(); The article is basically talking about storing it in an array..
The code that I've given you here solves the problem using Serial.read(); but not in a straight forward way!
Please first, look up the code and execute it and try to see the difference.
I don't want to just print the letters "7e" on the screen. I want to store the hexadecimal value within a single byte to make things easier when communicating with external devices.
Also, when typing on a keypad, you're allowed to wait as you wish, but when you hit enter, it sends data with the specified baud rate.
And if I enter 7 +enter and then e +enter instead of 7e +enter...
Your program fails ?
You could study the code of the ParseInt() method of the Stream class to get a sense of how this is done (and see why it's slow)
// returns the first valid (long) integer value from the current position.
// lookahead determines how parseInt looks ahead in the stream.
// See LookaheadMode enumeration at the top of the file.
// Lookahead is terminated by the first character that is not a valid part of an integer.
// Once parsing commences, 'ignore' will be skipped in the stream.
long Stream::parseInt(LookaheadMode lookahead, char ignore)
{
bool isNegative = false;
long value = 0;
int c;
c = peekNextDigit(lookahead, false);
// ignore non numeric leading characters
if(c < 0)
return 0; // zero returned if timeout
do{
if(c == ignore)
; // ignore this character
else if(c == '-')
isNegative = true;
else if(c >= '0' && c <= '9') // is c a digit?
value = value * 10 + c - '0';
read(); // consume the character we got with peek
c = timedPeek();
}
while( (c >= '0' && c <= '9') || c == ignore );
if(isNegative)
value = -value;
return value;
}
And no, when you type a String only each frame (byte) is guaranteed to be sent at right baud rate but this is done byte by byte, you could be on a slow machine that takes time to retrieve the next byte (say reading a file from a slow SD card for example). Your approach is doomed and who would want a library function that only kinda work if you are lucky at 9600 bauds...
We totally get what you want to do, we try to steer you in the right direction and not do it for you... (and yes code will be required, it won't magically read the ascii and build the byte)
Basically I was designing this for a quadcopter.. so I should be sending information continuously with 9600 bps.
So this silly "enter" thing never seems to happen anyway in real communications between devices!
The ONLY way to wait for the next byte to be available is not with a delay, it's by looking into the hardware/buffer if the byte is ready to be consumed. That's what the available() function does for you (and a bit more, tells you how many are available). With wireless communication you will also find that bytes or messages get resent if not received right... so timing is unknown. Get used to handling asynchronous communication in an asynchronous way... delay is synchronous.
You have been Warned, now it's a free world, every one gets to add bugs into his code if they choose so
Good luck - don't crash your copter on people's home because of crappy coding practice and dumb engineering behavior. You are not a genius, you are a lazy stubborn weirdo (said in a gentle tone to drive you to reconsider your view and grow up)
Making progress (I promise you delay(1) will fail you over the long run. When dealing with something asynchronous, don't second guess the timing, code asynchronously)
What if I send 7E instead of 7e?
Do you know for sure that hexadecimal below Or equal to 0xF - say 0xF - will be send as 0F and not just as F ?
No I don't think this should be in the library as such or would have to be implemented as parseInt, parseFloat, handling timeout which delivers poor timing performance in many cases...
my recommendation esp. if you are flying, don't send ASCII, send the byte, will be faster and easier