TL;DR: I put a $5 Raspberry Pi Zero, a Bluetooth USB dongle, and the
required adapter cable into my new Handy Tech Active Star 40 braille
display. An internal USB port provides the power. This has transformed
my braille display into an ARM-based, monitorless, Linux laptop that has
a keyboard and a braille display. It can be charged/powered via USB so it can
also be run from a power bank or a solar charger, thus potentially being able
to run for days, rather than just hours, without needing a standard wall-jack.
Braille displays come in various sizes. There are
models tailored for desktop use (with 60 cells or more), models tailored
for portable use with a laptop (usually with 40 cells), and, nowadays,
there are even models tailored for on-the-go use with a smartphone or similar
(with something like 14 or 18 cells).
Back in the old days, braille displays were rather massive.
A 40-cell braille display was typically about the size of a 13" laptop.
In modern times, manufacturers have managed to reduce the size of the internals
such that a 40-cell display can be placed in front of a laptop or keyboard
instead of placing the laptop on top of the braille display.
While this is a nice achievement, I personally haven't found it to be
very convenient because you now have to place two physically separate
devices on your lap. It's OK if you have a real desk,
but, at least in my opinion, if you try to use your laptop as its name suggests,
it's actually inconvenient to use a small form factor, 40-cell display.
For this reason, I've been waiting for a long-promised new model
in the Handy Tech Star series. In 2002, they released
the Handy Tech Braille Star 40, which is a 40-cell braille
display with enough space to put a laptop directly on top
of it. To accommodate larger laptop models, they even built in a little
platform at the back that can be pulled out to effectively enlarge the
Handy Tech has now released a new model, the Active Star 40,
that has essentially the same layout but modernized internals.
You can still pull out the little platform to increase the space
that can be used to put something on top.
But, most conveniently,
they've designed in an empty compartment, roughly the size of a modern
smartphone, beneath the platform. The original idea was to actually
put a smartphone inside, but this has turned out (at least to me)
to not be very feasible. Fortunately, they thought about the
need for electricity and added a Micro USB cable terminating within the
newly created, empty compartment.
My first idea was to put a conventional Raspberry Pi inside.
When I received the braille display, however, we immediately
noticed that a standard-sized rpi is roughly 3mm too high
to fit into the empty compartment.
Fortunately, though, a co-worker noticed that the Raspberry Pi Zero
was available for order. The Raspberry Pi Zero is a lot thinner,
and fits perfectly inside (actually, I think there's enough space
for two, or even three, of them). So we ordered one, along with some
accessories like a 64GB SDHC card, a Bluetooth dongle, and
a Micro USB adapter cable. The hardware arrived a few days later, and was
immediately bootstrapped with the assistance of very helpful friends.
It works like a charm!
The backside of the Handy Tech Active Star 40 features two USB host ports
that can be used to connect devices such as a keyboard. A small form-factor,
USB keyboard with a magnetic clip-on is included. When a USB keyboard
is connected, and when the display is used via Bluetooth, the braille display
firmware additionally offers the Bluetooth HID profile, and key press/release
events received via the USB port are passed through to it.
I use the Bluetooth dongle for all my communication needs.
Most importantly, BRLTTY is used as a console screen reader.
It talks to the braille display via Bluetooth (more precisely, via an RFCOMM channel).
The keyboard connects through to Linux via the Bluetooth HID profile.
Now, all that is left is network connectivity. To keep the energy
consumption as low as possible, I decided to go for Bluetooth PAN.
It appears that the tethering mode of my mobile phone works (albeit with a quirk),
so I can actually access the internet as long as I have cell phone reception.
Additionally, I configured a Bluetooth PAN access point on my desktop
machines at home and at work, so I can easily (and somewhat more reliably)
get IP connectivity for the rpi when I'm near one of these machines.
I plan to configure a classic Raspberry Pi as a mobile Bluetooth access point.
It would essentially function as a Bluetooth to ethernet adapter, and should
allow me to have network connectivity in places where I don't want to use my phone.
It was a bit challenging to figure out how to actually configure
Bluetooth PAN with BlueZ 5. I found the bt-pan python script
(see below) to be the only way so far to configure PAN without a GUI.
It handles both ends of a PAN network, configuring a server and a client.
Once instructed to do so (via D-Bus) in client mode, BlueZ will
create a new network device - bnep0 - once a connection to a server has been
established. Typically, DHCP is used to assign IP addresses
for these interfaces. In server mode, BlueZ needs to know the
name of a bridge device to which it can add a slave device for
each incoming client connection. Configuring an address for
the bridge device, as well as running a DHCP server + IP Masquerading
on the bridge, is usually all you need to do.
I'm using systemd-networkd to configure the bridge device.
Now, BlueZ needs to be told to configure a NAP profile.
To my surprise, there seems to be no way to do this with stock BlueZ 5.36
utilities. Please correct me if I'm wrong.
Luckily, I found a very nice blog post, as well as an accommodating
Python script that performs the required D-Bus calls.
For convenience, I use a Systemd service to invoke the script
and to ensure that its dependencies are met.
Description=Bluetooth Personal Area Network
# Ugly hack to work around #787480
iptables -t nat -F
iptables -t mangle -F
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
exec /usr/local/sbin/bt-pan --systemd --debug server pan
This last file wouldn't be necessary if IPMasquerade= were
supported in Debian right now (see #787480).
After the obligatory systemctl daemon-reload and systemctl restart systemd-networkd,
you can start your Bluetooth Personal Area Network with systemctl start pan.
Configuring the client is also quite easy to do with Systemd.
Description=Bluetooth Personal Area Network client
ExecStart=/usr/local/sbin/bt-pan --debug --systemd client %I --wait
Now, after the usual configuration reloading, you should be able to connect
to a specific Bluetooth access point with:
systemctl start pan@00:11:22:33:44:55
Of course, the server and client-side service configuration require
a pre-existing pairing between the server and each of its clients.
On the server, start bluetoothctl and issue the following commands:
Once you've set scan mode to on, wait a few seconds until
you see the device you're looking for scroll by. Note its
device address, and use it for the pair and (optional) trust commands.
On the client, the sequence is essentially the same except that
you don't need to issue the trust command. The server needs
to trust a client in order to accept NAP profile connections from it
without waiting for manual confirmation by the user.
I'm actually not sure if this is the optimal sequence of commands.
It might be enough to just pair the client with the server
and issue the trust command on the server,
but I haven't tried this yet.
Essentially the same as above also needs to be done
in order to use the Bluetooth HID profile of the Active Star 40 on Linux.
However, instead of agent on, you need to issue the command agent KeyboardOnly.
This explicitly tells bluetoothctl that you're specifically looking for a HID profile.
While I'm very happy that I actually managed to set all of this up,
I must admit that the command-line interface to BlueZ feels
a bit incomplete and confusing. I initially thought that agents
were only for PIN code entry. Now that I've discovered that "agent KeyboardOnly"
is used to enable the HID profile, I'm not sure anymore.
I'm surprised that I needed to grab a script from a random git repository
in order to be able to set up PAN. I remember, with earlier version of BlueZ,
that there was a tool called pand that you could use to do all of this
from the command-line. I don't seem to see anything like that
for BlueZ 5 anymore. Maybe I'm missing something obvious?
The data rate is roughly 120kB/s, which I consider acceptable for such a low
The 1GHz ARM CPU actually feels sufficiently fast for a console/text-mode
person like me.
I'll rarely be using much more than ssh and emacs on it anyway.
The default dimensions of the framebuffer on the Raspberry Pi Zero are a bit
unexpectedly strange. fbset reports that the screen dimension
is 656x416 pixels (of course, no monitor connected). With a typical console
font of 8x16, I got 82 columns and 26 lines.
With a 40 cell braille display, the 82 columns are very inconvenient.
Additionally, as a braille user, I would like to be able to view Unicode
braille characters in addition to the normal charset on the console.
Fortunately, Linux supports 512 glyphs, while most console fonts
do only provide 256. console-setup can load and combine two
256-glyph fonts at once. So I added the following to /etc/default/console-setup
to make the text console a lot more friendly to braille users:
You need console-braille installed for brl-16x8.psf to be available.
There's a 3.5mm audio jack inside the braille display as well.
Unfortunately, there are no converters from Mini-HDMI to 3.5mm audio
that I know of. It would be very nice to be able to use the
sound card that is already built into the Raspberry Pi Zero,
but, unfortunately, this doesn't seem possible at the moment.
Alternatively, I'm looking at using a Micro USB OTG hub and an
additional USB audio adapter to get sound from the Raspberry Pi Zero
to the braille display's speakers. Unfortunately, the two USB audio
adapters I've tried so far have run hot for some unknown reason.
So I have to find some other chipset to see if the problem goes away.
A little nuisance, currently, is that you need to manually power off
the Raspberry, wait a few seconds, and then power down the braille display.
Turning the braille display off cuts power delivery via the internal USB port.
If this is accidentally done too soon then the Raspberry Pi Zero
is shut down ungracefully (which is probably not the best way to do it).
We're looking into connecting a small, buffering battery to the GPIO pins
of the rpi, and into notifying the rpi when external power has dropped.
A graceful, software-initiated shutdown can then be performed.
You can think of it as being like a mini UPS for Micro USB.
If you are a happy owner of a Handy Tech Active Star 40 and would like
to do something similar, I am happy to share my current
(Raspbian Stretch based) image. In fact, if there is enough interest by
other blind users, we might even consider putting a kit together that makes it
as easy as possible for you to get started. Let me know if this could be
of interest to you.
Thanks to Dave Mielke for reviewing the text of this posting.
Thanks to Simon Kainz for making the photos for this article.
And I owe a big thank you to my co-workers at Graz University
of Technology who have helped me a lot to bootstrap really quickly into the
My first tweet about this topic is just
five days ago, and apart from the soundcard not working yet, I feel
like the project is already almost complete! By the way, I am editing
the final version of this blog posting from my newly created monitorless
ARM-based Linux laptop via an ssh connection to my home machine.