Перейти к содержимому

Управление AC-диммером с Raspberry Pi через DimmerLink

Linux не обеспечивает управление GPIO в реальном времени — прямое фазовое управление TRIAC невозможно без выделенного контроллера. DimmerLink решает эту проблему: Raspberry Pi отправляет только уровень яркости, а DimmerLink обеспечивает точную синхронизацию.

Коротко: Прямое фазовое управление TRIAC через GPIO Raspberry Pi нереализуемо — джиттер Linux составляет 1–10 мс, а для синхронизации TRIAC требуется < 100 мкс. Используйте DimmerLink как аппаратный контроллер: RPi записывает значение яркости (0–100) на I2C-адрес 0x50, регистр 0x10. Одна строка на Python: bus.write_byte_data(0x50, 0x10, level).




Почему Raspberry Pi не может управлять TRIAC напрямую

Фазовое диммирование с отсечкой зажигает затвор TRIAC с точной задержкой после каждого перехода через ноль AC (каждые 10 мс при 50 Гц). Допустимая ошибка синхронизации — менее 100 мкс, иначе возникает заметное мерцание.

Raspberry Pi работает под Linux — ОС общего назначения с вытесняющим планировщиком, подкачкой, сетевыми драйверами и GPU-активностью, конкурирующими за процессорное время. Задержка прерываний GPIO в этой ОС:

Условия Задержка прерывания GPIO
Система в простое 0,5–2 мс
Активная сеть / USB 2–10 мс
Дисковый ввод-вывод до 50 мс

Джиттер 2 мс при яркости 10 % (окно зажигания 9 мс) равен 22 % вариации яркости — явно заметное мерцание. Даже с демоном pigpio (GPIO на базе DMA, лучший доступный вариант) джиттер обычно составляет 200–500 мкс — всё ещё выше допустимого порога при любой реальной нагрузке.

Это ограничение не специфично для Raspberry Pi. Любой Linux SBC (Orange Pi, Rock Pi, Jetson Nano, Banana Pi) имеет те же ограничения. Управление TRIAC в реальном времени под Linux требует либо патча ядра RT (непрактично для любительского использования), либо выноса синхронизации на выделенный микроконтроллер.

DimmerLink — это такой выделенный контроллер. Он выполняет детектирование перехода через ноль и зажигание TRIAC на Cortex-M0+ (семейство STM32), обеспечивая джиттер < 50 мкс независимо от нагрузки на CPU хоста. Raspberry Pi лишь сообщает желаемую яркость — никаких требований к синхронизации.




Необходимое оборудование

  • Raspberry Pi 3, 4, 5 или Zero 2W (любая модель с I2C)
  • Модуль DimmerLink
  • Модуль AC-диммера rbdimmer (любой номинал по току)
  • 2 × резистора 4,7 кОм (подтяжка I2C — часто не нужны на RPi 3/4)



Шаг 1 — Переключение DimmerLink в режим I2C

DimmerLink поставляется в режиме UART по умолчанию. Переключите его в режим I2C перед подключением к Raspberry Pi.

Подключите DimmerLink к USB-UART-адаптеру (TX → RX, RX → TX, GND, VCC 3.3V). На любом компьютере откройте порт на скорости 115200 бод, 8N1, и отправьте:

text
Raw bytes: 02 5B

Ожидаемый ответ: 00 (ОК). Теперь устройство стартует в режиме I2C после каждого включения питания. (Режим сохраняется в EEPROM.)




Шаг 2 — Схема подключения


Raspberry Pi → DimmerLink (I2C)

Разъём GPIO Raspberry Pi Любой ESP32 Функция
Пин 1 (3.3V) VCC Питание
Пин 6 (GND) GND Земля
Пин 3 (GPIO2 / SDA) SDA Данные I2C
Пин 5 (GPIO3 / SCL) SCL Тактовый сигнал I2C

Подтягивающие резисторы: Raspberry Pi 3/4/5 имеет встроенные подтяжки 1,8 кОм на GPIO2 и GPIO3. Обычно их достаточно при длине кабеля до 30 см. Для более длинных кабелей или при нестабильной связи добавьте внешние резисторы 4,7 кОм от SDA и SCL к 3.3V.


DimmerLink → Модуль AC-диммера

Любой ESP32 Модуль диммера
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.




Шаг 3 — Включение I2C на Raspberry Pi

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

После перезагрузки установите i2c-tools и проверьте подключение:

bash
sudo apt install i2c-tools
i2cdetect -y 1

Ожидаемый вывод — адрес 50 виден в таблице:

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.




Шаг 4 — Управление на Python (smbus2)

Установите библиотеку:

bash
pip install smbus2


Минимальный пример

python
from smbus2 import SMBus
DIMMER_ADDR = 0x50
REG_LEVEL   = 0x10  # DIM0_LEVEL — яркость 0–100%
bus = SMBus(1)  # Шина I2C 1 на Raspberry Pi
bus.write_byte_data(DIMMER_ADDR, REG_LEVEL, 50)  # установить 50%
bus.close()


Полный класс с обработкой ошибок

python
from smbus2 import SMBus
import time
class DimmerLink:
    ADDR = 0x50
    REG_STATUS = 0x00
    REG_LEVEL  = 0x10  # яркость 0-100%
    REG_CURVE  = 0x11  # 0=LINEAR, 1=RMS, 2=LOG
    REG_FREQ   = 0x20  # частота сети (50 или 60 Гц)
    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):
        """Установить яркость 0–100%."""
        level = max(0, min(100, level))
        self.bus.write_byte_data(self.ADDR, self.REG_LEVEL, level)
    def get_level(self) -> int:
        """Прочитать текущую яркость."""
        return self.bus.read_byte_data(self.ADDR, self.REG_LEVEL)
    def set_curve(self, curve: int):
        """Установить кривую диммирования: 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:
        """Прочитать частоту сети (50 или 60 Гц)."""
        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"Частота сети: {dimmer.get_frequency()} Гц")
        # Плавное нарастание
        for level in range(0, 101, 5):
            dimmer.set_level(level)
            print(f"Яркость: {level}%")
            time.sleep(0.1)
        # Установить кривую RMS для ламп накаливания
        dimmer.set_curve(1)  # 1 = RMS
        print("Кривая: RMS (лампы накаливания)")
    else:
        print("DimmerLink не готов — проверьте подключение и режим I2C")
    dimmer.close()


Быстрое управление из CLI (без Python)

bash
# Установить яркость 50%  (0x32 hex = 50 decimal)
i2cset -y 1 0x50 0x10 50
# Прочитать текущую яркость
i2cget -y 1 0x50 0x10
# Прочитать частоту сети
i2cget -y 1 0x50 0x20



Шаг 5 — Интеграция с Node-RED


Через узел exec с командой i2cset

В простом потоке используйте exec для выполнения i2cset:

text
[inject: level=50] → [function: собрать команду] → [exec] → [debug]

Узел Function:

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


Через node-red-contrib-i2c

Установите узел:

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

Настройте узел i2c out:

  • Address: 0x50
  • Command: 0x10 (регистр)
  • Payload: значение яркости (0–100) из msg.payload

Слайдер UI, привязанный к диапазону 0–100, напрямую управляет диммером.




Шаг 6 — Home Assistant OS на Raspberry Pi

Если Raspberry Pi работает под Home Assistant OS (а не Home Assistant на Raspberry Pi OS), доступ к I2C из дополнений ограничен контейнерной моделью HA OS.

Рекомендуемый подход:

  1. Оставьте Raspberry Pi в качестве сервера HA.
  2. Добавьте отдельный ESP32 с DimmerLink как аппаратный контроллер.
  3. Используйте аддон ESPHome в Home Assistant для прошивки и управления ESP32.
  4. HA управляет яркостью через интеграцию ESPHome — без прямого I2C с хоста RPi.

See: AC Dimmer with Home Assistant and ESPHome

Если вы используете Home Assistant supervised на Raspberry Pi OS (не HA OS), доступ к I2C из Python-скриптов не ограничен, и подход через smbus2 работает напрямую.




Шаг 7 — Запуск как служба systemd

Для автоматического запуска скрипта управления диммером:

Создайте /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

Активируйте и запустите:

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



Другие одноплатные компьютеры на Linux

Тот же подход работает на любом Linux SBC с I2C:

Плата Шина I2C Команда обнаружения Примечания
Raspberry Pi 3/4/5 /dev/i2c-1 i2cdetect -y 1 Стандартно
Raspberry Pi Zero 2W /dev/i2c-1 i2cdetect -y 1 Стандартно
Orange Pi Zero 2 /dev/i2c-3 i2cdetect -y 3 Зависит от модели
Rock Pi 4 /dev/i2c-7 i2cdetect -y 7 Зависит от модели
Banana Pi M2 /dev/i2c-1 i2cdetect -y 1 Стандартно
Jetson Nano /dev/i2c-1 i2cdetect -y 1
HA OS на RPi Недоступна Используйте ESP32 + DimmerLink

Для поиска доступных шин I2C на любой плате Linux:

bash
ls /dev/i2c-*

Для Orange Pi и Banana Pi включите I2C через armbian-config:

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

В Python передайте правильный номер шины в SMBus():

python
bus = SMBus(3)  # для /dev/i2c-3 на Orange Pi Zero 2



Частые ошибки

Проблема Причина Решение
i2cdetect не показывает 0x50 DimmerLink всё ещё в режиме UART Переключите командой 02 5B через UART
OSError: [Errno 121] Нет подтяжки / неправильное подключение Проверьте соединения SDA/SCL
PermissionError: /dev/i2c-1 Пользователь не в группе i2c sudo usermod -aG i2c $USER
i2cdetect зависает (нет вывода) Режим UART притягивает SDA к низкому уровню Сначала переключите DimmerLink в режим I2C
Мерцание из-за джиттера RPi OS Попытка прямого управления TRIAC Необходим DimmerLink — GPIO RPi не может выполнять фазовое управление
RPi Zero 2W медленный I2C Режим низкой скорости Установите smbus2.SMBus(1, force_open=True) или сократите длину кабеля



Краткий чек-лист

  • ☐ DimmerLink переключён в режим I2C (`02 5B` через UART)
  • ☐ I2C включён в `raspi-config` (или `armbian-config`)
  • ☐ `i2cdetect -y 1` показывает адрес `50`
  • ☐ Пользователь добавлен в группу `i2c` (`sudo usermod -aG i2c $USER`)
  • ☐ `pip install smbus2` выполнена
  • ☐ `bus.write_byte_data(0x50, 0x10, 50)` изменяет яркость лампы



  • Связанные статьи



    Остались вопросы?

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

    Поделиться этой записью
    Войти оставить комментарий