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

Breathing LED on an ESP32-C3

One PWM pin, two LEDs: one sees the raw 1 kHz chopping, the other an RC filter smoothing it. The whole build, an ESP32-C3 and 6 more parts, 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.

Breathing LED · 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
// Fade: a breathing LED from software PWM on GPIO 8.
//
// The ESP32-C3 has an LED PWM peripheral, but Mokxi does not model it, so
// this bit-bangs it: a 1 kHz square wave whose high time is the brightness.
// delayMicroseconds is accurate to a couple of instructions in the simulator,
// so the waveform is clean.
//
// The table is one cycle of (1 - cos)/2, which is what makes the light look
// like it is breathing rather than ramping. Values are 0..250 microseconds
// times four, so a step is 0..1000 us of the 1000 us period.

const unsigned long PERIOD_US = 1000;   // 1 kHz
const int STEPS = 64;
const int CYCLES_PER_STEP = 30;         // 30 ms at each brightness

const uint8_t breath[STEPS] = {
    0,   1,   2,   5,  10,  15,  21,  28,
   37,  46,  56,  66,  77,  89, 101, 113,
  125, 137, 149, 161, 173, 184, 194, 204,
  213, 222, 229, 235, 240, 245, 248, 249,
  250, 249, 248, 245, 240, 235, 229, 222,
  213, 204, 194, 184, 173, 161, 149, 137,
  125, 113, 101,  89,  77,  66,  56,  46,
   37,  28,  21,  15,  10,   5,   2,   1,
};

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  for (int step = 0; step < STEPS; step++) {
    unsigned long onTime = (unsigned long)breath[step] * 4;
    unsigned long offTime = PERIOD_US - onTime;

    for (int cycle = 0; cycle < CYCLES_PER_STEP; cycle++) {
      if (onTime > 0) {
        digitalWrite(LED_BUILTIN, HIGH);
        delayMicroseconds(onTime);
      }
      if (offTime > 0) {
        digitalWrite(LED_BUILTIN, LOW);
        delayMicroseconds(offTime);
      }
    }
  }
}

Parts list

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

How it is wired

5 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; LED, red (1) pin C; Capacitor, 47 µF pin 2; LED, red (2) pin C
  • ESP32-C3-DevKitM-1 pin 8; Resistor, 150 Ω (1) pin 1; Resistor, 330 Ω pin 1
  • Resistor, 150 Ω (1) pin 2; LED, red (1) pin A
  • Resistor, 330 Ω pin 2; Capacitor, 47 µF pin 1; Resistor, 150 Ω (2) pin 1
  • Resistor, 150 Ω (2) pin 2; LED, red (2) pin A

Change it and keep it

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