
ESP32-S3 board
Now it reads your input as well as printing its own.
ESP32-S3 Lab · Day 12 of 30
Yesterday the board only talked. Today it listens. The same two USB wires that carried its readings out now carry your keystrokes back in — each character landing in a small buffer on the board, waiting there until the sketch reads it. Once your code can read what you type, it can act on it, and the board becomes something you steer while it runs.
TSK-DAY12-SERIALRW
Hand this to an agent so it can pull the lesson packet and coach you step by step.
01 First, know the pieces
The same three things as yesterday — nothing to wire. Tap Define on anything unfamiliar; the answer opens as a field note you can read and dismiss without losing your place.

Now it reads your input as well as printing its own.

Serial Monitor's input box is how you type to the board.

Sketch_07.2_SerialRW.ino
02 One action at a time
The whole day is upload, type, and read the reply. Tap each step as you go to keep your place — you can finish without opening a single field note.
Plug the ESP32-S3 into your computer with a data-capable USB cable.
In Arduino IDE, select your ESP32-S3 board and the port it appears on.
Open Sketch_07.2_SerialRW.ino.
Press Upload and wait for the IDE to say Done uploading.
Open Serial Monitor, set the baud rate to 115200, and set the line ending to Newline.
Type a word into the input box, press Enter, and watch the board echo it back.
03 Read just enough code
The sketch waits for you. When characters arrive it collects them into one message, tidies the ends, and prints that message back. Switch to MicroPython if you'd rather see the same idea in Python.
void loop() {
if (Serial.available()) {
inputString = Serial.readStringUntil('\n');
inputString.trim();
if (inputString.length() > 0) {
stringComplete = true;
}
}
if (stringComplete) {
Serial.printf("inputString: %s\r\n", inputString.c_str());
inputString = "";
stringComplete = false;
}
}
Serial.available()Reports how many of your characters are sitting in the receive buffer, so the board reads only when something has actually arrived rather than acting on an empty read. Serial.readStringUntil('\n')Pulls characters out of the buffer one after another and stops at the Enter key, handing you one whole message instead of loose bytes. inputString.trim()Trims the stray newline and spaces off the ends so the message you act on is exactly what you typed.Serial.printf("inputString: %s\r\n", inputString.c_str())Sends your message straight back as proof it was read, then the sketch clears its variable and waits for the next line. Optional side path · no wiring
print(str("\nESP32S3 initialization completed!\n")
+ str("Please input some characters,\n")
+ str("select \"Newline\" below and click send button. \n"))
while True:
print("inputString: ", input())
input()In MicroPython, input() waits for a line you type in Thonny's shell — the same pause-and-read as Serial.available plus readStringUntil.print("inputString: ", input())Echoes your typed line straight back, just like the Arduino sketch.Same cable, no wiring. MicroPython's input() reads from Thonny's shell instead of Serial Monitor, but the two-way idea is identical. If MicroPython isn't set up yet, skip this — it should never block the Arduino-first path.
04 Understand, don't memorise
Yesterday the cable carried the board's voice out. The reverse trip is the whole idea today, and it does not happen the way you might picture. The board is not watching your keyboard. Your characters arrive on their own schedule and pile up in a small holding area until the sketch gets around to reading them. Understanding that gap between arriving and being read is what makes input reliable.
Nothing new is wired. The two data wires that sent readings out yesterday now carry each key you press back to the board.
A typed character crosses the cable and lands in the board's receive buffer — a small queue — one byte at a time, whether or not the loop is ready for it.
Serial.available() reports how many bytes are sitting in that buffer right now. Zero means nothing has arrived yet.
Serial.read() removes the next byte and hands it to your code. readStringUntil is that same read run in a loop until it reaches your Enter key.
Each byte is a character code — the letter A arrives as the number 65. Compare it or convert it to a number, and the board can act on what you typed.
characters land in a buffer → available() counts → read() takes one → your code acts on it
Calling read() on an empty buffer returns -1, its stand-in for nothing here. Checking available() first means the board waits for real input instead of mistaking that -1 for something you sent.
The board receives raw character codes one at a time, so a five-letter word is five separate bytes. readStringUntil gathers them up to your Enter key into one whole message; a comparison or toInt() then turns that message into something to act on.
05 Know it worked
Success and recovery sit side by side, so you never have to go hunting when something looks off.
The start-up lines print once; after that, each line you send comes straight back prefixed with "inputString:".
06 Make the idea yours
Echoing text proves the board read you. Making it do something proves it can take orders. The onboard LED needs no wiring, so you can turn your typed words into a physical action without touching a single wire.
In setup() add pinMode(LED_BUILTIN, OUTPUT). In the loop, where the message is ready, add if (inputString == "on") digitalWrite(LED_BUILTIN, HIGH); and an off line that writes LOW. Type on or off and the onboard LED follows your command — the board acting on words, no wiring.
Replace the word check with int n = inputString.toInt(); and blink the onboard LED n times. Now a number you type drives real behaviour, and you have watched raw characters become a value the board acts on — exactly the byte-to-command step from the theory.
07 Learn it with a hand on the tiller
Every lesson ships with a code and a machine-readable packet, so an agent can guide you with full context.
TSK-DAY12-SERIALRW
How the agent should behave: keep the core loop to upload-type-read, and check board, port, cable, baud rate, and the Newline line ending before touching code. On request, explain how input arrives — characters landing in a receive buffer, available() counting them, read() taking one at a time, and read() returning -1 on an empty buffer — so the learner sees why the sketch checks before it reads.
Keep your place
Mark it complete — it shows on your course map, and your place is saved on this device.