Lab

What the Arduino actually receives

Bluetooth does not deliver messages. It delivers bytes, one at a time, each a number from 0 to 255. The letter F is 70. And a setting you may never have touched decides whether two invisible bytes, 13 and 10, follow every command.

Type what your app sends and pick its line-ending setting. Each byte appears as the number bytes.ino would print, beside the step of the dispatcher it reaches and what the Serial Monitor shows.

Then switch the sketch to one with no line-ending step that stops on anything it doesn’t know, and send F with Both NL & CR. That is the twitch. Last, send the word FORWARD.

WHAT THE APP SENDS
THE APP'S LINE-ENDING SETTING
adds 13, 10 after every message
THE SKETCH ON THE ARDUINO
Read one byte, ignore CR and LF, decide, act.
3 BYTES ARRIVE, ONE AT A TIME
bytes.ino
dispatcher.ino
F
bt: 70
3 · decide → F · 4 · act
prints: forward
CR
bt: 13
2 · line ending: thrown away
prints nothing
LF
bt: 10
2 · line ending: thrown away
prints nothing
WHAT A CAR ON THIS SKETCH ENDS UP DOING
forward
Change the line-ending setting: with the dispatcher, the 13 and 10 appear in bytes.ino and never reach a decision.
NOW YOU TRY
Your app’s Forward button sends f, with the line ending set to Both NL & CR. Predict the numbers bytes.ino prints, and what dispatcher.ino does with each. Then type it above and check.
Say your answer out loud, then open this
bytes.ino prints bt: 102, bt: 13, bt: 10. The dispatcher turns 102 (a lowercase f) into F and calls forward; 13 and 10 are thrown away at step 2, so nothing else prints. A sketch that only checks for a capital F would ignore the button completely.

What this shows

Bluetooth delivers bytes, not messages. Each byte is a number from 0 to 255: a capital F is 70, a lowercase f is 102, and the invisible carriage return and new line some apps add after every message are 13 and 10.

A dispatcher handles one byte per command in four steps: read one byte; throw away 13 and 10; decide, turning lowercase into uppercase and letting through only the command letters and digits; then act. With that order, line endings can never be mistaken for a command, and any other byte is reported as ignored.

A sketch without the line-ending step, which stops the motors on anything it does not recognise, obeys F and is stopped one byte later by its own line ending. That is the twitch: the car jerks and stops. The fix is either No line ending in the app or the dispatcher's step 2.

Words are not commands. FORWARD is seven bytes, and a one-byte dispatcher reads F as forward, ignores O, reads R as right, ignores W and A, reads R as right again and ignores D. The car goes forward, then turns right.

Common questions

What are 13 and 10 in the Arduino Serial Monitor?
A carriage return (13) and a new line (10): the bytes a line-ending setting adds after every message. They arrive like any other byte, and a sketch that does not throw them away will try to treat them as commands.
Why does my Bluetooth car twitch and stop?
The app is adding a line ending, and the sketch stops the motors on any byte it does not recognise. The car obeys the letter, then the 13 or 10 arrives a moment later and stops it. Set the app to No line ending, or ignore 13 and 10 before deciding.
Why should a Bluetooth command be a single letter?
Because Bluetooth delivers a stream of bytes with no message boundaries. A word can arrive split across two passes of loop(), and a sketch reading one byte at a time treats every letter as its own command. One byte is never split.