Ir al contenido

Control de dimmer AC con Raspberry Pi vía DimmerLink

Linux no proporciona control GPIO en tiempo real — la atenuación por corte de fase TRIAC directa es imposible sin un controlador dedicado. DimmerLink resuelve esto: Raspberry Pi envía solo un nivel de brillo, DimmerLink se encarga de la sincronización precisa.

Resumen: El corte de fase TRIAC directo desde GPIO de Raspberry Pi no es viable — el jitter del SO Linux es de 1–10 ms mientras que la sincronización TRIAC requiere < 100 µs. Usa DimmerLink como controlador de hardware: RPi escribe un valor de brillo (0–100) en la dirección I2C 0x50, registro 0x10. Una línea en Python: bus.write_byte_data(0x50, 0x10, level).




Por qué Raspberry Pi no puede controlar un TRIAC directamente

La atenuación por corte de fase TRIAC dispara la compuerta con un retardo preciso después de cada cruce por cero AC (cada 10 ms a 50 Hz). El error de sincronización admisible es inferior a 100 µs para evitar parpadeo visible.

Raspberry Pi ejecuta Linux — un SO de propósito general con un planificador preemptivo, swap, controladores de red y actividad de GPU, todos compitiendo por tiempo de CPU. La latencia de interrupciones GPIO en este SO:

Condición Latencia de interrupción GPIO
Sistema inactivo 0,5–2 ms
Red / USB activos 2–10 ms
E/S de disco hasta 50 ms

Un jitter de 2 ms al 10 % de brillo (ventana de disparo de 9 ms) equivale a una variación de brillo del 22 % — parpadeo claramente visible. Incluso con el demonio pigpio (GPIO basado en DMA, la mejor opción disponible) el jitter es típicamente de 200–500 µs — aún por encima del umbral requerido bajo carga real.

Esta no es una limitación específica de Raspberry Pi. Cualquier SBC con Linux (Orange Pi, Rock Pi, Jetson Nano, Banana Pi) tiene la misma restricción. El control TRIAC en tiempo real bajo Linux requiere un parche de kernel RT (poco práctico para uso amateur) o delegar la sincronización a un microcontrolador dedicado.

DimmerLink es ese controlador dedicado. Gestiona la detección de cruce por cero y el disparo del TRIAC en un Cortex-M0+ (familia STM32), alcanzando < 50 µs de jitter independientemente de la carga de CPU del host. Raspberry Pi solo le indica el brillo deseado — sin requisitos de sincronización.




Hardware necesario

  • Raspberry Pi 3, 4, 5 o Zero 2W (cualquier modelo con I2C)
  • Módulo DimmerLink
  • Módulo dimmer AC rbdimmer (cualquier capacidad de corriente)
  • 2 × resistencias de 4,7 kΩ (pull-ups I2C — a menudo no necesarias en RPi 3/4)



Paso 1 — Cambiar DimmerLink al modo I2C

DimmerLink viene en modo UART por defecto. Cámbialo al modo I2C antes de conectarlo al Raspberry Pi.

Conecta DimmerLink a un adaptador USB-UART (TX → RX, RX → TX, GND, VCC 3.3V). En cualquier computadora, abre el puerto a 115200 baudios, 8N1, y envía:

text
Raw bytes: 02 5B

Respuesta esperada: 00 (OK). El dispositivo ahora arranca en modo I2C tras cada encendido. (El modo se guarda en EEPROM.)




Paso 2 — Cableado


Raspberry Pi → DimmerLink (I2C)

Conector GPIO de Raspberry Pi Cualquier ESP32 Función
Pin 1 (3.3V) VCC Alimentación
Pin 6 (GND) GND Tierra
Pin 3 (GPIO2 / SDA) SDA Datos I2C
Pin 5 (GPIO3 / SCL) SCL Reloj I2C

Resistencias pull-up: Raspberry Pi 3/4/5 tiene pull-ups integrados de 1,8 kΩ en GPIO2 y GPIO3. Normalmente son suficientes para cables de menos de 30 cm. Para cables más largos o comunicación inestable, agrega resistencias externas de 4,7 kΩ de SDA y SCL a 3.3V.


DimmerLink → Módulo dimmer AC

Cualquier ESP32 Módulo dimmer
VCC VCC
GND GND
Z-C Z-C
Dim DIM

Connect the dimmer module to mains AC and the load per the Hardware Connection Guide.




Paso 3 — Habilitar I2C en Raspberry Pi

bash
sudo raspi-config
# Interface Options → I2C → Enable → OK → Finish
sudo reboot

Tras reiniciar, instala i2c-tools y verifica la conexión:

bash
sudo apt install i2c-tools
i2cdetect -y 1

Salida esperada — la dirección 50 visible en la tabla:

text
0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
...
50: 50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

If the device does not appear, see DimmerLink Not Detected.




Paso 4 — Control con Python (smbus2)

Instala la biblioteca:

bash
pip install smbus2


Ejemplo mínimo

python
from smbus2 import SMBus
DIMMER_ADDR = 0x50
REG_LEVEL   = 0x10  # DIM0_LEVEL — brillo 0–100%
bus = SMBus(1)  # Bus I2C 1 de Raspberry Pi
bus.write_byte_data(DIMMER_ADDR, REG_LEVEL, 50)  # establecer 50%
bus.close()


Clase completa con manejo de errores

python
from smbus2 import SMBus
import time
class DimmerLink:
    ADDR = 0x50
    REG_STATUS = 0x00
    REG_LEVEL  = 0x10  # brillo 0-100%
    REG_CURVE  = 0x11  # 0=LINEAR, 1=RMS, 2=LOG
    REG_FREQ   = 0x20  # frecuencia de red (50 o 60 Hz)
    def __init__(self, bus_number=1):
        self.bus = SMBus(bus_number)
    def is_ready(self):
        status = self.bus.read_byte_data(self.ADDR, self.REG_STATUS)
        return bool(status & 0x01)
    def set_level(self, level: int):
        """Establecer brillo 0–100%."""
        level = max(0, min(100, level))
        self.bus.write_byte_data(self.ADDR, self.REG_LEVEL, level)
    def get_level(self) -> int:
        """Leer brillo actual."""
        return self.bus.read_byte_data(self.ADDR, self.REG_LEVEL)
    def set_curve(self, curve: int):
        """Establecer curva de atenuación: 0=LINEAR, 1=RMS, 2=LOG."""
        if curve not in (0, 1, 2):
            raise ValueError("curve must be 0, 1, or 2")
        self.bus.write_byte_data(self.ADDR, self.REG_CURVE, curve)
    def get_frequency(self) -> int:
        """Leer frecuencia de red (50 o 60 Hz)."""
        return self.bus.read_byte_data(self.ADDR, self.REG_FREQ)
    def close(self):
        self.bus.close()
if __name__ == "__main__":
    dimmer = DimmerLink()
    if dimmer.is_ready():
        print(f"Frecuencia de red: {dimmer.get_frequency()} Hz")
        # Aumento progresivo
        for level in range(0, 101, 5):
            dimmer.set_level(level)
            print(f"Brillo: {level}%")
            time.sleep(0.1)
        # Establecer curva RMS para lámparas incandescentes
        dimmer.set_curve(1)  # 1 = RMS
        print("Curva: RMS (incandescente)")
    else:
        print("DimmerLink no está listo — verifica el cableado y el modo I2C")
    dimmer.close()


Control rápido desde CLI (sin Python)

bash
# Establecer brillo al 50%  (0x32 hex = 50 decimal)
i2cset -y 1 0x50 0x10 50
# Leer brillo actual
i2cget -y 1 0x50 0x10
# Leer frecuencia de red
i2cget -y 1 0x50 0x20



Paso 5 — Integración con Node-RED


Mediante nodo exec con comando i2cset

En un flujo simple, usa exec para ejecutar i2cset:

text
[inject: level=50] → [function: construir comando] → [exec] → [debug]

Nodo Function:

javascript
var level = msg.payload;  // 0-100
msg.payload = "i2cset -y 1 0x50 0x10 " + level;
return msg;


Mediante node-red-contrib-i2c

Instala el nodo:

bash
cd ~/.node-red
npm install node-red-contrib-i2c

Configura un nodo i2c out:

  • Address: 0x50
  • Command: 0x10 (registro)
  • Payload: el valor de brillo (0–100) desde msg.payload

Un slider UI mapeado a 0–100 controla directamente el dimmer.




Paso 6 — Home Assistant OS en Raspberry Pi

Si Raspberry Pi ejecuta Home Assistant OS (no Home Assistant sobre Raspberry Pi OS), el acceso al hardware I2C desde los add-ons está restringido por el modelo de contenedores de HA OS.

Enfoque recomendado:

  1. Mantén el Raspberry Pi como servidor de HA.
  2. Agrega un ESP32 con DimmerLink separado como controlador de hardware.
  3. Usa el add-on de ESPHome en Home Assistant para flashear y gestionar el ESP32.
  4. HA controla el brillo mediante la integración ESPHome — sin I2C directo desde el host RPi.

See: AC Dimmer with Home Assistant and ESPHome

Si ejecutas Home Assistant supervised en Raspberry Pi OS (no HA OS), el acceso I2C desde scripts Python no tiene restricciones y el enfoque con smbus2 funciona directamente.




Paso 7 — Ejecutar como servicio systemd

Para iniciar automáticamente el script de control del dimmer:

Crea /etc/systemd/system/dimmer.service:

ini
[Unit]
Description=DimmerLink Controller
After=multi-user.target
[Service]
Type=simple
ExecStart=/usr/bin/python3 /home/pi/dimmer_control.py
Restart=on-failure
User=pi
[Install]
WantedBy=multi-user.target

Habilita e inicia:

bash
sudo systemctl daemon-reload
sudo systemctl enable dimmer.service
sudo systemctl start dimmer.service



Otros SBC Linux

El mismo enfoque funciona en cualquier SBC Linux con I2C:

Placa Bus I2C Comando de detección Notas
Raspberry Pi 3/4/5 /dev/i2c-1 i2cdetect -y 1 Estándar
Raspberry Pi Zero 2W /dev/i2c-1 i2cdetect -y 1 Estándar
Orange Pi Zero 2 /dev/i2c-3 i2cdetect -y 3 Depende del modelo
Rock Pi 4 /dev/i2c-7 i2cdetect -y 7 Depende del modelo
Banana Pi M2 /dev/i2c-1 i2cdetect -y 1 Estándar
Jetson Nano /dev/i2c-1 i2cdetect -y 1
HA OS en RPi No accesible Usa ESP32 + DimmerLink

Para encontrar buses I2C disponibles en cualquier placa Linux:

bash
ls /dev/i2c-*

Para Orange Pi y Banana Pi, habilita I2C mediante armbian-config:

bash
sudo armbian-config
# System → Hardware → enable i2c

En Python, pasa el número de bus correcto a SMBus():

python
bus = SMBus(3)  # para /dev/i2c-3 en Orange Pi Zero 2



Errores frecuentes

Problema Causa Solución
i2cdetect no muestra nada en 0x50 DimmerLink aún en modo UART Cambiar con 02 5B vía UART
OSError: [Errno 121] Sin pull-up / cableado incorrecto Verificar conexiones SDA/SCL
PermissionError: /dev/i2c-1 Usuario no en grupo i2c sudo usermod -aG i2c $USER
i2cdetect se cuelga (sin salida) El modo UART lleva SDA a nivel bajo Cambiar DimmerLink a modo I2C primero
Parpadeo por jitter del RPi OS Intento de control TRIAC directo Se necesita DimmerLink — los GPIO del RPi no pueden hacer corte de fase
RPi Zero 2W I2C lento Modo de baja velocidad Establecer smbus2.SMBus(1, force_open=True) o reducir la longitud del cable



Checklist rápido

  • ☐ DimmerLink cambiado a modo I2C (`02 5B` vía UART)
  • ☐ I2C habilitado en `raspi-config` (o `armbian-config`)
  • ☐ `i2cdetect -y 1` muestra la dirección `50`
  • ☐ Usuario agregado al grupo `i2c` (`sudo usermod -aG i2c $USER`)
  • ☐ `pip install smbus2` completado
  • ☐ `bus.write_byte_data(0x50, 0x10, 50)` cambia el brillo de la lámpara



  • Artículos relacionados



    ¿Todavía tienes preguntas?

    Ask on forum.rbdimmer.com or open a GitHub Issue.

    Compartir esta publicación
    Iniciar sesión para dejar un comentario