Control brightness of external monitors on Linux
Until now I only knew the convenient feature from my laptop, where I can simply press a hotkey to adjust the brightness of the built in screen. But what about external monitors? Can I adjust the brightness without fiddling with the on-screen menu?
Turns out I can, and the secret sauce I need is called Display Data Channel (DDC).
The hardware
Whether DDC works properly depends on many different variables like the monitor, display connection, GPU,… Here is the list of hardware that worked for me:
- Desktop:
- GPU: Nvidia GTX 1070 (with proprietary driver)
- Monitor 1: Dell U2715H
- Monitor 2: Dell U2414H
- Both monitors are connected via DisplayPort (HDMI did not work)
- Laptop:
- Dell XPS 13 9370
- Anker USB-C to HDMI Adapter (Model A8306)
- No-name USB-C hub with HDMI (couldn’t find a modelnumber; Uses a VIA chip according to
dmesg
) - Monitor 1: Dell U2715H
- Monitor 2: Dell U2414H
- All monitors connected via HDMI
Of course, DDC has to be enabled in the on-screen menu of the monitor (“Others” -> “DDC/CI” on my Dells).
The software
The tool you need is ddcutil. It is available in the Ubuntu repositories and on Arch Linux via the AUR. On Arch Linux I had to make a few adjustments to get it working:
- Load the
i2c-dev
kernel module withmodprobe i2c-dev
. To make this change persistent across reboots:echo i2c_dev >> /etc/modules-load.d/ddc.conf
- Create group
i2c
:groupadd i2c
- Create udev rules to allow group
i2c
read and write access to/dev/i2c-*
:cp /usr/share/ddcutil/data/45-ddcutil-i2c.rules /etc/udev/rules.d/
- Add your user to the
i2c
group:usermod $USER -aG i2c
After a reboot ddcutil detect
should detect the monitors. If it does not, check the documentation.
Some devices need special tweaking, e.g. the Raspberry Pi.
One more tip: The output of ddcutil environment
suggests that it is not necessary to load i2c-dev
when using proprietary Nvidia drivers.
However, without i2c-dev
(and with special Nvidia driver settings) ddcutil could not detect any monitors.
Examples
Settings like color corrections, orientation of the on-screen menu and the input source can be adjusted through DDC.
ddcutil capabilities
shows a list of supported options.
The following examples adjust and read the brightness of the monitor:
- Get the brightness of the first display:
ddcutil getvcp 10 --display 1
- Set the brightness of the second display to 100%:
ddcutil setvcp 10 100 --display 2
- Decrease the brightness of the second display by 5%:
ddcutil setvcp 10 - 5 --display 2
- Increase the brightness of the first display by 5%:
ddcutil setvcp 10 + 5 --display 1
I mapped these commands to some hotkeys in my i3 config.