Built-in project · ESP32-C3-DevKitM-1

Rainbow strip on an ESP32-C3

An ESP32-C3 runs a hue wheel along sixteen WS2812Bs, bit-banged to the datasheet pulse widths. The whole build, an ESP32-C3 and 1 more part, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.

IntermediateRuns in your browser. Free, and no account needed.

Step by step, with the wiring and the common mistakes: ESP32 NeoPixel (WS2812B) Rainbow Tutorial

Rainbow strip · ESP32-C3-DevKitM-1live0.000 s 0.00x
Click to open it in the editor
The circuit itself, running here on the simulator. Press what can be pressed; click anything else to open it in the editor.

The code

The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.

sketch.ino · ESP32-C3-DevKitM-1
// Rainbow: a hue wheel running along a WS2812B strip.
//
// Wiring, strip to board:
//   DIN -> GPIO 5      VDD -> 5 V      VSS -> GND
//
// One wire carries the whole strip. There is no clock: a bit is a high pulse
// whose length is the bit, 0.4 us for a 0 and 0.8 us for a 1, twenty-four bits
// an LED, green first. Fifty microseconds of quiet at the end is the latch, and
// that is when every LED takes up what it was sent.
//
// The driver in mokxi_ws2812.h makes those pulses with a counted loop rather
// than a timer, because SYSTIMER ticks at 16 MHz, 62.5 ns a tick, and reading
// it takes longer than the pulse being measured. At 160 MHz with one
// instruction a cycle, a two-instruction loop is a 12.5 ns clock, which is
// plenty. See the header for the numbers that come out on the wire.
//
// There is no floating point in this runtime, so the colour wheel is integers:
// 1536 steps round the six edges of the RGB cube, one channel at full, one at
// nothing and one sliding between them.

#include "mokxi_ws2812.h"

const uint8_t DIN_PIN = 5;
const uint16_t LEDS = 16;

// Three bytes an LED, green first: the order the wire wants them in.
uint8_t pixels[LEDS * 3];
Ws2812 strip(DIN_PIN, pixels, LEDS);

// Where the wheel has got to, and how far apart two neighbours are on it.
uint16_t phase = 0;
const uint16_t SPREAD = 1536 / LEDS;
const uint16_t SPEED = 12;

// Full scale on all sixteen would be a floodlight. This is a sixth of it.
const uint8_t LEVEL = 40;

const int FRAME_MS = 20;

void setup() {
  Serial.begin(115200);
  Serial.println("Mokxi ESP32-C3: a rainbow on sixteen WS2812Bs");
  strip.begin();
  strip.clear();
  strip.show();
}

void loop() {
  for (uint16_t i = 0; i < LEDS; i++) {
    uint8_t r;
    uint8_t g;
    uint8_t b;
    ws2812_wheel((uint16_t)(phase + i * SPREAD), &r, &g, &b);
    strip.setPixel(i, ws2812_scale(r, LEVEL), ws2812_scale(g, LEVEL),
                   ws2812_scale(b, LEVEL));
  }
  strip.show();

  phase = (uint16_t)((phase + SPEED) % 1536u);
  delay(FRAME_MS);
}

Parts list

3 parts, plus the jumper wires. Every one is in the editor's parts bin.

How it is wired

3 connections, pin by pin, read from the circuit itself. Each line is one set of pins joined together, by a jumper wire or a breadboard strip.

  • Ground: ESP32-C3-DevKitM-1 pin GND; Addressable RGB LEDs pin VSS
  • ESP32-C3-DevKitM-1 pin 5; Addressable RGB LEDs pin DIN
  • ESP32-C3-DevKitM-1 pin 5V; Addressable RGB LEDs pin VDD

Change it and keep it

Open it in the editor, change the circuit or the code, and keep your version in a free account.