Braille Reader using Arduino
-
Upload
shubhanginipandey -
Category
Documents
-
view
245 -
download
0
Transcript of Braille Reader using Arduino
-
8/18/2019 Braille Reader using Arduino
1/16
Page 1111 of 16161616
TACTILE BRAILLE E-BOOK/E-TEXT READER
Rajarshi Roy ([email protected])
Angky William ([email protected])
December 15th, 2010
ECE 395: Advanced Digital Projects Laboratory
University of Illinois at Urbana Champaign
-
8/18/2019 Braille Reader using Arduino
2/16
Page 2222 of 16161616
Abstract:Abstract:Abstract:Abstract:
This report details the design concept and prototype implementation of a tactile Braille e-book/e-
text reader. The text is stored in the .txt file format inside a micro-SD card. An Arduino
Duemilanove micro-controller then reads this information to control a six-dot Braille cell using six
servos. A mouse scroll-wheel encoder is used at the bottom of the device so that the user can scrollforward or backward through the textual information by sliding the device on a flat surface to the
right or left respectively. This device opens up a much cheaper and complete platform for
education and knowledge transfer for the blind as compared to current technologies.
Introduction:Introduction:Introduction:Introduction:
Technology has revolutionized the daily life of people but it has particularly benefited visually
impaired individuals. Until recently, most print information such as newspapers, magazines, books
and such were of very limited accessibility due to the lack of widespread Braille publications. Only
recently have assistive technologies such as audio books and tactile Braille refreshable displays
allowed the access of information to the blind through the digital medium. However, current
technologies still have major drawbacks. For example, audio books only cover certain publications
and any piece of text cannot be accessed through them. Furthermore, this technology inaccessible
to the deaf-blind and does not provide intuitive control over the information flow. Tactile
refreshable Braille displays on the other hand overcome this problem by using refreshable tactile
Braille cells that are accessible to all due the use of touch. Furthermore, tactile Braille cells can berefreshed at the user's own pace allowing full control. However, most tactile Braille technologies
are extremely expensive, ranging from 5000 to 10000 dollars [1]. This cost factor makes this
technology impact-less in the blind community.
Our motivation for this project was to have a low-cost tactile Braille reader that can make digital
information widely accessible to the blind. The main cost factor of tactile Braille displays is the cost
of the actuators that raise or lower each Braille dot. In all current tactile Braille devices,
piezoelectric actuators are used which are very expensive [2]. Thus we based our design on using
servo motors which provide a precise actuation for a very cheap price. Also we used the ArduinoDuemilanove micro-controller to carry out all controls. This allows the device to be easily modified
from our current portable e-text reader design to a Braille output interface from software.
-
8/18/2019 Braille Reader using Arduino
3/16
Page 3333 of 16161616
Design:Design:Design:Design:
The main design consists of four parts: the micro-controller (Arduino Duemilanove) [3], the
encoder (a cheap old mouse scroll wheel), the Braille cell (six servos and some piano wire) and the
SD card reader (micro-SD/prototyping shield PCB from SparkFun.com) [4]. All circuitry was
soldered on the prototyping portion of the micro-SD/prototyping shield.
Figure 1: Top-right-back corner view of device
Figure 2: Top-left-front corner view of device
-
8/18/2019 Braille Reader using Arduino
4/16
Page 4444 of 16161616
The concept of the device is simple. Since there is only one Braille cell of 6 dots, the device can
only show one character in the text at a time. Thus, the user will not use the traditional method of
reading a Braille text by moving his fingers from left to right over a row of Braille characters. In
this design, the user will keep his finger on the Braille cell and move the device from left to right
on a flat surface to read the text. As the device is moved, the encoder wheel rotates, signaling the
micro-controller. After a certain threshold amount of movement, the Arduino refreshes the Braille
cell to the configuration of the next character in the text that is stored in the micro-SD card.
Similarly, the user can move the device from right to left to read the previous character, thus
allowing a bidirectional control over the reading of the text (Figure 3).
Figure 3: Reading text using the Braille e-book reader (left) as compared to reading traditional
Braille (right)
Thus, the overall data flow is as such:
the movement data from the encoder
and the text file from the micro-SD card
is processed by the Arduino to control
the six servos in the Braille cell.
Braille CellBraille CellBraille CellBraille Cell
The most important component of the device that distinguishes it from current tactile Braille
technology is the cheap Braille cell. The Braille cell is constructed using six servos (T-Pro SG90 at
$2.77 each) (Appendix C), some piano wire (0.040” at negligible cost) and a section of a perfboard.
Since the standard Braille specifications require that the spacing between two Braille dots to be
0.090” to 0.100” [5], it was a challenge to create a Braille cell that compact with servos that are
Encoder
Micro-SD card
Arduino Servos in Braille cell
-
8/18/2019 Braille Reader using Arduino
5/16
Page 5555 of 16161616
0.88”x 0.86”x0.45”. In our design, we made two stacks of three servos (Figure 4). Each stack
controls either the left or right vertical column of Braille dots. The Braille dots are basically the
rounded tips of the piano wire that is attached on the other end to the servo arm. The piano wire
passes through the holes of the perfboard and can thus move in or out through the holes. This
system converts the rotational motion of the servo arm into the translational motion of the Braille
dots (similar to the piston system of an internal combustion engine). The slight angle change of the
servo arm controlled by the Arduino determines the raised or lowered position of the Braille dot.
Figure 4: The left stack of three servos (4.1) control the left vertical column of Braille dots. The
Braille dots are the rounded tips of the three .040” piano wires (a), (b), (c) which are 3.3mm,
2.2mm, and 1.1 mm long respectively. A slight change in the angle of the lowest servo’s arm (d)
produces the translational displacement (e) to raise the bottom-left Braille dot (f). Image 4.2 shows
the actual implementation of the design and the corresponding dot pattern (4.3).
We were very lucky that the standard perfboard has holes which are 0.100” spaced apart [6] which
met the Braille specification exactly. The Braille cell was constructed by using glue-gun to attach
the parts together and a Dremel tool to cut the perfboard and round the tips of the piano wire. This
was the most time-consuming portion of our project.
The six servos are controlled by the digital pins 4(top left), 5(middle left), 6(bottom left), 7(top
right), 9(middle right), 10(bottom right). The servo library [7] provided online
in the Arduino playground was used. In the code (Appendix A), function braille() takes in a char
variable and controls the servos based on the Braille code. We decided to use the ‘#’ symbol to be
the special character that number follows.
4.1 4.2 4.3
-
8/18/2019 Braille Reader using Arduino
6/16
Page 6666 of 16161616
The circuit for the servo system (Figure 5) is very simple as all the servos’ power (red) and ground
(brown) are connected to the Arduino’s 5V and GND pin respectively. The signal wires (yellow) of
each servo are connected to their respective digital pins (10, 9, 7, 6, 5, 4).
Encoder Encoder Encoder Encoder
We attempted to use an optical mouse’s sensor to
sense the movement of the device. We managed
to interface a mouse’s optical chip to the Arduino.
However, it was difficult to integrate it into the
device due the precise height the chip and its lens
system needs to be above a surface. Thus, we
simplified things by using a mouse’s scroll wheel
mechanical encoder. The mechanical encoder has
three pins A, B and C with C being in the middlewhile A and B being at the sides. In the circuit, C
is connected to 5V from the Arduino while A and
B are pulled down to GND through 300 ohm
resistors (Figure 6).
Power
GND
Signal
Servo: bot. left
5V
GND
D10
Power
GND
Signal
Servo: mid left
5V
GND
D9
Power
GND
Signal
Servo: top left
5V
GND
D7
Power
GND
Signal
Servo: bot. left
5V
GND
D6
Power
GND
Signal
Servo: mid left
5V
GND
D5
Power
GND
Signal
Servo: top left
5V
GND
D4
Figure 5: Servo connections schematic
Figure 6: Encoder circuit
-
8/18/2019 Braille Reader using Arduino
7/16
Page 7777 of 16161616
When the encoder wheel is rotated, each A and B pins
produce pulse patterns which are at slight offsets [8]. This
pattern is actually etched into copper inside the
mechanical encoder. One interesting property of this
pattern is that when pin A has a rising or falling edge, pin
B will either be zero or one. Depending on which way the
encoder is rotated, the transition from zero to one (rising
edge) of pin A will correspond to a low or high value of
pin B. The Arduino code (Appendix A) uses polling to detect this. In the void loop() portion of the
Arduino code that always loops, the outermost if structure checks for a rising edge by comparing
the current value of A with the previous value of A. Then when a rising edge triggers the
conditional, the code checks the value of B and accordingly increments or decrements the
encoderPos variable. After certain threshold conditions that decide how much the device should be
moved before a change in the character, the next or previous character is fetched from the SD cardcode nested inside the encoder code.
SD card interfaceSD card interfaceSD card interfaceSD card interface
The SD card circuitry was entirely provided on the Sparkfun micro-SD shield that was bought
online [4]. The code uses the and libraries provided online [9] by Sparkfun
to access a byte in the SD card. We decided to use a .txt format to store our text in because each
character in the text has a one-to-one correspondence with each byte in the file system. Thus,reading a byte and then reading the next byte would directly mean reading a character and then
reading the next character.
The documentation of the library only had the .read() function that reads a byte and sets the
pointer to the next byte. Thus, initially we read a certain point in the file by reading through every
point until that point. However, this caused a lot of problem with large files like books because the
code was not fast enough. Thus, after searching through the code of the library we found a variable
CurrentPos in the SDFat library that determined which byte was being read. Luckily the library
even has an internal function .seekSet() which sets this value. Thus, using this function we could
directly jump to a point in the text based on the variable position that incremented or decremented
based on the movement of the ebook reader.
The data transfer between the SD card and Arduino uses the Arduino’s built-in SPI protocol pins
8(CS), 11(MOSI), 12(MISO), 13(SCK). The micro-SD shield was designed by sparkfun.com and its’
schematic is provided in Figure 7.
-
8/18/2019 Braille Reader using Arduino
8/16
Page 8888 of 16161616
Future work:Future work:Future work:Future work:
The size of the device can be made much smaller by using smaller servos and using custom PCB
with the ATMega328 chip and SD card integrated. We started working on this but could not finish
due to the lack of time. Also, an optical mouse chip can be used instead of the mouse encoder. This
would enable another mode of use whereby the mouse chip’s image is accessed and the Arduino
runs a simple optical character recognition program on it. The character recognized would
determine the Braille cell content, allowing the user to read printed text such as medicine expiry
labels. Finally, a feature that we could have added that we realized lately is a character number
storing system whereby the character number is continuously stored at the end of the file. Thus,
when the device is turned off and on again, the user can choose to continue reading from where he
last left off.
ConclusionConclusionConclusionConclusion and Acknowledgementsand Acknowledgementsand Acknowledgementsand Acknowledgements::::
This project was very enjoyable and we would like to thank Professor Lippold Haken and Zuofu
Cheng (big-time!) for their supervision and insights. We are grateful to the University of Illinois at
Urbana Champaign Department of Electrical and Computer Engineering for providing us with
every resource we needed including funding for parts, access to the ECE machine shop and ECE
service store.
Figure 7: micro-SD shield schematic [10]
-
8/18/2019 Braille Reader using Arduino
9/16
Page 9999 of 16161616
Refer Refer Refer Refereeeencesncesncesnces
[1] Accessibility: Refreshable Braille Displays
[2] Refreshable Braille Now and in the Years Ahead
[3] Arduino Duemilanove
[4] SparkFun electronics: microSD Shield
[5] Size and Spacing of Braille Characters
[6] Pre-Punched IC-Spacing Perfboard
[7] Arduino Playground-Servo
[8] Using Encoders
[9] SparkFun electronics: microSD Shield SdFat library
[10] SparkFun electronics: microSD Shield Schematic
-
8/18/2019 Braille Reader using Arduino
10/16
Page 10101010 of 16161616
Appendix AAppendix AAppendix AAppendix A
// OVERALL DEVICE CONTROL// crystallized into a big crystal with the// help of seed crystals (example codes):// http://www.sparkfun.com/tutorial/microSD_Shield/SD_SimpleExample.pde// http://www.arduino.cc/playground/ComponentLib/Servo
// ECE395 - Braille e-book/e-text reader
// Developers//// Rajarshi Roy: servo control, sd card reading, quadrature encoder// Angky William: the idea to structure the function braille()// based on each pin rather than each character, shortening the code greatly
//add servo library#include
//add sd card library#include
#include #include
//////sd card variables and objectsSd2Card card;SdVolume volume;SdFile root;SdFile file;
char name[] = "Test.txt"; // Create an array that contains the name of our file.
//////servo variables and objectsSoftwareServo servoltop; // create servo object to control left-top servoSoftwareServo servolmiddle; // create servo object to control left-middle servo
SoftwareServo servolbottom; // create servo object to control left-bottom servoSoftwareServo servortop; // create servo object to control right-top servoSoftwareServo servormiddle; // create servo object to control right-middle servoSoftwareServo servorbottom; // create servo object to control right-bottom servo//note that all servo.write() values were caliberated for our device. the same values//may not work for other builds
//////encoder variablesint encoderPinA = A0; // pin A of encoder hooked up to analog0int encoderPinB = A1; // pin B of encoder hooked up to analog1int encoderPos = 0; /* variable that increments or decrements based on
quadrature data*/int encoderPinALast = LOW; /* last value of pin A (used to detect rising edges)*/int n = LOW; /* current value of pin A (used to detect rising edges)*/
int position = -1; // position in the text. we noticed initially position=0// makes it skip the first character
void setup() {servoltop.attach(4); // digital pin 4 now controls left-top servoservoltop.write(92); /* quickly stabilize servo (default lowered position) to
prevent damage to device*/servolmiddle.attach(5); // digital pin 5 now controls left-middle servoservolmiddle.write(95); // to stabilize servoservolbottom.attach(6); // digital pin 6 now controls left-bottom servoservolbottom.write(93); // to stabilize servoservortop.attach(7); // digital pin 7 now controls right-top servo
-
8/18/2019 Braille Reader using Arduino
11/16
Page 11111111 of 16161616
servortop.write(90); // to stabilize servoservormiddle.attach(9); // digital pin 9 now controls right-middle servoservormiddle.write(96); // to stabilize servoservorbottom.attach(10); // digital pin 10 now controls right-bottom servoservorbottom.write(91); // to stabilize servo
pinMode (encoderPinA,INPUT); // use encoder pin A as digital input pinMode (encoderPinB,INPUT); // use encoder pin B as digital input
pinMode(10, OUTPUT); /* Pin 10 must be set as an output for the SD communicationto work.*/
card.init(); // Initialize the SD card and configure the I/O pins.volume.init(card); // Initialize a volume on the SD card.root.openRoot(volume); // Open the root directory in the volume.
}
void loop() {
// Quadrature encoding from encoder code works using polling// SD card code is nested withing this code
n = digitalRead(encoderPinA); // make n to be current value of A
if ((encoderPinALast == LOW) && (n == HIGH)) { // if rising edge (1 to 0transition)
if (digitalRead(encoderPinB) == LOW) { // decrement if B is lowencoderPos--;
} else { // increment if B is highencoderPos++;
}if(encoderPos == 2) {position++; encoderPos=0;} // determines how much to move
//before refreshingif(encoderPos == -2) {position--; encoderPos=0;} // determines how much to move
//before refreshing
// SD card code begins herechar alphabet; // To store the current character
file.open(root, name, O_READ); // Open the file in read mode.file.seekSet(position); // Position seek in file.alphabet=file.read(); // Get the byte in the file at seek location.file.close(); // Close the file
// SD card code ends here
braille(alphabet); // Actuate braille pins based on current//character
}encoder0PinALast = n; //Now last value of pin A must be set to n
}
void braille(char letter){ //takes in a character (char letter) and initializes pins basedon that
servoltop.write(92); // initializes pin to default lowered positionservolmiddle.write(95); // initializes pin to default lowered positionservolbottom.write(93); // initializes pin to default lowered positionservortop.write(90); // initializes pin to default lowered positionservormiddle.write(96); // initializes pin to default lowered positionservorbottom.write(91); // initializes pin to default lowered position
-
8/18/2019 Braille Reader using Arduino
12/16
Page 12121212 of 16161616
for (d=0; d
-
8/18/2019 Braille Reader using Arduino
13/16
Page 13131313 of 16161616
((letter=='w'||letter=='W') && (d==0)) ||((letter=='w'||letter=='W') && (d==1)) ||((letter=='y'||letter=='Y') && (d==1)) ||((letter=='z'||letter=='Z') && (d==1)) ||(letter==',' && (d==0)) ||(letter=='.' && (d==0)) ||(letter=='.' && (d==1)) ||(letter==';' && (d==0)) ||(letter=='!' && (d==0)) ||
(letter=='!' && (d==1)) ||((letter=='(' || letter==')') && (d==0)) ||((letter=='(' || letter==')') && (d==1)) ||(letter=='?' && (d==0)) ||
(letter=='"' && (d==1)) ||(letter=='#' && (d==1))
){if(d==0){servolmiddle.write(85);} if(d==1){servormiddle.write(106);}} //set middle//pins
if( ((letter=='k'||letter=='K') && (d==0))||((letter=='l'||letter=='L') && (d==0))||((letter=='m'||letter=='M') && (d==0))||((letter=='n'||letter=='N') && (d==0))||((letter=='o'||letter=='O') && (d==0))||((letter=='p'||letter=='P') && (d==0))||
((letter=='q'||letter=='Q') && (d==0))||((letter=='r'||letter=='R') && (d==0))||((letter=='s'||letter=='S') && (d==0))||((letter=='t'||letter=='T') && (d==0))||((letter=='u'||letter=='U') && (d==0))||((letter=='u'||letter=='U') && (d==1))||((letter=='v'||letter=='V') && (d==0))||((letter=='v'||letter=='V') && (d==1))||((letter=='w'||letter=='W') && (d==1))||((letter=='x'||letter=='X') && (d==0))||((letter=='x'||letter=='X') && (d==1))||((letter=='y'||letter=='Y') && (d==0))||((letter=='y'||letter=='Y') && (d==1))||((letter=='z'||letter=='Z') && (d==0))||((letter=='z'||letter=='Z') && (d==1))||
(letter== '\''&& (d==0)) ||(letter=='.' && (d==1)) ||(letter==';' && (d==0)) ||(letter=='!' && (d==0)) ||((letter=='('|| letter==')') && (d==0)) ||((letter=='('|| letter==')') && (d==1)) ||(letter=='-' && (d==0)) ||(letter=='-' && (d==1)) ||(letter=='?' && (d==0)) ||(letter=='?' && (d==1)) ||
(letter=='"' && (d==0)) ||(letter=='"' && (d==1)) ||(letter=='#' && (d==0)) ||(letter=='#' && (d==1))
){if(d==0){servolbottom.write(83);} if(d==1){servorbottom.write(101);}} //set bottom
//pins
} // end of for loop} // end of function braille
-
8/18/2019 Braille Reader using Arduino
14/16
Page 14141414 of 16161616
Appendix BAppendix BAppendix BAppendix B
Since Braille uses the same symbol for 1 and A, 2 and B and so on till 0 and J, it adds a special
character before a number. This code modifies a text file in the computer to add the ‘#’ symbols in
front of numbers prior to transferring the text into the device.
// ADDING # CHARACTER BEFORE NUMBERS
// ECE395 - Braille e-book/e-text reader
// Developer: Angky William
#include int main (){FILE * pFile;int c='a';int n = 0;int a;int b;int d;int e=0;int f=0;
pFile=fopen ("test.txt","r+"); //file name to be editedif (pFile==NULL) perror ("Error opening file");else{
for(n=0;c!=EOF;n++){
c=getc(pFile);if('0'
-
8/18/2019 Braille Reader using Arduino
15/16
Page 15151515 of 16161616
fputc((int)b,pFile); b=getc(pFile);fseek(pFile,-1,SEEK_CUR);//printf(" a is %d b is %d",a,b);}
fseek(pFile,n+2,SEEK_SET);n++;}
}
//adding special code start herefseek(pFile,0,SEEK_SET);c='a';
for(n=0;c!=EOF;n++){c=getc(pFile);if(('0'
-
8/18/2019 Braille Reader using Arduino
16/16
Page 16161616 of 16161616
Appendix CAppendix CAppendix CAppendix C