A first-time journey with the ESP32-C6 DevKitM-1 — from detecting the board over USB to a smooth rainbow LED cycling through the full spectrum, entirely from the command line.
Why the ESP32-C6?
The ESP32-C6 is Espressif's newest mainstream chip: RISC-V core, Wi-Fi 6, Bluetooth 5, and IEEE 802.15.4 (Thread/Zigbee) — all for € 12,50 What caught my eye was the DevKitM-1 form factor: compact, USB-C, and a WS2812B RGB LED already soldered on. A perfect first target for a no-IDE, command-line-only workflow on macOS.

Instead of reaching for the Arduino IDE or VS Code with PlatformIO, I wanted to understand each step: find the port, install the toolchain, compile, flash. This is what actually happened — including the parts that didn't go smoothly.
Step 1 — Find the Board
Plug in the ESP32-C6 over USB-C and macOS creates a serial device automatically. The factory firmware is already running — a rainbow demo that cycles through colors, confirming the hardware is alive.
ls /dev/cu.* /dev/cu.Bluetooth-Incoming-Port /dev/cu.usbserial-110 # ← there it is
One port. No guessing. /dev/cu.usbserial-110 is what we'll target for both flashing and monitoring.
Step 2 — Install arduino-cli
The Arduino IDE is a fine tool, but it carries a lot of GUI overhead that gets in the way of scripting and automation. arduino-cli gives you the full Arduino ecosystem — board packages, libraries, compilation, upload — as a clean command-line program.
brew install arduino-cli arduino-cli version arduino-cli Version: 1.5.1
Step 3 — Add the ESP32 Board Package
Out of the box, arduino-cli knows nothing about Espressif boards. We point it at the official board index, then install the ESP32 core.
arduino-cli config add board_manager.additional_urls \
https://espressif.github.io/arduino-esp32/package_esp32_index.json
arduino-cli core update-index
arduino-cli core install esp32:esp32@3.0.7
Heads up: During installation the Espressif download server returned a 504 Gateway Timeout on the xtensa-esp-elf-gdb debugger package. Workaround: download the ARM64 macOS build manually from the espressif/binutils-gdb releases page and extract it into ~/Library/Arduino15/packages/esp32/tools/xtensa-esp-elf-gdb/12.1_20231023/. After that, the installation completes normally.
Step 4 — The Right LED Library
The onboard LED is a WS2812B — a "smart" RGB LED with its own protocol. You can't just toggle a GPIO pin; you need a library that generates the precise timing the chip expects.
FastLED is the obvious choice, but version 3.10.5 has a compilation error against ESP32 core 3.0.7: it references dma_burst_size and MALLOC_CAP_CACHE_ALIGNED that were added in a later IDF version. Adafruit NeoPixel compiles cleanly:
arduino-cli lib install "Adafruit NeoPixel" Installed Adafruit NeoPixel@1.15.5
Step 5 — The Code
Version 1: basic color cycling
The first version switches between red, green, blue, and off — one color every 500 ms. Useful for verifying the library works and that you have the right pin and color order (NEO_GRB for this board).
esp32c6-blink.ino C++ / Arduino
#include <Adafruit_NeoPixel.h>
#define LED_PIN 8
#define NUM_LEDS 1
Adafruit_NeoPixel strip(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
strip.begin();
strip.setBrightness(50);
strip.show();
}
void loop() {
strip.setPixelColor(0, strip.Color(255, 0, 0)); strip.show(); delay(500);
strip.setPixelColor(0, strip.Color(0, 255, 0)); strip.show(); delay(500);
strip.setPixelColor(0, strip.Color(0, 0, 255)); strip.show(); delay(500);
strip.setPixelColor(0, strip.Color(0, 0, 0)); strip.show(); delay(500);
}
Version 2: smooth rainbow with HSV
Mixing RGB values to get a smooth color transition is tedious — you'd need to interpolate three channels separately. The HSV color model makes this trivial: keep Saturation and Value fixed, and simply increment the Hue from 0 to 65535. The library maps that arc directly onto the LED, and you get the full visible spectrum with no math.
esp32c6-blink.ino C++ / Arduino
#include <Adafruit_NeoPixel.h>
#define LED_PIN 8
#define NUM_LEDS 1
Adafruit_NeoPixel strip(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
strip.begin();
strip.show();
}
void loop() {
for (long hue = 0; hue < 65536; hue += 32) {
strip.setPixelColor(0, strip.ColorHSV(hue, 255, 150));
strip.show();
delay(8); // 2048 steps × 8 ms ≈ 16 s per full cycle
}
}
The three arguments to ColorHSV: hue (0–65535), saturation (255 = fully saturated), value/brightness (150 out of 255 — bright but not eye-searing). Changing hue += 32 to a larger step speeds up the cycle; changing delay(8) fine-tunes the smoothness.
Step 6 — Compile and Flash
Two commands. The --fqbn flag is the "fully qualified board name" that tells the compiler exactly which chip it's targeting.
arduino-cli compile \
--fqbn esp32:esp32:esp32c6 \
./esp32c6-blink \
--output-dir /tmp/esp32c6-build
Sketch uses 221778 bytes (16%) of program storage space.
arduino-cli upload \
--fqbn esp32:esp32:esp32c6 \
--port /dev/cu.usbserial-110 \
--input-dir /tmp/esp32c6-build \
./esp32c6-blink
Hash of data verified.
Hard resetting via RTS pin...
The board resets automatically after flashing and starts running the new program immediately. No button presses, no manual reboot.
What I Learned
| Topic | Takeaway |
|---|---|
| arduino-cli vs IDE | Easier to script, faster iteration, no GUI overhead — worth the setup cost |
| ESP32 core version | Pin to a specific version (3.0.7 here) until library compatibility catches up |
| FastLED vs NeoPixel | FastLED 3.10.5 breaks on core 3.0.7; Adafruit NeoPixel is more conservative and reliable |
| HSV for animations | Far easier than RGB interpolation for any hue-cycling effect |
| WS2812 color order | The ESP32-C6 DevKitM-1 uses GRB, not RGB — wrong order = wrong colors |
What's Next
The ESP32-C6 has Wi-Fi 6, Bluetooth 5, and Thread built in — a single LED barely scratches the surface. Logical next steps: read a DHT22 temperature sensor and push the data to an MQTT broker over Wi-Fi, or use the LED as a status indicator for something external (a build pipeline, a home automation event). The command-line workflow scales to all of it.

