First of all, may I say "Thank you" for helping your friend like that? I cannot think of a better way to use an Arduino than as a driver for a Braille display like you describe!
As you know, Braille is a representation of characters into a "shape" that many systems don't recognise. Most people only encounter Braille when they press a button on an elevator or an ATM and see raised dots. Nevertheless, this is MUCH easier than the system that deaf people use: they represent whole words with a hand gesture.
I hereby challenge EVERY reader of this post to enter an elevator, or look at an ATM, and notice (and decode!) the Braille dots on the buttons. Elevators for some reason use the double coding "#1
", "#2
", "#3
" etc. (as described in the question's graphic) when it is clearly unnecessary - of course you want to press a floor number! ATM buttons just use the 'raw' number pattern.
Because in Braille each character is converted into its own representation, you can do a VERY simple conversion. If you think about it, it is happening in computers trillions of times a day: when a computer converts a keypress into a set of pixels that represent the character on a computer screen. Your "pixels" are just a WHOLE lot simpler than the 5x7, 13x15 or font-specific conversion for the characters that normal-sighted people see.
The first thing that you need to do is define a system that converts the 2x3 array into an array of bits. Why? To make storage easier. I'm going to represent the Braille cell with a set of digits from 0
to 5
:
0 1
2 3
4 5
Why? Because it is then possible to "compress" the representation into a single byte of data. If you know computing well enough, you know that it runs in binary, and each digit above can be represented in a single bit, numbered 0-5.
Thus A
is represented by raising the top left pin, which is the same as bit 0
: which can be represented by the byte B000001
or 0x01
:
X .
. .
. .
Of course a space, with nothing raised, would be represented by B000000
or 0x00
.
You may not know this, and most computing people wouldn't either: the next "obvious" encoding (for B
) would be B000010
or 0x02
:
. X
. .
. .
But a blind person would have a serious difficulty in decoding this, since in isolation (no way of interpreting the "down" pins) it would look exactly like an 'A'. So the fact that 'B' is encoded as:
X .
X .
. .
means that the binary encoding would be B000101
or 0x05
.
As a further example, the character 'I' would be
. X
X .
. .
or the byte B000110
or 0x06
.
I'm not going to convert every character, but I hope that this explains things well enough for you. By giving every character its own bit pattern, you can then convert any possible string into a set of bytes for conversion by your library.
Only... there's a problem. With Braille, you need to convert numbers 0
to 9
into a special pattern. Because Braille only has 6 'bits' to choose from (and even then not every combination is "nice" for blind people to read), there is a special "flag" character to say "the following characters are digits!" (and a pattern to say "OK, back to normal letters again").
This means that there is not a one-to-one translation between an English string of characters, and the resultant string of bytes to represent those characters in Braille: you need to add extra "convert" bytes to the process. Of course these "convert" bytes can also be represented by the same bitmap as described above:
. X
. X
X X
is equal to B111010
or 0x3A
.
That means that it is possible to write a function to convert a series of ASCII characters into a series of Braille bytes: you just need to provide more bytes than the string converts! This also means that you may need to use less than 14 characters from the source before you run out of room on the display...
I would love to give you my address for more help: I'm afraid that StackExchange won't let me post my e-mail address!