🌈 ESP32-S3 Rainbow: ZX Spectrum Emulator Board! Get it on Crowd Supply →
View All Posts
read
Want to keep up to date with the latest posts and videos? Subscribe to the newsletter
HELP SUPPORT MY WORK: If you're feeling flush then please stop by Patreon Or you can make a one off donation via ko-fi
#ARDUINO #ARDUINO IDE #BREAKPOINTS #DEBUGGING #EMBEDDED SYSTEMS #ESP32 #GPIO #JTAG #PRINTF DEBUGGING #SERIAL

The Six Stages of Debugging (and How to Escape Printf Hell)

Every developer knows this journey.

  • A bug is reported.
  • You’re confident it’s impossible.
  • A few hours later you’re staring at the code wondering how it ever worked at all.

Here are the six stages of debugging - which we’re all going to go through at some point in our lives:

  1. That can’t happen
  2. That doesn’t happen on my machine
  3. That shouldn’t happen
  4. Why does that happen?
  5. Oh, I see
  6. How did that ever work?

Stage 1: That can’t happen

The first stage tends to be denial.

We get a bug report in and our response is immediate: “That can’t happen.” What’s being reported is simply impossible — our software does not behave in that way.

Stage 2: That doesn’t happen on my machine

The second stage is more denial, just slightly more polite.

There’s a grudging acceptance that the user may be experiencing some kind of problem… but we can’t recreate it.

It’s the classic: “Works on my machine.”

Stage 3: That shouldn’t happen

Now things are starting to get interesting.

We’ve managed to recreate the bug, but we know in our heart that it should not be happening. The code is not supposed to behave like this.

There is clearly something wrong with the universe.

Stage 4: Why does that happen?

This is where we’re finally getting into the fun part of debugging.

We’ve accepted reality, and now we’re asking the right question: What is our code actually doing?

This is the most important stage — and also the one where we can easily get stuck.

Stage 5: Oh, I see

If you’re lucky, your debugging leads you to the solution.

Suddenly the problem is obvious. The code is wrong — and now you know exactly why.

This is the moment every developer is chasing.

Stage 6: How did that ever work?

The final stage is an existential crisis.

The code is definitely broken. You’re left scratching your head, wondering how this thing ever worked in the first place.

The real challenge

The real trick is getting from stage 4 — “Why does that happen?” — to stage 5 — “Oh, I see” — as quickly as possible.

On this blog and YouTube channel, we’re often dealing with embedded devices - particularly the ESP32 range of MCUs.

What are our debugging options?

Printf debugging

For anyone familiar with the Arduino framework, these two functions will be very familiar:

Serial.printf("...");
Serial.println("...");

We litter our code with lines such as:

Serial.println("Here 1");
Serial.println("Here 2");

And eventually end up with things like:

Serial.println("Should not be here");
Serial.println("Really should not be here");
Serial.println("Why the **** are we here!?");

Printf debugging works — up to a point.

It’s quick. It’s easy. And it’s often the only tool we reach for.

But it’s also slow, messy, and gives us very limited visibility into what’s actually going on.

Wiggling GPIO pins

Another option with embedded systems is outputting values on GPIO pins.

We can hook up some LEDs to make this more visible, or if we’re very lucky, connect a logic analyser and really dig into what’s happening. These tools are powerful and can do all sorts of clever things, like decoding protocols.

But even then, we’re still inferring behaviour rather than observing it directly.

There is another way

If you’re debugging an ESP32 project, you might think these two options are all you have:

  • Printf debugging
  • Wiggling LEDs

But there is another option.

Recent ESP32 modules have built-in USB peripherals — and more interestingly, built-in JTAG debugging support.

That means you can add breakpoints to your code and simply hit “Start Debugging” in the Arduino IDE.

It really can be that simple.

With a real debugger, you can:

  • Set breakpoints
  • Use conditional breakpoints
  • Inspect variables
  • Modify values while the code is running

It’s just like debugging code on your desktop — but on an embedded device.

See it in action

Here’s a short video showing what’s possible when you use the ESP32’s built-in USB debugging support, including breakpoints, variable watches, and conditional logic.

If you’re tired of being stuck in stage 4, this might be the quickest route to stage 5.

#ARDUINO #ARDUINO IDE #BREAKPOINTS #DEBUGGING #EMBEDDED SYSTEMS #ESP32 #GPIO #JTAG #PRINTF DEBUGGING #SERIAL

Related Posts

This number does nothing - Ever wondered about the ubiquitous 'Serial.begin(115200);' in your Arduino projects? It turns out, with boards like the ESP32-S3 offering native USB support, this baud rate doesn't really matter when streaming data. My tests even showed surprising results with different speeds using Arduino and ESP-IDF, highlighting potential in USB full-speed capabilities. I dove into raw performance testing, and saw deviations from expected UART limits. Check out the full video and explore the results if you're curious about maximizing your data transfer speeds!
How do we debug? - Today, we dissected a classic programmer joke about the stages of debugging and why we find it funny while it reflects a dire situation. We pondered why our first instinct is to dismiss a bug, dug into invalid claims about machines, and appreciated the shift from denial and blame to accepting responsibility and finding solutions. After deconstructing the old stages of debugging, we reconstructed healthier, proactive stages with prime focus on problem-solving. Next, we explored different types of bugs from easy user interface bugs to the complex Heisenbugs. Lastly, I highlighted logging, debuggers, and good old human brainpower as instrumental tools for debugging. Be patient, be a detective.
ESP32-S3 Dev Board Assembly - I finally assembled our ESP32-S3 dev boards—used a stencil for easy SMD work, fixed a few tiny USB solder bridges with flux, and even hand-built one for fun. The EPAD isn’t required (per the datasheet), power LEDs look good, and on macOS you can spot it under /dev before flashing. A quick boot-button dance and the blink sketch runs great—full build and walkthrough in the video.
Minimalist Microcontroller: Building a Bare-Bones Dev Board - In a thrilling DIY endeavour, I attempted to build the most minimalist ESP32 dev board possible. Diving deep into the schematic of the ESP32 S3 WROOM module, I chopped out the non-essentials and whittled our needs down to bare bones. The experiment saw me juggling USB data lines and voltage regulators, waving goodbye to an array of capacitors and connectors and boldly embracing the simplicity of direct connections. Despite a few hitches, the miniature Frankenboard came alive, proving that sometimes less is more...at least in the world of microcontrollers.
Easy esp32 s3 dev board - Quick recap: I’m putting together a super simple ESP32-S3 dev board—there’s a video walkthrough, the full KiCad project on GitHub, plus the schematic and a slick 3D render of the assembled board.

Related Videos

Stop Using printf() - Debug ESP32 the Right Way - Right, let’s give this a go. Instead of drowning in printf()s and blinking LEDs, I show how the ESP32-S3’s built‑in USB JTAG lets you hit Debug in the Arduino IDE (or PlatformIO) and actually step through code. We set breakpoints, add watch expressions, use conditional breakpoints, and even edit variables live with a simple FizzBuzz/LED demo. It’s quick, it works, and it beats “works on my machine”—just mind real‑time code and ISRs. Works on ESP32s with native USB.
I Built My Own ESP32-S3 Board… And It Actually Works! - I finally assembled my super simple ESP32‑S3 dev board—voltage regulator, reset button, three status LEDs (5V, 3.3V, and a GPIO blinker), and all pins broken out. I showed two build methods: stencil + hot-plate reflow (quick, with a few USB bridges to clean up) and full hand-solder under the microscope, complete with the rigorous ‘solid’ test. Soldered the ESP32‑S3 module (skipping the center thermal pad unless you need it), plugged in, got power LEDs, confirmed USB enumeration, flashed a blink sketch, and we’ve got a blinking LED. Next up: turning this basic dev board into something more professional for production.
ESP32-S3 - Which Pins Are Safe To Use? - In this video, I've decided to dive deep into the ESP32-S3, a module ruling my lab recently due to its plug-in-and-play functionality, and the flexibility offered by its GPIO matrix. However, working with it requires vigilance, especially with regard to the strapping pins and USB data pins, among others. Discovering such quirks, I've encountered unexpected values, short glitches and the occasional code crash. To help you avoid these bumps, I've documented everything I've learned on my GitHub repo, where I'm inviting you, my fellow makers and engineers, to contribute your valuable experiences and findings. After a minor hiccup with my ESP32-TV, expect an updated PCB design, courtesy of PCBWay. Explore the ESP32-S3 with me, and let's unravel its secrets together, one pull request at a time.
Can You Spot the Problem? - Buckle up folks, this video is a thrilling one! There's everything from unboxing my new ESP32 TV boards that arrived from PCB Way to discovering some hidden issues. We're talking about some pesky problems, surprises, and even a potential catastrophic error that could've led to a disaster. The main dish is the high-speed SD card access over USB - ultimately achieving a whooping transfer rate! But, the journey is a roller-coaster ride, from the project completely failing initially, to some smart hacks and triumphant moments. All the peripherals worked well, from the display to the sound amplifier and even the infrared receiver. Despite the ups and downs, there's a lot to learn and that's what makes this video exciting! Can't wait to share the improvements I have in mind for turning the prototype into the ultimate all-in-one device. But first, let's address the elephant in the room - an ill-placed diode that's a ticking bomb, because you know, safety first!
Minimalist Microcontroller: Building a Bare-Bones Dev Board - Dive into the fascinating process of building a minimal ESP32-based dev board, beginning with the ESP32-S3 Wroom module, and eliminating unnecessary components. Through soldering, wire connecting, and voltage testing, we reach a product that's compact, efficient and fully functional.
HELP SUPPORT MY WORK: If you're feeling flush then please stop by Patreon Or you can make a one off donation via ko-fi
Want to keep up to date with the latest posts and videos? Subscribe to the newsletter
Blog Logo

Chris Greening


Published

> Image

atomic14

A collection of slightly mad projects, instructive/educational videos, and generally interesting stuff. Building projects around the Arduino and ESP32 platforms - we'll be exploring AI, Computer Vision, Audio, 3D Printing - it may get a bit eclectic...

View All Posts