Passa al contenuto

Controllo dimmer AC da Raspberry Pi tramite DimmerLink

Linux non fornisce controllo GPIO in tempo reale — il taglio di fase TRIAC diretto è impossibile senza un controller dedicato. DimmerLink risolve il problema: Raspberry Pi invia solo un livello di luminosità, DimmerLink gestisce la temporizzazione precisa.

In breve: Il taglio di fase TRIAC diretto dai GPIO di Raspberry Pi non è fattibile — il jitter dell'OS Linux è di 1–10 ms mentre la temporizzazione del TRIAC richiede < 100 µs. Usa DimmerLink come controller hardware: RPi scrive un valore di luminosità (0–100) all'indirizzo I2C 0x50, registro 0x10. Una riga in Python: bus.write_byte_data(0x50, 0x10, level).




Perché Raspberry Pi non può pilotare un TRIAC direttamente

La dimmerizzazione con taglio di fase attiva il gate del TRIAC con un ritardo preciso dopo ogni passaggio per lo zero AC (ogni 10 ms a 50 Hz). L'errore di temporizzazione ammissibile è inferiore a 100 µs per evitare sfarfallio visibile.

Raspberry Pi esegue Linux — un OS generico con scheduler preemptive, swap, driver di rete e attività GPU, tutti in competizione per il tempo CPU. La latenza degli interrupt GPIO in questo OS:

Condizione Latenza interrupt GPIO
Sistema inattivo 0,5–2 ms
Rete / USB attivi 2–10 ms
I/O su disco fino a 50 ms

Un jitter di 2 ms al 10 % di luminosità (finestra di attivazione di 9 ms) equivale al 22 % di variazione di luminosità — sfarfallio chiaramente visibile. Anche con il demone pigpio (GPIO basato su DMA, la migliore opzione disponibile) il jitter è tipicamente 200–500 µs — ancora sopra la soglia richiesta sotto carico reale.

Questa non è una limitazione specifica di Raspberry Pi. Qualsiasi SBC Linux (Orange Pi, Rock Pi, Jetson Nano, Banana Pi) ha lo stesso vincolo. Il controllo TRIAC in tempo reale su Linux richiede un patch kernel RT (poco pratico per uso amatoriale) o la delega della temporizzazione a un microcontrollore dedicato.

DimmerLink è quel controller dedicato. Gestisce il rilevamento passaggio per lo zero e l'attivazione del TRIAC su un Cortex-M0+ (famiglia STM32), raggiungendo < 50 µs di jitter indipendentemente dal carico CPU dell'host. Raspberry Pi gli comunica solo la luminosità desiderata — nessun requisito di temporizzazione.




Hardware necessario

  • Raspberry Pi 3, 4, 5 o Zero 2W (qualsiasi modello con I2C)
  • Modulo DimmerLink
  • Modulo dimmer AC rbdimmer (qualsiasi portata di corrente)
  • 2 × resistenze da 4,7 kΩ (pull-up I2C — spesso non necessarie su RPi 3/4)



Passo 1 — Impostare DimmerLink in modalità I2C

DimmerLink viene spedito in modalità UART di default. Impostalo in modalità I2C prima di collegarlo al Raspberry Pi.

Collega DimmerLink a un adattatore USB-UART (TX → RX, RX → TX, GND, VCC 3.3V). Su qualsiasi computer apri la porta a 115200 baud, 8N1, e invia:

text
Raw bytes: 02 5B

Risposta attesa: 00 (OK). Il dispositivo ora si avvia in modalità I2C dopo ogni accensione. (La modalità viene salvata in EEPROM.)




Passo 2 — Cablaggio


Raspberry Pi → DimmerLink (I2C)

Header GPIO Raspberry Pi DimmerLink Funzione
Pin 1 (3.3V) VCC Alimentazione
Pin 6 (GND) GND Massa
Pin 3 (GPIO2 / SDA) SDA Dati I2C
Pin 5 (GPIO3 / SCL) SCL Clock I2C

Resistenze di pull-up: Raspberry Pi 3/4/5 ha pull-up integrati da 1,8 kΩ su GPIO2 e GPIO3. Di solito sono sufficienti per cavi inferiori a 30 cm. Per cavi più lunghi o comunicazione instabile, aggiungi resistenze esterne da 4,7 kΩ da SDA e SCL a 3.3V.


DimmerLink → Modulo dimmer AC

DimmerLink Modulo 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.




Passo 3 — Abilitare I2C su Raspberry Pi

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

Dopo il riavvio, installa i2c-tools e verifica la connessione:

bash
sudo apt install i2c-tools
i2cdetect -y 1

Output atteso — indirizzo 50 visibile nella tabella:

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.




Passo 4 — Controllo con Python (smbus2)

Installa la libreria:

bash
pip install smbus2


Esempio minimo

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


Classe completa con gestione errori

python
from smbus2 import SMBus
import time
class DimmerLink:
    ADDR = 0x50
    REG_STATUS = 0x00
    REG_LEVEL  = 0x10  # luminosità 0-100%
    REG_CURVE  = 0x11  # 0=LINEAR, 1=RMS, 2=LOG
    REG_FREQ   = 0x20  # frequenza di rete (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):
        """Impostare la luminosità 0–100%."""
        level = max(0, min(100, level))
        self.bus.write_byte_data(self.ADDR, self.REG_LEVEL, level)
    def get_level(self) -> int:
        """Leggere la luminosità attuale."""
        return self.bus.read_byte_data(self.ADDR, self.REG_LEVEL)
    def set_curve(self, curve: int):
        """Impostare la curva di dimmerizzazione: 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:
        """Leggere la frequenza di rete (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"Frequenza di rete: {dimmer.get_frequency()} Hz")
        # Aumento graduale
        for level in range(0, 101, 5):
            dimmer.set_level(level)
            print(f"Luminosità: {level}%")
            time.sleep(0.1)
        # Impostare curva RMS per lampade a incandescenza
        dimmer.set_curve(1)  # 1 = RMS
        print("Curva: RMS (incandescenza)")
    else:
        print("DimmerLink non pronto — verificare il cablaggio e la modalità I2C")
    dimmer.close()


Controllo rapido da CLI (senza Python)

bash
# Impostare luminosità al 50%  (0x32 hex = 50 decimale)
i2cset -y 1 0x50 0x10 50
# Leggere luminosità attuale
i2cget -y 1 0x50 0x10
# Leggere frequenza di rete
i2cget -y 1 0x50 0x20



Passo 5 — Integrazione con Node-RED


Tramite nodo exec con comando i2cset

In un flusso semplice, usa exec per eseguire i2cset:

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

Nodo Function:

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


Tramite node-red-contrib-i2c

Installa il nodo:

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

Configura un nodo i2c out:

  • Address: 0x50
  • Command: 0x10 (registro)
  • Payload: il valore di luminosità (0–100) da msg.payload

Uno slider UI mappato su 0–100 controlla direttamente il dimmer.




Passo 6 — Home Assistant OS su Raspberry Pi

Se Raspberry Pi esegue Home Assistant OS (non Home Assistant su Raspberry Pi OS), l'accesso hardware I2C dagli add-on è limitato dal modello a container di HA OS.

Approccio consigliato:

  1. Mantieni il Raspberry Pi come server HA.
  2. Aggiungi un ESP32 con DimmerLink separato come controller hardware.
  3. Usa l'add-on ESPHome in Home Assistant per flashare e gestire l'ESP32.
  4. HA controlla la luminosità tramite l'integrazione ESPHome — senza I2C diretto dall'host RPi.

See: AC Dimmer with Home Assistant and ESPHome

Se stai usando Home Assistant supervised su Raspberry Pi OS (non HA OS), l'accesso I2C dagli script Python non è limitato e l'approccio con smbus2 funziona direttamente.




Passo 7 — Eseguire come servizio systemd

Per avviare automaticamente lo script di controllo 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

Abilita e avvia:

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



Altri SBC Linux

Lo stesso approccio funziona su qualsiasi SBC Linux con I2C:

Scheda Bus I2C Comando di rilevamento Note
Raspberry Pi 3/4/5 /dev/i2c-1 i2cdetect -y 1 Standard
Raspberry Pi Zero 2W /dev/i2c-1 i2cdetect -y 1 Standard
Orange Pi Zero 2 /dev/i2c-3 i2cdetect -y 3 Dipende dal modello
Rock Pi 4 /dev/i2c-7 i2cdetect -y 7 Dipende dal modello
Banana Pi M2 /dev/i2c-1 i2cdetect -y 1 Standard
Jetson Nano /dev/i2c-1 i2cdetect -y 1
HA OS su RPi Non accessibile Usa ESP32 + DimmerLink

Per trovare i bus I2C disponibili su qualsiasi scheda Linux:

bash
ls /dev/i2c-*

Per Orange Pi e Banana Pi, abilita I2C tramite armbian-config:

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

In Python, passa il numero di bus corretto a SMBus():

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



Errori frequenti

Problema Causa Soluzione
i2cdetect non mostra nulla in 0x50 DimmerLink ancora in modalità UART Commutare con 02 5B via UART
OSError: [Errno 121] Nessun pull-up / cablaggio errato Verificare le connessioni SDA/SCL
PermissionError: /dev/i2c-1 Utente non nel gruppo i2c sudo usermod -aG i2c $USER
i2cdetect si blocca (nessun output) La modalità UART tiene SDA a livello basso Commutare DimmerLink in modalità I2C prima
Sfarfallio per jitter dell'RPi OS Tentativo di controllo TRIAC diretto Serve DimmerLink — i GPIO dell'RPi non possono fare il taglio di fase
RPi Zero 2W I2C lento Modalità bassa velocità Impostare smbus2.SMBus(1, force_open=True) o ridurre la lunghezza del cavo



Checklist rapida

  • ☐ DimmerLink impostato in modalità I2C (`02 5B` via UART)
  • ☐ I2C abilitato in `raspi-config` (o `armbian-config`)
  • ☐ `i2cdetect -y 1` mostra l'indirizzo `50`
  • ☐ Utente aggiunto al gruppo `i2c` (`sudo usermod -aG i2c $USER`)
  • ☐ `pip install smbus2` completato
  • ☐ `bus.write_byte_data(0x50, 0x10, 50)` modifica la luminosità della lampada



  • Articoli correlati



    Hai ancora domande?

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

    Condividi articolo
    Accedi per lasciare un commento