Components and supplies
Solenoid, 5V, push-pull
Arduino UNO
2N3904 NPN transistor
Resistor 220 ohm
1N4007 – High Voltage, High Current Rated Diode
Project description
Code
Arduino ASCII- Braille Translator
arduino
1/* 2 Arduino ASCII- Braille Translator 3 by Cesare Brizio | CC by-sa-nc 4 this sketch is in the public domain 5 6 Version 1.0 - 29 June 2019 7 ------------------------------ 8 This sketch will use six small solenoids/electromagnets arranged in 9 three rows of two columns to operate a Braille dot matrix. 10 Any ASCII character sent to Arduino via COM port will be "translated" 11 in a timed sequence of Braille symbols by configuring, one character 12 at a time, the dot matrix, so that the "dots" (solenoids) corresponding 13 to the current ASCII character are raised for 500 msec before passing to 14 the subsequent character. 15 When an un-translatable character is sent, a short buzz is emitted. 16 17 ==== DOT NUMBERING ==== 18 Dots are not numbered according to the Braille convention, but are 19 conventionally numbered from left to right, then from top to bottom: 20 1 2 21 3 4 22 5 6 23 As an example, showing letter "b" (asterisk represent an high dot): 24 *- 25 *- 26 -- 27 will require raising dots number 1 and 3 28 29 30 ==== DOT CONFIGURATION ==== 31 Dot configuration will be stored as a series of six binary values. As an 32 example, according to the preceding explanation, the configuration for "b" 33 is 101000. 34 As long as configurations contain just 6 bits of information, they can be 35 stored in a single char that, translated bitwise (least significant bit at 36 right), corresponds to the needed configuration. 37 So, 101000 (configuration for "b"), corresponding to DEC 40 and HEX 28, 38 will be represented by ASCII character "(". 39 Summarizing, considering that ascii code for "b" is 98D (62H) I will say 40 that 41 myBrailleDots[98] = 40; 42 meaning that the binary sextet corresponding to letter "b" is 101000. 43 44 When needed, a bitwise AND with increasing powers of two (from 1 to 32) 45 will reveal which dots shall be raised: this is accomplished by iterating 46 through a 6 bit mask: 47 48 Some simplifications will be applied, e.g.: 49 a) the multi-letter Braille glyphs (ch, ing, for, ar, th and others) 50 b) number prefix (010111), 51 c) letter prefix (000101), 52 d) uppercase prefix (000001) and other prefixes 53 will not be implemented in this version, but this sketch can 54 be quite easily implemented with the needed modifications. 55*/ 56 57// Declare a char array with one index for every possible ASCII byte / character 58byte myBrailleDots[255]; 59int firstOutputPin = 2; // pin corresponding to least significant bit 60int buzzerPin = 8; // Buzzer on pin 8 61byte matrixPoints = 0; // byte that will store the point matrix configuration 62 // for a specific ASCII character 63byte inByte; 64byte mask = 1; //our bitmask 65 66void setup() { 67 // Temporarily assign 99 to every possible ASCII byte/character 68 // All the characters in the input string will decode to "99" by default 69 for (int i = 0; i < 256; i = i + 1) { 70 myBrailleDots[i] = 99; 71 } 72 73 // Now, only for the ASCII characters with a corresponding Braille character. 74 // assign the corresponding Braille Dot configuration 75 myBrailleDots[32] = 0; // blank is 000000 76 myBrailleDots[33] = 14; // exlamation mark is 001110 77 myBrailleDots[34] = 7; // double quote is 000111 78 myBrailleDots[34] = 2; // single quote is 000010 79 myBrailleDots[40] = 15; // left parenthesis is 001111 80 myBrailleDots[41] = 15; // right parenthesis is 001111 81 myBrailleDots[44] = 8; // comma is 001000 82 myBrailleDots[46] = 13; // period is 001101 83 myBrailleDots[48] = 28; // 0 is 011100 84 myBrailleDots[49] = 32; // 1 is 100000 85 myBrailleDots[50] = 40; // 2 is 101000 86 myBrailleDots[51] = 48; // 3 is 110000 87 myBrailleDots[52] = 52; // 4 is 110100 88 myBrailleDots[53] = 36; // 5 is 100100 89 myBrailleDots[54] = 56; // 6 is 111000 90 myBrailleDots[55] = 60; // 7 is 111100 91 myBrailleDots[56] = 44; // 8 is 101100 92 myBrailleDots[57] = 24; // 9 is 011000 93 myBrailleDots[58] = 12; // colon is 001100 94 myBrailleDots[59] = 10; // semicolon is 001010 95 myBrailleDots[63] = 11; // question mark is 001011 96 myBrailleDots[65] = 32; // A is 100000 97 myBrailleDots[66] = 40; // B is 101000 98 myBrailleDots[67] = 48; // C is 110000 99 myBrailleDots[68] = 52; // D is 110100 100 myBrailleDots[69] = 36; // E is 100100 101 myBrailleDots[70] = 56; // F is 111000 102 myBrailleDots[71] = 60; // G is 111100 103 myBrailleDots[72] = 44; // H is 101100 104 myBrailleDots[73] = 24; // I is 011000 105 myBrailleDots[74] = 28; // J is 011100 106 myBrailleDots[75] = 34; // K is 100010 107 myBrailleDots[76] = 42; // L is 101010 108 myBrailleDots[77] = 50; // M is 110010 109 myBrailleDots[78] = 54; // N is 110110 110 myBrailleDots[79] = 38; // O is 100110 111 myBrailleDots[80] = 58; // P is 111010 112 myBrailleDots[81] = 62; // Q is 111110 113 myBrailleDots[82] = 46; // R is 101110 114 myBrailleDots[83] = 26; // S is 011010 115 myBrailleDots[84] = 30; // T is 011110 116 myBrailleDots[85] = 35; // U is 100011 117 myBrailleDots[86] = 43; // V is 101011 118 myBrailleDots[87] = 29; // W is 011101 119 myBrailleDots[88] = 51; // X is 110011 120 myBrailleDots[89] = 55; // Y is 110111 121 myBrailleDots[90] = 39; // Z is 100111 122 myBrailleDots[97] = 32; // A is 100000 123 myBrailleDots[98] = 40; // B is 101000 124 myBrailleDots[99] = 48; // C is 110000 125 myBrailleDots[100] = 52; // D is 110100 126 myBrailleDots[101] = 36; // E is 100100 127 myBrailleDots[102] = 56; // F is 111000 128 myBrailleDots[103] = 60; // G is 111100 129 myBrailleDots[104] = 44; // H is 101100 130 myBrailleDots[105] = 24; // I is 011000 131 myBrailleDots[106] = 28; // J is 011100 132 myBrailleDots[107] = 34; // K is 100010 133 myBrailleDots[108] = 42; // L is 101010 134 myBrailleDots[109] = 50; // M is 110010 135 myBrailleDots[110] = 54; // N is 110110 136 myBrailleDots[111] = 38; // O is 100110 137 myBrailleDots[112] = 58; // P is 111010 138 myBrailleDots[113] = 62; // Q is 111110 139 myBrailleDots[114] = 46; // R is 101110 140 myBrailleDots[115] = 26; // S is 011010 141 myBrailleDots[116] = 30; // T is 011110 142 myBrailleDots[117] = 35; // U is 100011 143 myBrailleDots[118] = 43; // V is 101011 144 myBrailleDots[119] = 29; // W is 011101 145 myBrailleDots[120] = 51; // X is 110011 146 myBrailleDots[121] = 55; // Y is 110111 147 myBrailleDots[122] = 39; // Z is 100111 148 pinMode(buzzerPin, OUTPUT); 149 pinMode(2, OUTPUT); 150 pinMode(3, OUTPUT); 151 pinMode(4, OUTPUT); 152 pinMode(5, OUTPUT); 153 pinMode(6, OUTPUT); 154 pinMode(7, OUTPUT); 155 Serial.begin(9600); 156 Serial.println("ASCII - Braille Arduino Converter"); 157 Serial.println("LED test - begin"); 158 digitalWrite(2,HIGH); 159 digitalWrite(3,HIGH); 160 digitalWrite(4,HIGH); 161 digitalWrite(5,HIGH); 162 digitalWrite(6,HIGH); 163 digitalWrite(7,HIGH); 164 delay(3000); 165 digitalWrite(2,LOW); 166 digitalWrite(3,LOW); 167 digitalWrite(4,LOW); 168 digitalWrite(5,LOW); 169 digitalWrite(6,LOW); 170 digitalWrite(7,LOW); 171 Serial.println("LED test - end"); 172 Serial.println("Type some character: it will be transmitted to Arduino and displayed on a Braille 2 x 3 matrix"); 173} 174 175 176void loop() { 177 // Braille print data only when you receive data: 178 if (Serial.available() > 0) { 179 // read the incoming byte: 180 inByte = Serial.read(); 181 // say what you got: 182 Serial.print("Received (inByte): "); 183 Serial.println(inByte); 184 // Translate inByte in matrix points 185 Serial.print("Matrix points variable (myBrailleDots[inByte]): "); 186 Serial.println(myBrailleDots[inByte]); 187 188 // Braille print only admissible characters 189 // the unadmissible ones decode to 99 190 if (myBrailleDots[inByte] == 99) // if unadmissible 191 { 192 Serial.println("Not a translatable character"); 193 digitalWrite(buzzerPin,HIGH); // buzz 194 delay(250); 195 digitalWrite(buzzerPin,LOW); // stop buzzing 196 } 197 else{ 198 int thisPin = 2; 199 for (mask = 000001; mask<64; mask <<= 1) { 200 Serial.print("thisPin = "); 201 Serial.println(thisPin); 202 if (myBrailleDots[inByte] & mask){ // if bitwise AND resolves to true 203 Serial.print("AND successful, put pin on!"); 204 Serial.println(mask); 205 digitalWrite(thisPin,HIGH); 206 } 207 else{ //if bitwise and resolves to false 208 Serial.print("AND unsuccessful, put pin off!"); 209 Serial.println(mask); 210 digitalWrite(thisPin,LOW); 211 } 212 thisPin = thisPin + 1; 213 } 214 } 215 delay(3000); // allow 3 sec before passing to next character 216 } 217}
Arduino ASCII- Braille Translator
arduino
1/* 2 Arduino ASCII- Braille Translator 3 by Cesare Brizio | CC by-sa-nc 4 this sketch is in the public domain 5 6 Version 1.0 - 29 June 2019 7 ------------------------------ 8 This sketch will use six small solenoids/electromagnets arranged in 9 three rows of two columns to operate a Braille dot matrix. 10 Any ASCII character sent to Arduino via COM port will be "translated" 11 in a timed sequence of Braille symbols by configuring, one character 12 at a time, the dot matrix, so that the "dots" (solenoids) corresponding 13 to the current ASCII character are raised for 500 msec before passing to 14 the subsequent character. 15 When an un-translatable character is sent, a short buzz is emitted. 16 17 ==== DOT NUMBERING ==== 18 Dots are not numbered according to the Braille convention, but are 19 conventionally numbered from left to right, then from top to bottom: 20 1 2 21 3 4 22 5 6 23 As an example, showing letter "b" (asterisk represent an high dot): 24 *- 25 *- 26 -- 27 will require raising dots number 1 and 3 28 29 30 ==== DOT CONFIGURATION ==== 31 Dot configuration will be stored as a series of six binary values. As an 32 example, according to the preceding explanation, the configuration for "b" 33 is 101000. 34 As long as configurations contain just 6 bits of information, they can be 35 stored in a single char that, translated bitwise (least significant bit at 36 right), corresponds to the needed configuration. 37 So, 101000 (configuration for "b"), corresponding to DEC 40 and HEX 28, 38 will be represented by ASCII character "(". 39 Summarizing, considering that ascii code for "b" is 98D (62H) I will say 40 that 41 myBrailleDots[98] = 40; 42 meaning that the binary sextet corresponding to letter "b" is 101000. 43 44 When needed, a bitwise AND with increasing powers of two (from 1 to 32) 45 will reveal which dots shall be raised: this is accomplished by iterating 46 through a 6 bit mask: 47 48 Some simplifications will be applied, e.g.: 49 a) the multi-letter Braille glyphs (ch, ing, for, ar, th and others) 50 b) number prefix (010111), 51 c) letter prefix (000101), 52 d) uppercase prefix (000001) and other prefixes 53 will not be implemented in this version, but this sketch can 54 be quite easily implemented with the needed modifications. 55*/ 56 57// Declare a char array with one index for every possible ASCII byte / character 58byte myBrailleDots[255]; 59int firstOutputPin = 2; // pin corresponding to least significant bit 60int buzzerPin = 8; // Buzzer on pin 8 61byte matrixPoints = 0; // byte that will store the point matrix configuration 62 // for a specific ASCII character 63byte inByte; 64byte mask = 1; //our bitmask 65 66void setup() { 67 // Temporarily assign 99 to every possible ASCII byte/character 68 // All the characters in the input string will decode to "99" by default 69 for (int i = 0; i < 256; i = i + 1) { 70 myBrailleDots[i] = 99; 71 } 72 73 // Now, only for the ASCII characters with a corresponding Braille character. 74 // assign the corresponding Braille Dot configuration 75 myBrailleDots[32] = 0; // blank is 000000 76 myBrailleDots[33] = 14; // exlamation mark is 001110 77 myBrailleDots[34] = 7; // double quote is 000111 78 myBrailleDots[34] = 2; // single quote is 000010 79 myBrailleDots[40] = 15; // left parenthesis is 001111 80 myBrailleDots[41] = 15; // right parenthesis is 001111 81 myBrailleDots[44] = 8; // comma is 001000 82 myBrailleDots[46] = 13; // period is 001101 83 myBrailleDots[48] = 28; // 0 is 011100 84 myBrailleDots[49] = 32; // 1 is 100000 85 myBrailleDots[50] = 40; // 2 is 101000 86 myBrailleDots[51] = 48; // 3 is 110000 87 myBrailleDots[52] = 52; // 4 is 110100 88 myBrailleDots[53] = 36; // 5 is 100100 89 myBrailleDots[54] = 56; // 6 is 111000 90 myBrailleDots[55] = 60; // 7 is 111100 91 myBrailleDots[56] = 44; // 8 is 101100 92 myBrailleDots[57] = 24; // 9 is 011000 93 myBrailleDots[58] = 12; // colon is 001100 94 myBrailleDots[59] = 10; // semicolon is 001010 95 myBrailleDots[63] = 11; // question mark is 001011 96 myBrailleDots[65] = 32; // A is 100000 97 myBrailleDots[66] = 40; // B is 101000 98 myBrailleDots[67] = 48; // C is 110000 99 myBrailleDots[68] = 52; // D is 110100 100 myBrailleDots[69] = 36; // E is 100100 101 myBrailleDots[70] = 56; // F is 111000 102 myBrailleDots[71] = 60; // G is 111100 103 myBrailleDots[72] = 44; // H is 101100 104 myBrailleDots[73] = 24; // I is 011000 105 myBrailleDots[74] = 28; // J is 011100 106 myBrailleDots[75] = 34; // K is 100010 107 myBrailleDots[76] = 42; // L is 101010 108 myBrailleDots[77] = 50; // M is 110010 109 myBrailleDots[78] = 54; // N is 110110 110 myBrailleDots[79] = 38; // O is 100110 111 myBrailleDots[80] = 58; // P is 111010 112 myBrailleDots[81] = 62; // Q is 111110 113 myBrailleDots[82] = 46; // R is 101110 114 myBrailleDots[83] = 26; // S is 011010 115 myBrailleDots[84] = 30; // T is 011110 116 myBrailleDots[85] = 35; // U is 100011 117 myBrailleDots[86] = 43; // V is 101011 118 myBrailleDots[87] = 29; // W is 011101 119 myBrailleDots[88] = 51; // X is 110011 120 myBrailleDots[89] = 55; // Y is 110111 121 myBrailleDots[90] = 39; // Z is 100111 122 myBrailleDots[97] = 32; // A is 100000 123 myBrailleDots[98] = 40; // B is 101000 124 myBrailleDots[99] = 48; // C is 110000 125 myBrailleDots[100] = 52; // D is 110100 126 myBrailleDots[101] = 36; // E is 100100 127 myBrailleDots[102] = 56; // F is 111000 128 myBrailleDots[103] = 60; // G is 111100 129 myBrailleDots[104] = 44; // H is 101100 130 myBrailleDots[105] = 24; // I is 011000 131 myBrailleDots[106] = 28; // J is 011100 132 myBrailleDots[107] = 34; // K is 100010 133 myBrailleDots[108] = 42; // L is 101010 134 myBrailleDots[109] = 50; // M is 110010 135 myBrailleDots[110] = 54; // N is 110110 136 myBrailleDots[111] = 38; // O is 100110 137 myBrailleDots[112] = 58; // P is 111010 138 myBrailleDots[113] = 62; // Q is 111110 139 myBrailleDots[114] = 46; // R is 101110 140 myBrailleDots[115] = 26; // S is 011010 141 myBrailleDots[116] = 30; // T is 011110 142 myBrailleDots[117] = 35; // U is 100011 143 myBrailleDots[118] = 43; // V is 101011 144 myBrailleDots[119] = 29; // W is 011101 145 myBrailleDots[120] = 51; // X is 110011 146 myBrailleDots[121] = 55; // Y is 110111 147 myBrailleDots[122] = 39; // Z is 100111 148 pinMode(buzzerPin, OUTPUT); 149 pinMode(2, OUTPUT); 150 pinMode(3, OUTPUT); 151 pinMode(4, OUTPUT); 152 pinMode(5, OUTPUT); 153 pinMode(6, OUTPUT); 154 pinMode(7, OUTPUT); 155 Serial.begin(9600); 156 Serial.println("ASCII - Braille Arduino Converter"); 157 Serial.println("LED test - begin"); 158 digitalWrite(2,HIGH); 159 digitalWrite(3,HIGH); 160 digitalWrite(4,HIGH); 161 digitalWrite(5,HIGH); 162 digitalWrite(6,HIGH); 163 digitalWrite(7,HIGH); 164 delay(3000); 165 digitalWrite(2,LOW); 166 digitalWrite(3,LOW); 167 digitalWrite(4,LOW); 168 digitalWrite(5,LOW); 169 digitalWrite(6,LOW); 170 digitalWrite(7,LOW); 171 Serial.println("LED test - end"); 172 Serial.println("Type some character: it will be transmitted to Arduino and displayed on a Braille 2 x 3 matrix"); 173} 174 175 176void loop() { 177 // Braille print data only when you receive data: 178 if (Serial.available() > 0) { 179 // read the incoming byte: 180 inByte = Serial.read(); 181 // say what you got: 182 Serial.print("Received (inByte): "); 183 Serial.println(inByte); 184 // Translate inByte in matrix points 185 Serial.print("Matrix points variable (myBrailleDots[inByte]): "); 186 Serial.println(myBrailleDots[inByte]); 187 188 // Braille print only admissible characters 189 // the unadmissible ones decode to 99 190 if (myBrailleDots[inByte] == 99) // if unadmissible 191 { 192 Serial.println("Not a translatable character"); 193 digitalWrite(buzzerPin,HIGH); // buzz 194 delay(250); 195 digitalWrite(buzzerPin,LOW); // stop buzzing 196 } 197 else{ 198 int thisPin = 2; 199 for (mask = 000001; mask<64; mask <<= 1) { 200 Serial.print("thisPin = "); 201 Serial.println(thisPin); 202 if (myBrailleDots[inByte] & mask){ // if bitwise AND resolves to true 203 Serial.print("AND successful, put pin on!"); 204 Serial.println(mask); 205 digitalWrite(thisPin,HIGH); 206 } 207 else{ //if bitwise and resolves to false 208 Serial.print("AND unsuccessful, put pin off!"); 209 Serial.println(mask); 210 digitalWrite(thisPin,LOW); 211 } 212 thisPin = thisPin + 1; 213 } 214 } 215 delay(3000); // allow 3 sec before passing to next character 216 } 217}
Downloadable files
General overview of a breadboard implementation of the circuit
Caution: read the text attentively. There are many better implementations of solenoids under Arduino.
General overview of a breadboard implementation of the circuit
Comments
Only logged in users can leave comments