GPIO18 (PWM) · Python · rpi_ws281x


🔧 Requisits de maquinari

  • Raspberry Pi (3, 4, Zero, etc.)
  • Pin GPIO18 (pin físic 12) → senyal de dades
  • LED ARGB (WS2812 / SK6812 RGBW)
  • Font d’alimentació externa de 5 V (⚠️ no alimentar la tira des de la Raspberry Pi)
  • GND comú entre la Raspberry Pi i els LEDs
  • (Recomanat) Level shifter de 3,3 V → 5 V

🧩 Instal·lació del driver

sudo apt update
sudo apt install python3-pip
sudo pip3 install rpi_ws281x

La llibreria controla PWM0 mitjançant GPIO18, que és el mètode estable per a protocols tipus WS2812 / ARGB.


📌 IMPORTANT (abans d’executar)

Cal desactivar l’àudio, ja que utilitza el mateix PWM:

sudo nano /boot/config.txt

Afegeix:

dtparam=audio=off

«

I reinicia:

sudo reboot


✅ Codi Python (versió ARGB)

Aquest codi és l’equivalent funcional del teu codi en AVR:

  • Activació i desactivació del GPIO
  • Generació de polsos amb temporització precisa
  • Reset / latch superior a 50 µs

Tot això gestionat per PWM + DMA per maquinari, sense errors de timing.


📜 argb_pwm_gpio18.py

from rpi_ws281x import PixelStrip, Color
import time

# -----------------------------
# CONFIGURACIÓ
# -----------------------------
LED_COUNT      = 8        # Nombre de LEDs
LED_PIN        = 18       # GPIO18 (PWM0)
LED_FREQ_HZ    = 800000   # Freqüència del protocol WS2812
LED_DMA        = 10       # Canal DMA segur
LED_BRIGHTNESS = 255
LED_INVERT     = False
LED_CHANNEL    = 0        # PWM0

# -----------------------------
# INICIALITZAR LA TIRA
# -----------------------------
strip = PixelStrip(
    LED_COUNT,
    LED_PIN,
    LED_FREQ_HZ,
    LED_DMA,
    LED_INVERT,
    LED_BRIGHTNESS,
    LED_CHANNEL
)

strip.begin()

# -----------------------------
# FUNCIÓ ARGB (equivalent a ARGB2_readoutstring)
# -----------------------------
def ARGB2_readoutstring():
    for i in range(LED_COUNT):
        A = 255   # Alfa / brillantor
        R = 255
        G = 0
        B = 0

        # rpi_ws281x usa ordre GRB internament
        strip.setPixelColor(i, Color(G, R, B))

    strip.show()            # Envia els polsos + latch
    time.sleep(0.00008)     # >80 µs reset (equivalent a _delay_us(80))

# -----------------------------
# BUCLE PRINCIPAL
# -----------------------------
try:
    while True:
        ARGB2_readoutstring()
        time.sleep(1)

        # Apagar els LEDs
        for i in range(LED_COUNT):
            strip.setPixelColor(i, Color(0, 0, 0))
        strip.show()
        time.sleep(1)

except KeyboardInterrupt:
    for i in range(LED_COUNT):
        strip.setPixelColor(i, Color(0, 0, 0))
    strip.show()

Executa’l amb permisos DMA:

sudo python3 argb_pwm_gpio18.py

🔍 Correspondència directa amb el teu codi en AVR

AVR (C)Raspberry Pi
`PORTB= 1`PWM en nivell alt
PORTB &= ~1PWM en nivell baix
_delay_us(20/50)Temporització del FIFO PWM
_delay_us(80)Reset del bus amb strip.show()
DDRB on/offGestionat internament pel driver

La llibreria genera exactament els polsos T0H, T1H i el reset del protocol ARGB/WS2812 per maquinari.


⚠️ Notes crítiques de seguretat

  • Cada LED pot consumir fins a ~60 mA a blanc complet
  • 🧨 No utilitzar DMA 5 (pot provocar corrupció del sistema)
  • ✅ Canal DMA recomanat: 10

✅ Conclusió

✔ GPIO18 (PWM per maquinari)
✔ Temporització precisa
✔ Compatible amb ARGB / WS2812 / SK6812
✔ Substitueix completament el codi manual de timings en AVR


Si vols, puc:

  • Adaptar-ho a RGBW / ARGB real
  • Fer animacions optimitzades amb DMA
  • Integrar-ho amb sensors o OpenCV
  • Traduir el teu codi AVR línia per línia al món Raspberry

Quan vulguis 👍