DEV Community

Jennifer Davis
Jennifer Davis

Posted on

The RGB LED Sidequest 💡

Welcome back to my journey From Dust to Droid Dreams. While the primary path to building a droid is a long-term mission, sometimes you have to take a sidequest to master the fundamentals of the "nervous system." Today’s mission: Multi-LED color blending and the hidden traps of Serial debugging.

I discovered that I had an RGB LED and decided that I would rewire the existing Red, Blue, and Green LEDs and keep the yellow LED as is. The goal was to create a smooth transition between Red, Green, and Blue using Pulse Width Modulation (PWM), dedicated Yellow LED that glows based on the overlap of the Red and Green channels.

The "Fiddly" Hardware

First lesson of the sidequest: The physical world is messy. I quickly learned that the RGB LED setup is super fiddly. Wires cross over easily, and it requires very careful application of the resistors to keep the signals clean and the components safe.

LED surrounded by jumper wires and resistors

Encountering the "Lag" Monster

Once I got the LEDs in sync, I wanted to monitor the values changing in real time. This did not work the way I was expecting. Suddenly, the synchronization disappeared—the Yellow LED started stuttering and wouldn't come on at the right time.

Problematic Code:

void updateLEDs() {
  analogWrite(RED, redValue);
  analogWrite(GREEN, greenValue);
  analogWrite(BLUE, blueValue);

  // Serial output inside the main update loop
  Serial.print("R: "); Serial.print(redValue);
  Serial.print(" | G: "); Serial.print(greenValue);
  Serial.print(" | B: "); Serial.print(blueValue);
  Serial.print(" | Y-LED: "); Serial.print(yellowBright);
  // ... this was slowing everything down!
}
Enter fullscreen mode Exit fullscreen mode

At the default 9600 baud, Serial communication is relatively slow. Every time the code reached these print statements, it paused the loop to send data. This created a "hiccup" in the PWM signal, making the LEDs flicker and the timing feel "off."

The Optimization Fix

To resolve the lag and reclaim that smooth fade, I applied two key fixes:

  • Baud Rate Boost: I increased the speed from 9600 to 115200 (updating it in both the code and the IDE configuration).
  • Timed Printing (Non-blocking): Instead of printing every single loop, I used a timer (millis()) to update the Serial output every 100ms. This keeps the processor focused on the LED pulses.
void updateLEDs() {
  analogWrite(RED, redValue);
  analogWrite(GREEN, greenValue);
  analogWrite(BLUE, blueValue);

  int yellowBright = (redValue < greenValue) ? redValue : greenValue;
  analogWrite(YELLOW, yellowBright);

  // Non-blocking timer: Only print every 100ms
  if (millis() - lastPrintTime > 100) {
    Serial.print("R:"); Serial.print(redValue);
    Serial.print(" G:"); Serial.print(greenValue);
    Serial.print(" B:"); Serial.print(blueValue);
    // Added a small offset (+5) so the yellow line is visible on the plotter
    Serial.print(" Y-LED:"); Serial.println(yellowBright + 5); 
    lastPrintTime = millis();
  }
}
Enter fullscreen mode Exit fullscreen mode

New Tool Use Unlocked: The Serial Plotter

I also spent some time with the Arduino IDE's Serial Plotter (Tools > Serial Plotter). It’s a fantastic tool for visualizing how the color variables oscillate in waves.

Yellow LED blip on the Serial Plotter graph

I had to go through a few iterations to get the yellow line to show up properly. Because the values were identical to the Red or Green lines, they were hidden behind them. Adding a small offset (+5) to the print statement finally made the yellow line visible!

Yellow LED now visible on the Serial Plotter graph

A minor mystery: I haven't figured out how to get the line colors in the plotter to actually match the RGB colors I'm outputting. The IDE seems to assign them automatically based on the order of the variables. If anyone has a hack for this, please let me know in the comments! Even without matching colors, seeing the waves overlap in real-time is a huge help for debugging the logic.

Key Takeaways for the Droid Build

  • Communication Overhead: Consider how much "talking" your microcontroller is doing—it might be slowing down its "thinking."
  • Visualization over Text: Data is much easier to digest as a wave than as a wall of scrolling numbers.
  • Timing is Everything: Don't just default to delay. millis() allows for multi-tasking, whereas delay() essentially puts the Arduino Uno to sleep.

Top comments (0)