Introduction
Every embedded developer eventually reaches the same moment: the code uploads, the circuit is connected, but the project does not behave as expected.
Maybe the LED never turns on. Maybe a button seems reversed. Maybe an analog sensor gives strange numbers. At that point, guessing is slow. You need a way to see what the ESP32 is doing.
Serial Monitor is the simplest debugging tool in Arduino IDE. It lets the ESP32 send text back to your computer so you can inspect values while the program runs.
What you will learn
By the end of this lesson, you should understand:
- Why debugging matters
- How Serial Monitor helps during development
- How to use
Serial.begin() - How to use
Serial.print()andSerial.println() - How to print button and sensor values
- How to check program timing with
millis() - How to solve common Serial Monitor problems
Why debugging matters
When working with a microcontroller, you cannot directly look inside the chip. You need to ask questions:
- Did the program start?
- Is the button reading
HIGHorLOW? - What ADC value is the sensor producing?
- Is the code entering this
ifstatement? - Is the timing correct?
Serial Monitor gives you a simple text output window for answering those questions.
Start Serial Monitor
To use Serial Monitor, start serial communication inside setup().
void setup()
{
Serial.begin(115200);
Serial.println("ESP32 started");
}
void loop()
{
}
After uploading, open Serial Monitor and set the baud rate to 115200.
If you see ESP32 started, you know:
- The code uploaded correctly
- The ESP32 restarted
- Serial communication is working
- Your baud rate is correct
That small message is often the first useful debug checkpoint.
Serial.print() vs Serial.println()
Serial.print() prints without moving to a new line.
Serial.println() prints and then moves to the next line.
Example:
Serial.print("Value: ");
Serial.println(123);
Output:
Value: 123
This pattern is very useful because labels make your debug output readable.
Debug a button input
In the push button lesson, we used INPUT_PULLUP. That means:
- Released button reads
HIGH - Pressed button reads
LOW
Serial Monitor makes this easy to confirm:
const int buttonPin = 4;
void setup()
{
Serial.begin(115200);
pinMode(buttonPin, INPUT_PULLUP);
}
void loop()
{
int buttonState = digitalRead(buttonPin);
Serial.print("Button: ");
Serial.println(buttonState);
delay(200);
}
If the value never changes, check the wiring. If the value changes but feels reversed, remember that INPUT_PULLUP uses active-low logic.
Debug an analog input
For analog sensors, guessing is especially risky. Always print the raw value first.
const int sensorPin = 34;
void setup()
{
Serial.begin(115200);
}
void loop()
{
int adcValue = analogRead(sensorPin);
float voltage = adcValue * (3.3 / 4095.0);
Serial.print("ADC: ");
Serial.print(adcValue);
Serial.print(" Voltage: ");
Serial.print(voltage);
Serial.println(" V");
delay(200);
}
This helps you answer two important questions:
- Is the sensor changing?
- Is the voltage in the expected range?
Before writing complex logic, first understand the numbers.
Debug timing with millis()
millis() returns the number of milliseconds since the ESP32 started running.
Serial.print("Time: ");
Serial.println(millis());
This is useful when checking delays, repeated events, and timing problems.
Later in the series, millis() becomes important when replacing blocking delay() code with non-blocking code.
Print only when values change
Sometimes Serial Monitor becomes hard to read because the same value prints too quickly.
For a button, you can print only when the state changes:
const int buttonPin = 4;
int lastButtonState = HIGH;
void setup()
{
Serial.begin(115200);
pinMode(buttonPin, INPUT_PULLUP);
}
void loop()
{
int buttonState = digitalRead(buttonPin);
if (buttonState != lastButtonState)
{
Serial.print("Button changed to: ");
Serial.println(buttonState);
lastButtonState = buttonState;
}
delay(20);
}
This makes the output cleaner and easier to follow.
Common Serial Monitor mistakes
If Serial Monitor shows nothing:
- Check the selected COM port
- Check the baud rate
- Confirm that
Serial.begin()is insidesetup() - Press the ESP32 reset button after opening Serial Monitor
- Make sure the USB cable supports data, not only charging
If the output looks like random symbols, the baud rate is probably wrong.
If the output scrolls too fast, add a delay or print only when something changes.
Real engineering use cases
Serial debugging helps with:
- Checking sensor values
- Finding wiring mistakes
- Confirming communication with modules
- Understanding state machines
- Debugging WiFi connection problems
- Testing thresholds before adding automation
Even in professional embedded systems, logging is one of the most important debugging tools.
Engineering challenge
Create a debug sketch that prints:
- A boot message
- Button state
- ADC value
- Estimated voltage
- LED state
Then make the output readable enough that someone else could understand the project state by looking only at Serial Monitor.
Next lesson
Next, we will use Serial Monitor with a real sensor project: an LDR light sensor. We will read light level, choose a threshold, and build a simple automatic night light.