I'm working on an application using the Hobbytronics USB Host board that translates a USB byte stream to an equivalent ASCII byte stream. So, for instance, you plug your USB keyboard into the Hobbytronics board, hit the F1 key, and the board outputs 0x1B, 0x3B on it's serial port.
For the special case of control keys, e.g. CTRL-A, the board puts out a null (0x00) followed by the appropriate byte, e.g. 0x01. So if you hit CTRL-A, the board sends 0x00, 0x01.
My question is, what does my Arduino do with the first byte, the null, when I do a Serial.read()?
It seems as though the Serial.read() simply discards the null and reads the next byte immediately, without the need for a second call. If that is the case, is there any way to alter that behavior?
A null character is a perfectly valid character to transmit and read over Serial. Why do you think Serial.read() skips over it? Please post your code that demonstrates this behavior.
Perhaps I'm misinterpreting what I'm seeing on the serial monitor? If my arduino board reads the null and then writes it, what would I see on the serial monitor...nothing? So if I hit CTRL-A, I would get 0x00, 0x01, but all I would see is "Control-A" because the null was written but produced nothing visible on the monitor?
Since the nul character is 0, all your if() statements do not apply so it falls into the "normal key" clause. Writing that out to the Serial monitor will not display anything. I would add another if() statement before your Ctrl-A
It seems that my confusion may arrise from an incomplete (read "total lack of ") understanding of USB keyboard protocol. And, while it may be true, per the Hobbytronics website that:
Certain keys cannot be represented by the standard ascii codes. To represent the codes, a two-character
sequence is used. The first character is always an ASCII NUL (0). The second character and its
translations are listed in the following table. Some codes expand to multi-keystroke characters.
Control codes
Dec Hex ASCII Key
0 00 NUL (null) ctrl @
1 01 SOH (start of heading) ctrl A
2 02 STX (start of text) ctrl B
3 03 ETX (end of text) ctrl C
4 04 EOT (end of transmission) ctrl D
5 05 ENQ (enquiry) ctrl E
6 06 ACK (acknowledge) ctrl F
7 07 BEL (bell) ctrl G
8 08 BS (backspace) ctrl H
9 09 HT (horizontal tab) ctrl I
10 0A LF (line feed) ctrl J
11 0B VT (vertical tab) ctrl K
12 0C FF (form feed) ctrl L
13 0D CR (carriage return) ctrl M
14 0E SO (shift out) ctrl N
15 0F SI (shift in) ctrl O
16 10 DLE (data link escape) ctrl P
17 11 DC1 (device control 1) ctrl Q
18 12 DC2 (device control 2) ctrl R
19 13 DC3 (device control 3) ctrl S
20 14 DC4 (device control 4) ctrl T
21 15 NAK (negative acknowledge) ctrl U
22 16 SYN (synchronous idle) ctrl V
23 17 ETB (end of transmission block) ctrl W
24 18 CAN (cancel) ctrl X
25 19 EM (end of medium) ctrl Y
26 1A SUB (substitute) ctrl Z
27 1B ESC (escape) ctrl [
28 1C FS (file separator) ctrl
29 1D GS (group separator) ctrl [
30 1E RS (record separator) ctrl ^
31 1F US (unit separator) ctrl _
... this does not mean that your keyboard transmits two bytes when you hit CTRL-A.
What is, in fact, transmitted when you hit CTRL-A (ascii SOH - Start of Header) is the single byte, 0x01. The ASCII code for null (or NUL), which is 0x00, is not transmitted from your keyboard when you hit the CTRL-SHIFT-2 (or CTRL-@) keys. What gets transmitted in this case simply ignores the CTRL key and you get the single byte 0x40 (the @ sign).
So, in answer to my original question, the null character has not been lost, it was never there in the first place.