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:
Raw bytes: 02 5BRespuesta 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
sudo raspi-config
# Interface Options → I2C → Enable → OK → Finish
sudo rebootTras reiniciar, instala i2c-tools y verifica la conexión:
sudo apt install i2c-tools
i2cdetect -y 1Salida esperada — la dirección 50 visible en la tabla:
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:
pip install smbus2Ejemplo mínimo
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
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)
# 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 0x20Paso 5 — Integración con Node-RED
Mediante nodo exec con comando i2cset
En un flujo simple, usa exec para ejecutar i2cset:
[inject: level=50] → [function: construir comando] → [exec] → [debug]Nodo Function:
var level = msg.payload; // 0-100
msg.payload = "i2cset -y 1 0x50 0x10 " + level;
return msg;Mediante node-red-contrib-i2c
Instala el nodo:
cd ~/.node-red
npm install node-red-contrib-i2cConfigura 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:
- Mantén el Raspberry Pi como servidor de HA.
- Agrega un ESP32 con DimmerLink separado como controlador de hardware.
- Usa el add-on de ESPHome en Home Assistant para flashear y gestionar el ESP32.
- 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:
[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.targetHabilita e inicia:
sudo systemctl daemon-reload
sudo systemctl enable dimmer.service
sudo systemctl start dimmer.serviceOtros 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:
ls /dev/i2c-*Para Orange Pi y Banana Pi, habilita I2C mediante armbian-config:
sudo armbian-config
# System → Hardware → enable i2cEn Python, pasa el número de bus correcto a SMBus():
bus = SMBus(3) # para /dev/i2c-3 en Orange Pi Zero 2Errores 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
Artículos relacionados
- DimmerLink I2C not detected → DimmerLink Not Detected: I2C vs UART Mode
- Tasmota integration → Tasmota AC Dimmer via DimmerLink
- Home Assistant guide → AC Dimmer with Home Assistant and ESPHome
- ESPHome YAML → ESPHome YAML for AC Dimmer and DimmerLink
- Safety and wiring → AC Dimmer Safety: Mains Voltage, Isolation, and Wiring
¿Todavía tienes preguntas?
Ask on forum.rbdimmer.com or open a GitHub Issue.