Refreshing multiple e-ink displays on Linux using Python
At my desk at home, I have a pair of e-ink displays – a Dasung Paperlike 253 and a Boox Mira 13.3".
In a previous post I covered a how I refresh these on the Windows machine I use for work. While a bit of a hack, it works in a pinch.
When using my own laptop, on the other hand, I have much greater freedom. A pair of Python scripts allow me to control either or both of the monitors.
Boox have written their own Electron app for controlling Boox Mira and Boox Mira Pro displays. It’s hot garbage.
Not being big on JS, I decided to reimplement some of this functionality in Python using
pyusb. For now it’s just a couple of scripts: one for refreshing the display, the other for turning off the frontlight. I’ve created a repo, which I’ll be adding to when I get the time.
Dasung Paperlike 253
While communicating with the Paperlike is slightly more involved, the work had already been done for me. Philip Metzler has written a great Python script, which makes use of
pyserial to control the monitor.
Unfortunately, getting the script to run for the first time was a learning experience, to say the least.
The script needs the monitor’s device file. Something like
python ./dasung253.py --port /dev/ttyUSB0 --clear
Although I quickly identified the monitor could be found at
/dev/ttyUSB0 when connected via USB, it would disconnect shortly after. Running
sudo dmesg | grep tty confirmed this.
[ 2553.808793] usb 1-1.4.1: ch341-uart converter now attached to ttyUSB0 [ 2556.138673] ch341-uart ttyUSB0: ch341-uart converter now disconnected from ttyUSB0
After some very confused googling, I discovered the package
brltty was interfering. Although it’s a package for driving refreshable braille displays, the daemon it runs in the background was (mis)identifying the Paperlike from the CH340 serial converter chip it uses. Based on this thread, it appears the CH340 is used by a specific Braille eReader and
brltty therefore has conflicting udev rules for this device.
To solve this I had two options:
- Remove the package completely with a simple
sudo apt remove brltty.
- Change the udev rules.
Since I’m not planning on using any braille screens anytime soon, I opted for the former.
As a final hurdle, I also hit a permissions error trying to access
/dev/ttyUSB0. To access this device my user had to be added to the
sudo adduser cyclist dialout.
However, once I’d done that and rebooted, the script worked like a charm!
Bringing it all together
To refresh both displays (near) simultaneously. I call them both with a Bash script.
#!/usr/bin/env bash /home/cyclist/scripts/mira-refresh.py python /home/cyclist/scripts/dasung253.py --port /dev/ttyUSB0 --clear
I then bind this to a shortcut in Gnome Settings: Settings > Keyboard > Keyboard Shortcuts > View and customise shortcuts. I’ve chosen to bind this to Shift+Alt+R (for refresh)
Calling the scripts individually
There are also times where I only want to refresh one of the displays. After all, I generally don’t have the same windows open on both screens and therefore I may only want to clear ghosting/sharpen the image on one of them.
For this, I’ve used the same technique as above, but this time each shortcut calls its respective refresh script.
- Paperlike 253 = Shift+Alt+P
- Boox Mira = Shift+Alt+B
Notice that I’ve used the initial letter from each monitor’s name to help me remember the shortcut.
Conveniently, because I use the Miryoku layout on all my keyboards, P and B are right next to each other. They’re also in the same configuration as my physical monitors – Paperlike on the left, Boox Mira on the right.
I’m pretty stoked at how simple it is to control these displays with just a few lines of Python! Having these shortcuts set up has made a world of difference in usability. Next up I’d like to expand what my scripts can do with the Boox Mira (i.e. controlling contrast, refresh rate, etc.) and making my Bash script a little smarter, so that it can handle when new monitors are plugged in/unplugged and the device files change.
#linux #e-ink #python