Source: https://mokxi.com/learn/arduino-serial-read
Updated: 2026-10-25

Learn

# Reading the serial monitor on an Arduino

Written by the Mokxi team, updated October 25, 2026

Start building free

Or see every lesson.

- 455 parts on the bench
- 43 boards running now
- 1.00x real time, on every board

Click to open it in the editor

Type o, f or b into the serial monitor and press Enter: on, off or blink, answered each time.

To read what you type into the serial monitor, check Serial.available() to see whether anything has arrived, then call Serial.read() to take one character. if (Serial.available() > 0) { char c = Serial.read(); } is the whole pattern, and it lets a sketch take commands from your keyboard while it carries on with everything else.

The circuit above is an Uno with an LED on pin 13, listening for three commands. Press Run, click in the box under the serial monitor, type o and press Enter. It answers "ok: on" and the lamp lights. Type b for "ok: blink", f for "ok: off", and anything else for "unknown command: x" with your letter in place of the x.

Below is what Serial.read() really hands you, reading a whole line, reading a number, and the one bug everyone meets with parseInt(): the extra 0 that turns up a second after the number you typed.

Want the step-by-step version? The lesson "Taking commands" walks through this with checkpoints.
Open the lesson

## available() and read()

Serial.available() returns how many characters have arrived and are waiting. It does not wait for anything. Serial.read() takes the oldest one and returns it, or -1 if there is nothing there; with nothing typed, our sketch printed -1 and an available() of 0. Neither call ever waits, so the blink in the sketch above keeps running while it listens.

Type "hi" and press Enter, and print each character as a number instead of a letter, and the board printed 104 105 10. Those are the codes for h and i, and then a 10, which is the newline. The Arduino IDE’s serial monitor has a Line ending menu that decides what it sends after your text; Mokxi’s monitor always sends a newline, the same as the IDE’s New Line setting. That is why the sketch above skips '\n' and '\r' instead of answering "unknown command".

firmware/uno/examples/commands (the reading half of the sketch above)

## Read a whole line

For commands longer than one letter, read up to the newline with Serial.readStringUntil('\n'). It collects characters into a String until it sees a newline, takes the newline away and hands back the rest. Typed "hello", the sketch below printed "[hello] 5": five letters, no newline on the end.

If nothing arrives, readStringUntil() waits for up to one second for the next character, then gives up and returns what it has. Call it only once available() says something is there, as below, and the wait is never more than the time it takes a line to arrive.

With the line in a String, the rest is ordinary code. if (line == "on") compares it, line.startsWith("speed ") checks how it begins, and line.substring(6).toInt() turns the rest into a number, so a command like speed 120 needs no more than three lines to read.

If your sketch compares a line with == and it never matches on a real board, check the IDE’s Line ending menu. With Both NL & CR it sends a carriage return before the newline, and that carriage return stays on the end of the line. We sent "on" that way: the line was 3 characters long and line == "on" was false. After line.trim(); it was 2 characters and true. Mokxi’s monitor sends no carriage return, so this one only shows up on the bench, which is a good reason to call trim() anyway.

Read up to the newline

## Read a number, and the 0 a second later

Serial.parseInt() skips anything that is not a digit, reads a whole number and returns it as a long. It is the quickest way to type a number in, and it has a trap. Run the sketch below, type 42 and press Enter. It printed "got 42 at 502", and then, a second later, "got 0 at 1502", a number you never typed.

Here is why. parseInt() stops at the first character that is not a digit and leaves it waiting, so the newline is still there. Next time round, available() is 1, so parseInt() runs again, skips the newline, finds nothing more, waits its one-second timeout and returns 0. Call Serial.setTimeout(50); in setup() and the 0 arrives sooner, at 552 ms, but it still arrives.

The fix is to read the line first and turn it into a number second. With String line = Serial.readStringUntil('\n'); int n = line.toInt(); the same 42 printed "got 42 at 502" and nothing else. parseInt() is still handy for two numbers on one line. Typed "12 30", two calls in a row printed "42 at 505", the sum, and then "0 at 2505": the leftover newline started another round, and both of its calls waited out their second.

parseInt() and its extra 0

## Questions

Why does Serial.parseInt() return 0?

Because the newline sent after your number is still waiting. The next parseInt() skips it, finds no digits, waits for its one-second timeout and returns 0. Read the line with readStringUntil('\n') and convert it with toInt() instead.

What does Serial.read() return when nothing has been sent?

-1. Check Serial.available() first, and only call read() when it is more than 0.

Why does my input have an extra character on the end?

The serial monitor sends a line ending after your text: a newline, a carriage return or both, depending on its Line ending setting. readStringUntil('\n') removes the newline but keeps a carriage return. Call trim() on the String to remove it.

Does Serial.read() wait for input?

No. It returns at once, with the next character or -1. readString(), readStringUntil() and parseInt() do wait, for up to the timeout set by Serial.setTimeout(), which is 1000 ms unless you change it.

Can I test serial input without a board?

Yes. Mokxi’s serial monitor sends what you type to the simulated board, followed by a newline, so every sketch on this page runs in the browser as it would on an Uno.

How do I read a string from serial into a char array?

`int n = Serial.readBytesUntil('\n', buf, sizeof(buf) - 1);` copies everything up to the newline into buf and returns how many characters it copied. It does not end the text with a zero, so write `buf[n] = 0;` next. Typed hello, the sketch printed "got 5 bytes: hello".

Related

## Keep going

UART Serial Explained: Baud, Frames and the Wire Arduino Simulator: Serial Monitor and Logic Analyzer Arduino Serial Monitor Garbage or Blank: Fixes Arduino switch case: Modes, Menus and break How to Debug Arduino Code: Prints to Breakpoints Arduino String: Join, Compare, Convert, Split Arduino Serial.print vs println, and Decimals Arduino strtok: Parse Serial Commands and CSV Run and the serial monitor in the editor The free Arduino simulator

Sources

## Where the facts on this page come from

- Arduino reference: Serial.read()
- Arduino reference: Serial.parseInt()
- Arduino reference: Serial.readStringUntil()

## Build this for real

Open the editor, change a value and watch the number move with it. Nothing to install, and no account needed.

Start building free Open the editor
