Braille Reader using Arduino

download Braille Reader using Arduino

of 16

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