🛠 Variation d'intensité d'une LED avec le PWM
Objectives
Use the H3's PWM (pulse-width modulation) output to make an LED "breathe": vary the brightness by changing the duty cycle rather than by rapid blinking. The 40-pin connector on the Orange Pi PC exposes PWM functions (available functions: UART, I2C, SPI, PWM, CAN, I2S, SPDIF, LRADC, ADC). Under the mainline kernel, PWM is handled via the sysfs pwmchip class, without any vendor library.
Hardware
- Orange Pi PC running Armbian, 5 V / 2 A power supply (DC jack)
- 1 LED + 330 Ω resistor
- Cable to the PWM pin enabled by the overlay + GND (3.3 V logic)
sudo armbian-configor editing/boot/armbianEnv.txtto enable the PWM overlay
Complete Code
- Enable PWM and identify the channel:
# Activer l'overlay PWM (armbian-config > Hardware > Overlays > pwm)
sudo sed -i 's/^overlays=.*/& pwm/' /boot/armbianEnv.txt && sudo reboot
# Après reboot : lister les contrôleurs PWM exposés
ls /sys/class/pwm/ # pwmchip0, pwmchipN...
echo 0 | sudo tee /sys/class/pwm/pwmchip0/export # exporter le canal 0
- Breathing script in Python:
#!/usr/bin/env python3
"""respiration.py — effet breathing LED via sysfs PWM (Orange Pi PC)."""
from pathlib import Path
import time
PWM = Path("/sys/class/pwm/pwmchip0/pwm0") # canal exporté ci-dessus
PERIOD_NS = 20_000 # 20 kHz : inaudible, sans scintillement
def main -> None:
(PWM / "period").write_text(str(PERIOD_NS))
(PWM / "polarity").write_text("normal")
(PWM / "enable").write_text("1")
try:
while True:
for pct in list(range(0, 101, 2)) + list(range(98, -1, -2)):
duty = PERIOD_NS * pct // 100
(PWM / "duty_cycle").write_text(str(duty))
time.sleep(0.02)
finally:
(PWM / "enable").write_text("0")
if __name__ == "__main__":
main
Expected Verification
The LED brightness rises and falls continuously (breathing cycle ~4 seconds), without visible flickering. cat /sys/class/pwm/pwmchip0/pwm0/duty_cycle follows the variations.
Common Errors
- Forgetting the overlay: without it, no
/sys/class/pwm/pwmchipappears — this is the #1 blocking point under Armbian. - Writing
duty_cyclebeforeperiod: the kernel rejects or truncates the value; always setperiodfirst. - Period too low with a white LED: visible flickering; stay at ≥ 1 kHz.
- Connecting the LED to a pin that is not multiplexed for PWM: nothing blinks, check the pinmux with the schematic.
Other tutorials for this board
Code examples for this board
clignotante.pyPythonbouton-gpio.pyPythoncapteur-i2c.shBashsurveillance-temperature.shBashcapteur-dht11.pyPythonservo-pwm-sysfs.shBash