TL;DR: DimmerLink ships from the factory in UART mode.
i2cdetectwill not show address 0x50 until you send the SWITCH_I2C command (02 5B) over UART at 115200 baud. Also add 4.7 kΩ pull-up resistors on SDA and SCL — many boards do not have adequate built-in pull-ups. Set VCC to match your MCU logic voltage (5V, 3.3V, or 1.8V).
Symptom
You connect DimmerLink to your I2C bus, run i2cdetect -y 1
(or scan from Arduino), and either:
- the address grid is completely empty — address 0x50 is not shown;
- the scan takes much longer than usual or appears to hang.
Root Cause 1 — Wrong Mode (UART Active)
Every DimmerLink module leaves the factory in UART mode. In UART mode:
- the device does not monitor the I2C bus;
- the TX/SDA and RX/SCL pins behave as UART outputs;
- the device cannot respond to I2C addresses — it will never appear in a scan.
The I2C interface is only active after the mode has been switched to I2C. The mode is stored in EEPROM and persists across power cycles, so you only need to switch once.
Root Cause 2 — UART Mode Pulls I2C Bus Lines Low
When DimmerLink is in UART mode and connected to your I2C bus:
- The UART TX output is held logic high (idle state) — this is not a problem.
- Some UART implementations pull the output low between transmissions or during startup.
If the TX line (which is wired to SDA) goes low, it pulls the I2C SDA
line low. The I2C scanner sends a START condition on SDA and SCL,
but SDA stays low — the bus appears permanently busy. i2cdetect
will stall for several seconds per address before timing out, making
the scan appear to hang.
This is not a hardware fault — once DimmerLink is switched to I2C mode, SDA/SCL become true bidirectional I2C lines and the issue disappears.
Root Cause 3 — Missing Pull-Up Resistors
I2C requires external pull-up resistors on SDA and SCL. Without them the voltage on these lines cannot rise to logic high and the bus does not function.
| Board | Built-in I2C pull-ups | Adequacy |
|---|---|---|
| Raspberry Pi 3/4/5 | 1.8 kΩ (on-board) | Usually sufficient |
| Arduino Uno / Mega | ~50 kΩ (weak) | Insufficient — add external |
| ESP8266 / ESP32 | Weak (~50 kΩ) | Insufficient — add external |
| STM32 | None | Must add external |
| Raspberry Pi Pico | None | Must add external |
Required value: 4.7 kΩ from SDA to VCC, and 4.7 kΩ from SCL to VCC. Use the same VCC as DimmerLink (see below).
Root Cause 4 — VCC Voltage Mismatch
DimmerLink supports three supply voltages:
| VCC | Logic levels | Typical MCU |
|---|---|---|
| 5V | 5V TTL | Arduino Uno, Mega |
| 3.3V | 3.3V CMOS | ESP32, ESP8266, Raspberry Pi |
| 1.8V | 1.8V CMOS | Low-voltage MCUs |
Connect VCC to the same voltage as your MCU logic level. Do not mix: a 5V DimmerLink VCC connected to a 3.3V MCU will result in 5V signals on SDA/SCL, which may damage the MCU or cause logic errors.
There is no level converter needed — DimmerLink adapts to whatever VCC you supply.
Fix: Step-by-Step Switch to I2C Mode
What You Need
- USB-UART adapter (CP2102, CH340, FT232, or similar)
- Jumper wires
- Any serial terminal application
Step 1 — Connect DimmerLink to USB-UART Adapter
| DimmerLink pin | UART adapter pin |
|---|---|
| VCC | 3.3V output |
| GND | GND |
| TX/SDA | RX |
| RX/SCL | TX |
Wire TX to RX and RX to TX (crossed). Power from the adapter 3.3V output — do not use 5V if your UART adapter only provides 5V signals.
Step 2 — Open Serial Terminal
Configure: 115200 baud, 8 data bits, no parity, 1 stop bit (8N1).
Recommended terminals:
- Windows: RealTerm (HEX send mode)
- Linux/macOS:
picocom -b 115200 /dev/ttyUSB0
Step 3 — Send SWITCH_I2C Command
Send raw bytes: 02 5B
- In RealTerm: Send tab → Send Numbers field:
02 5B→ Send - On Linux/macOS — use the Python one-liner below (requires
pyserial):
python3 -c "
import serial
s = serial.Serial('/dev/ttyUSB0', 115200, timeout=1)
s.write(bytes([0x02, 0x5B]))
resp = s.read(1)
print('Response:', resp.hex() if resp else 'none')
s.close()
"Replace /dev/ttyUSB0 with your actual port (/dev/ttyACM0, /dev/ttyS0, etc.).
Install pyserial if needed: pip install pyserial.
Expected response: 00 (one byte, OK).
If no response:
- Check TX/RX are crossed (adapter TX → DimmerLink RX).
- Confirm baud rate is exactly 115200.
- Confirm VCC is connected.
Step 4 — Verify Mode Switch
After receiving 00, DimmerLink is now in I2C mode. Disconnect from
the UART adapter, wire for I2C, and scan:
Raspberry Pi:
i2cdetect -y 1Arduino:
#include <Wire.h>
void setup() {
Serial.begin(115200);
Wire.begin();
for (uint8_t addr = 1; addr < 127; addr++) {
Wire.beginTransmission(addr);
if (Wire.endTransmission() == 0) {
Serial.print("Found at 0x");
Serial.println(addr, HEX);
}
}
}Expected: address 0x50 found.
Wiring for I2C Operation
After switching to I2C mode, connect as follows:
Raspberry Pi
| RPi GPIO header | DimmerLink |
|---|---|
| Pin 1 (3.3V) | VCC |
| Pin 6 (GND) | GND |
| Pin 3 (GPIO2 / SDA) | TX/SDA |
| Pin 5 (GPIO3 / SCL) | RX/SCL |
RPi has 1.8 kΩ pull-ups on GPIO2/3 — usually sufficient for cables under 30 cm. Add 4.7 kΩ external pull-ups if communication is unreliable.
Arduino (Uno/Mega)
| Arduino | DimmerLink |
|---|---|
| A4 (SDA) | TX/SDA |
| A5 (SCL) | RX/SCL |
| 5V | VCC |
| GND | GND |
Add 4.7 kΩ pull-ups from A4 to 5V and from A5 to 5V.
ESP32
| ESP32 | DimmerLink |
|---|---|
| GPIO21 (SDA) | TX/SDA |
| GPIO22 (SCL) | RX/SCL |
| 3.3V | VCC |
| GND | GND |
Add 4.7 kΩ pull-ups from GPIO21 to 3.3V and GPIO22 to 3.3V.
I2C Pull-Up Wiring Diagram
VCC (match DimmerLink VCC)
│
├── 4.7kΩ ── SDA
│
└── 4.7kΩ ── SCLVerify Communication
Raspberry Pi (CLI)
# Read mains frequency (should return 50 or 60)
i2cget -y 1 0x50 0x20
# Set brightness to 50%
i2cset -y 1 0x50 0x10 50
# Read brightness back
i2cget -y 1 0x50 0x10Arduino
#include <Wire.h>
void setup() {
Serial.begin(115200);
Wire.begin();
// Set brightness to 50%
Wire.beginTransmission(0x50);
Wire.write(0x10); // DIM0_LEVEL register
Wire.write(50); // 50%
if (Wire.endTransmission() == 0) {
Serial.println("DimmerLink: brightness set to 50%");
} else {
Serial.println("Error: DimmerLink not responding");
}
}Python (Raspberry Pi)
from smbus2 import SMBus
try:
bus = SMBus(1)
freq = bus.read_byte_data(0x50, 0x20)
print(f"DimmerLink OK — mains frequency: {freq} Hz")
bus.close()
except OSError as e:
print(f"Not found: {e}")
print("Check: I2C mode switched, pull-ups installed, VCC correct")How to Switch Back to UART Mode
If you need to return to UART mode, write command 0x03
(SWITCH_UART) to the I2C COMMAND register (0x01):
Arduino:
Wire.beginTransmission(0x50);
Wire.write(0x01); // COMMAND register
Wire.write(0x03); // SWITCH_UART
Wire.endTransmission();
// I2C no longer works — reconnect via UARTRaspberry Pi:
i2cset -y 1 0x50 0x01 0x03
# Now control via UART onlyDiagnostic Flowchart
i2cdetect shows nothing at 0x50?
│
├── Is DimmerLink VCC connected and correct? → No → Connect VCC
│
├── Has SWITCH_I2C been sent (02 5B via UART)? → No → Send it
│
├── Are 4.7kΩ pull-ups on SDA and SCL? → No → Add them
│
├── Is SDA wired to SDA, SCL to SCL? → No → Fix wiring
│
└── Does i2cdetect hang (slow scan)?
→ UART mode active → Send SWITCH_I2C firstQuick Checklist
Related Articles
- Raspberry Pi setup → Raspberry Pi AC Dimmer via DimmerLink
- Tasmota setup → Tasmota AC Dimmer via DimmerLink
- ESPHome integration → ESPHome YAML for AC Dimmer and DimmerLink
- Home Assistant guide → AC Dimmer with Home Assistant and ESPHome
Still have questions?
Ask on forum.rbdimmer.com or open a GitHub Issue.