View Single Post
Old 02-18-2023, 03:58 AM   #1
jmacindoe
Junior Member
jmacindoe began at the beginning.
 
Posts: 4
Karma: 10
Join Date: Feb 2023
Device: Kobo Libra H2O, Kobo Clara 2E
Using a Bluetooth keyboard with recent Kobos

Recent Kobos have Bluetooth so we can use a physical keyboard. I'm using this to turn my Kobo into an eink writing device but you can also use it in the Nickel web browser, to turn pages, or even in X11

I've only tested this with a Kobo Clara 2E and a Logitech POP KEYS keyboard, but I expect it would work for other Bluetooth devices. I'm guessing even a mouse would work in X11.

Setup
Setup is quite technical! If you're not familiar with the linux command line, you might have a tough time.
1. You'll need SSH access to your device e.g. using the SSH server built into KOReader. I like to do it over USB because it's more stable than WiFi https://www.mobileread.com/forums/sh...d.php?t=254214
2. Download the uhid.ko kernel module for your device from https://github.com/jmacindoe/kobo-kernel-modules/
3. Copy it to your device by plugging your Kobo into your computer, or use SSH to copy it wirelessly
Code:
scp uhid.ko root@192.168.2.2:/mnt/onboard/
4. Insert the module into the kernel
Code:
insmod /mnt/onboard/uhid.ko
5. Pair the keyboard. Pairing in Nickel didn't work for my keyboard but you can do it on the command line. You only have to pair it once, and then connecting/disconnecting each time can be done in Nickel. To pair, first go into the Bluetooth settings in Nickel and make sure bluetooth is turned on. Then run the command `bluetoothctl`. Inside the bluetoothctl prompt, run the following commands.
Code:
bluetoothctl
[bluetooth]# power on
Changing power on succeeded
[bluetooth]# discoverable on
Changing discoverable on succeeded
[bluetooth]# pairable on
Changing pairable on succeeded
[bluetooth]# agent NoInputNoOutput
Agent registered
If it says "Agent is already registered", run
Code:
[bluetooth]# agent off
Agent unregistered
[bluetooth]# agent NoInputNoOutput
Agent registered
Now run
Code:
[bluetooth]# default-agent 
Default agent request successful
Now we need the Bluetooth address of your keyboard. Put the keyboard in pairing mode and inside bluetoothctl run
Code:
[bluetooth]# scan on
Once you see the address show up, run `pair` with that address
Code:
[bluetooth]# pair 59:A0:E4:69:24:7B [replace with your address]
Pairing successful
This is what worked for my keyboard. If doesn't work for you, I'd suggest trying different 'agents'. These describe the tactic Bluetooth will use to pair securely (e.g. enter a 6 digit code, etc). Normally for my keyboard, MacOS/Android/etc will give me a 6 digit code I need to type on the keyboard to pair, however I couldn't get this to work with the Kobo. 'NoInputNoOutput' is designed for devices with no input or output, where you can't type a code, and so it pairs without any codes. Fortunately this worked with my keyboard. I'm not sure if it works with every keyboard, but I hope so.

You can check if your device is paired and connected using
Code:
info 59:A0:E4:69:24:7B [replace with your address]
We want to see
Code:
	Paired: yes
	Connected: yes
And if you ever forget that address you can see it again by running "paired-devices" in bluetoothctl.

Once paired, you should never need to do this pairing process again, but you will need to 'connect' each time. In Bluetooth terminology, pairing is the thing you do once so the devices know about each other, connecting is what you need to do everytime you use the device.

You should be able to connect using Nickel, or in the bluetoothctl prompt, run
Code:
connect 59:A0:E4:69:24:7B [replace with your address]
My keyboard can be paired with up to 3 different devices and there are three buttons to switch between devices. On my keyboard, after I start the connect from bluetoothctl, I need to press one of these buttons (the one I paired with) for the connect to complete. This is the same in Nickel: it won't connect unless I press the button on the keyboard.

6. Once paired and connected, you should get a new input event device at /dev/input/event3. Try running `cat /dev/input/event3` and press some keys on your keyboard. You should see some random output. It's working! Press Ctrl-C to exit that. You can also see info about your device by running `cat /proc/bus/input/devices`.
7. Once everything is looking good, let's set it up so uhid.ko loads on start up. Otherwise you'll have to run `insmod uhid.ko` after every restart.
First we will move the module onto the root filesystem. The onboard storage may not be mounted yet during startup, so it's safer this way.
Code:
mkdir /usr/local/modules
mv /mnt/onboard/uhid.ko /usr/local/modules/uhid.ko
Now we tell the OS to insert the module on every boot
Code:
echo KERNEL==\"loop0\", RUN+=\"/bin/sh -c \'insmod /usr/local/modules/uhid.ko\'\" > /etc/udev/rules.d/99-modules.rules
This will create a file `/etc/udev/rules.d/99-modules.rules` with contents
Code:
KERNEL=="loop0", RUN+="/bin/sh -c 'insmod /usr/local/modules/uhid.ko'"
which will get udev to insert the module for us on boot.

Using it in Nickel
It seems like the keyboard "just works" in Nickel 🎉. I don't use Nickel much so I haven't tested it a lot but it worked for me in search, the browser, the reader, etc.

Using it in KOReader
KOReader kills the bluetooth on launch here and here. But even if we remove that, it seems KOReader still doesn't make use of the keyboard. No doubt this could be fixed. I'll update this section if anyone gets it working!

Using it in X
You can set up X on you Kobo by following the instructions here. These commands will get the keyboard working (thanks to elinkser for first posting about this here).
1. Install udev
Code:
apk add eudev
apk add eudev-hwids
2. Launch udev. This must be done after every reboot before starting X.
Code:
udevd -d
udevadm trigger
3. Launch X
4. Hopefully the keyboard is working! If not, check /dev/input/event3 exists and check libinput can see it by running `DISPLAY=:0 libinput debug-events`

Keyboard on non-Bluetooth Kobos
I haven't tested this myself, but I think you could get the above instructions working on non-Bluetooth Kobos by having a keyboard plugged into another computer (e.g. Rasberry Pi) and then streaming the keyboard events over WiFi as detailed here
It also looks like you can theoretically use a USB keyboard, but the Kobo USB port isn't powered, so powering the keyboard is tricky, and you'll also need to compile a new kernel. So it's not very practical. See https://github.com/olup/kobowriter if interested.
inkvt also has some nice tricks for streaming keyboard events over the network.
jmacindoe is offline   Reply With Quote