respiration.ino
The hardware PWM (LEDC) generates the carrier by itself: analogWrite applies a 0-255 duty cycle and the LED breathes without burning CPU time. The chosen frequency avoids PWM whine.
Hardware required
An ESP32-C6 board (RISC-V 160 MHz, Wi-Fi 6 + BLE 5 + 802.15.4) such as a DevKitC-1, powered over USB. 1 LED + 330 Ω resistor (or common RGB LED + anode on the pin).
Wiring
LED on 7 through 330 Ω to GND. On pins also wired to flash memory, pick another GPIO.
How it works
analogWrite/analogWriteFrequency configure an LEDC channel; the loop only ramps the duty cycle 0-255 while the peripheral generates the signal. In the Arduino IDE (recent esp32 package), select « ESP32C6 Dev Module » then Upload; for Zigbee/Thread use ESP-IDF (idf.py set-target esp32c6).
Going further
Three phase-shifted LEDC channels for an RGB LED, or a small MOSFET stage to drive a power LED strip.
respiration.ino
// Respiration LED par le contrôleur LEDC (PWM matériel du SoC).
const int LED = 7;
const int FREQ = 5000; // 5 kHz : inaudible, pas de sifflement
const int RESOLUTION = 8; // 256 niveaux
int niveau = 0;
int sens = 4; // pas par étape
void setup() {
analogWriteResolution(RESOLUTION);
analogWriteFrequency(FREQ);
analogWrite(LED, 0);
}
void loop() {
niveau += sens;
if (niveau >= 255 || niveau <= 0) sens = -sens;
analogWrite(LED, niveau);
delay(8); // 255/4*8 ms ≈ 0,5 s par rampe
}