pwm-respiration.ino
The LED breathes along a gamma 2.2 curve matched to human brightness perception. On Teensy, analogWriteFrequency() lets you pick the PWM frequency (3 kHz here) so LED drivers never chirp audibly.
Hardware
A Teensy 3.2 (NXP Kinetis MK20DX256, Cortex-M4 @ 72 MHz, 3.3 V logic) powered over USB. 1 LED + 330 Ω resistor (sized for 3.3 V).
Wiring
LED anode to pin 5 through 330 Ω, cathode to GND. Most Teensy pins are PWM-capable.
How it works
analogWriteFrequency() reconfigures the hardware timer; analogWrite() applies the 0-255 duty cycle. The value passes through a 2.2 power curve for a natural ramp.
Running it
Install the Teensyduino plugin in the Arduino IDE, select the « Teensy 3.2 » board, click Upload then the Teensy Loader button. Note: 3.3 V pins.
Variants
Drive brightness with touchRead() or a light sensor, or extend to several LEDs breathing out of phase.
pwm-respiration.ino
// Respiration LED : analogWrite() + analogWriteFrequency() (Teensy).
const int LED = 5; // broche PWM (la plupart des broches Teensy le sont)
float niveau = 0.0;
float pas = 0.02;
unsigned long derniereEtape = 0;
const unsigned long PERIODE = 10; // ms entre deux paliers
void setup() {
pinMode(LED, OUTPUT);
analogWriteFrequency(LED, 3000); // 3 kHz : au-dessus du sifflement
analogWriteResolution(8); // consignes 0..255
Serial.begin(9600);
}
void loop() {
if (millis() - derniereEtape < PERIODE) return;
derniereEtape = millis();
niveau += pas;
if (niveau >= 1.0) { niveau = 1.0; pas = -pas; }
if (niveau <= 0.0) { niveau = 0.0; pas = -pas; }
// Gamma 2.2 : la perception visuelle est non lineaire.
float gamma = pow(niveau, 2.2);
analogWrite(LED, (int)(gamma * 255));
Serial.println((int)(gamma * 255));
}