Skip to content

benkne/tolino-controller

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Tolino Presenter Bridge

Turn pages on a Tolino e-reader with a wireless presenter remote. A Raspberry Pi sits between the two: it reads the presenter's button presses and forwards them to the Tolino over USB/ADB as taps on the page edges — fully headless, starts at boot, recovers from unplugs on its own.

The Tolino stays stock: no root, no custom firmware, nothing installed on the device. The only change on the reader is enabling USB debugging via the built-in debug menu — it keeps working as a completely normal e-reader. Everything else happens host-side on the Pi.

[Logitech presenter] --2.4 GHz--> [USB dongle]
                                       |
                               [Raspberry Pi]
                    evdev → tolino_presenter.py → adb
                                       |
                                       |  USB (also charges the Tolino)
                                       v
                              [Tolino Shine 2 HD]

Why not just use a Bluetooth page-turner clicker?

Two hardware facts about the Tolino Shine 2 HD make the usual solutions impossible:

  • No Bluetooth. Off-the-shelf BLE page-turner remotes have nothing to pair with.
  • Infrared touchscreen, not capacitive. The screen detects objects breaking an IR light grid, so capacitive tappers and conductive-foam contraptions do nothing.

The reliable way in is software: the Tolino runs Android 4.4 underneath, and with USB debugging enabled, adb shell input tap … turns pages in the stock reader app. This project automates exactly that.

What it handles for you

  • Persistent adb shell — one long-running shell instead of a ~200 ms adb process spawn per button press.
  • Sleep handling — Android 4.4 has no KEYCODE_WAKEUP; the daemon checks the screen state after idle periods and toggles KEYCODE_POWER only when the screen is really off.
  • Exclusive presenter grab — button presses don't leak into the console; works with the several event nodes a Logitech receiver exposes.
  • Self-healing — Tolino unplugged, presenter dongle removed, adb died: everything reconnects with backoff, and stale presses queued during an outage are dropped instead of replayed as a page-turn burst.
  • The "connected to PC" overlay — solved host-side, without rooting or touching the Tolino, see below.

The "connected to PC" problem

When connected to a host, the Tolino shares its storage as USB mass storage and shows a fullscreen "connected to PC" overlay — the reader is unusable while the cable is in, which is fatal for a permanently tethered setup.

The trick: the overlay disappears the moment the host ejects the volume (what Windows calls "safely remove") — Android unshares the storage, remounts it internally, the book comes back, and adb keeps working. A udev rule on the Pi does this automatically on every connect. No root or modification on the Tolino is needed.

Getting that rule right involves three genuinely non-obvious pitfalls (udev rule ordering, a meaningless eject exit code, and a share-timing race) — they are documented in AGENTS.md and in the comments of 99-tolino.rules.

Hardware

Component Tested with
E-reader Tolino Shine 2 HD (Android 4.4.2, 1072 × 1448 e-ink, IR touch)
Bridge Raspberry Pi 3B (any Linux box with USB host works)
Presenter Logitech R400/R500/R700/R800/Spotlight via 2.4 GHz dongle (any HID remote with arrow/page keys works)

One 5 V supply powers the Pi, and the Pi charges the Tolino through the same USB cable that carries adb.

Quick start

On the Tolino: enter the debug code in the search field (1123581321 for firmware ≤ 15.x, 112358132fb for 16.x), set Environment → prod (debuggable) and enable USB debugging.

On the Pi:

sudo apt update
sudo apt install -y python3-evdev adb eject

# udev rules first: adb permissions + auto-eject of the storage share
sudo cp 99-tolino.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules

# Pair with the same identity the service uses (root, HOME=/root).
# Accept the authorization prompt on the Tolino.
sudo mkdir -p /root/.android
echo '0x1f85' | sudo tee -a /root/.android/adb_usb.ini
sudo -H adb kill-server
sudo -H adb devices        # must show 'device'

# Install daemon + service
sudo cp tolino_presenter.py /usr/local/bin/
sudo chmod +x /usr/local/bin/tolino_presenter.py
sudo cp tolino-presenter.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now tolino-presenter.service

Verify: replug the Tolino's USB cable — the "connected to PC" overlay must disappear by itself within a few seconds. journalctl -u tolino-presenter -f should show adb shell ready and Presenter found, and a button press should turn the page.

The full installation runbook with verification steps and the reasoning behind every step is in AGENTS.md.

Configuration

Everything lives in constants at the top of tolino_presenter.py: tap coordinates (preset for the stock reader on a 1072 × 1448 screen), the presenter name hints, the key map, debounce and reconnect timings.

Troubleshooting

Symptom Fix
adb devices shows no permissions Install 99-tolino.rules (only affects non-root adb; the service runs as root)
"Connected to PC" overlay stays One-off: sudo eject /dev/sdX. Debug recipe in AGENTS.md
ADB gone after Tolino reboot Debug mode may not persist on some firmware — re-enter the debug code
Garbled serial in adb devices Known Tolino quirk (non-ASCII serial), cosmetic only

Repository layout

tolino_presenter.py        The daemon (evdev → adb)
tolino-presenter.service   systemd unit (autostart, restart, adb server)
99-tolino.rules            Host udev rules: adb access + storage auto-eject
AGENTS.md                  Full technical documentation / runbook

About

Turn pages on a Tolino e-reader with a presenter remote. No root, stock firmware - a Raspberry Pi bridges HID presses to ADB taps.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages