-
11Loading Voice
To incorporate voice functionality into BrailleBot, the DFPlayer Mini is utilized, which plays different audio files stored on a memory card in response to signals from the Romeo ESP32-S3.
- If you wish to use your own custom voice, you can explore https://speechgen.io/ for generating alphabet pronunciations.
- However, for immediate use, you can simply copy and paste the provided audio files from the GitHub repository: https://github.com/MukeshSankhla/BrailleBot.
Follow these steps:
- Download the provided audio files from the GitHub repository by navigating to the repository and finding the "Audio.zip" file.
- Extract the contents of the "Audio.zip" file.
- Copy the extracted audio files to the memory card.
- Insert the memory card into the DFPlayer.
By completing these steps, you ensure that the DFPlayer has access to the necessary audio files, allowing BrailleBot to provide voice feedback during the learning process.
Note: Here I am using a 4GB memory card which was available with me, if you have a memory card with lsize less then 32GB "since DFPlayer can support up to 32GB memory card" you can use it.
-
12Connecting Audio Circuit
DFPlayer to Romeo ESP32 Connections:
- Connect the GND (Ground) of the DFPlayer to the GND on the Romeo ESP32.
- Connect VCC of the DFPlayer to 5V on the Romeo ESP32.
- Connect RX (Receive) of the DFPlayer to IO48 on the Romeo ESP32.
- Connect TX (Transmit) of the DFPlayer to IO46 on the Romeo ESP32.
Speaker Connections:
- Connect SPK1 of the DFPlayer to one terminal of the speaker.
- Connect SPK2 of the DFPlayer to the other terminal of the speaker.
Ensure that the connections are secure and accurate, following the circuit diagram.
-
13Touch Sensor Connection
Grab the two touch sensors and connect them by soldering the female jumper wires.
Now, establish the connections:
- Attach Sensor 1 (Next) I/O pin to pin IO45 of the Romeo ESP32.
- Connect Sensor 2 (Previous) I/O pin to pin IO8 Romeo ESP32.
- Also, connection GND to GND and Vcc to 3v3 of both sensors to corresponding Romeo pins, following the guidance provided in the circuit diagram.
-
14Final Assembly
To complete the assembly, follow these steps:
Mounting the Speaker:
- Securely screw the speaker onto the main enclosure. Ensure it is firmly attached.
Protecting DFPlayer Connection:
- Use masking tape to cover the open connections of the DFPlayer. This precaution helps protect against potential short circuits.
Placing DFPlayer and Wires:
- Position the DFPlayer and its associated wires inside the main enclosure.
Assembling the Enclosure:
- Align the Top 3D printed part with the main enclosure.
- Snap the Top part onto the main enclosure, ensuring a secure fit.
With these steps completed, your assembly should be finished.
-
15Code
Download the Code from GitHub:
- Visit the GitHub repository: https://github.com/MukeshSankhla/BrailleBot
- Click on the green "Code" button, and then click "Download ZIP."
- Extract the downloaded ZIP file to a location on your computer.
Install DFRobotDFPlayerMini Library:
- Open the Arduino IDE on your computer.
- Click on Sketch in the menu, then select Include Library -> Add .ZIP Library.
- Navigate to the extracted folder and select the "DFRobotDFPlayerMini-master.zip" file. Click "Open" to install the library.
Open and Upload the Code:
- Open the Arduino sketch by navigating to the extracted folder and opening the .ino file.
- In the Arduino IDE, set the board type by clicking on Tools -> Board and selecting the bosrd type as "DFRobot Romeo ESP32-S3".
- Choose the correct port by clicking on Tools -> Port and selecting the port to which your Romeo ESP32-S3 is connected.
- Upload the code to the board by clicking on the right arrow icon (or by selecting Sketch -> Upload).
Code Successfully Uploaded:
- Once the code is successfully uploaded, you should see the message "Done uploading" at the bottom of the Arduino IDE.
-
16Code Explanation
setup():
- This function is called once when the Arduino starts.
- It sets up the pin modes for the "Next" and "Previous" buttons, initializes serial communication, and attaches interrupt service routines to these buttons.
- It initializes the DFPlayer module, prints welcome messages to the serial monitor, and performs the initial setup for BrailleBot, including moving the Braille dots and playing the introduction audio.
void setup() { pinMode(nextPin, INPUT_PULLUP); pinMode(previousPin, INPUT_PULLUP); // Set up serial communication FPSerial.begin(9600, SERIAL_8N1, /*rx =*/48, /*tx =*/46); Serial.begin(115200); // Display welcome message Serial.println(F("Hello! I am BrailleBot.")); // Attach interrupts for button presses attachInterrupt(digitalPinToInterrupt(nextPin), nextISR, FALLING); attachInterrupt(digitalPinToInterrupt(previousPin), previousISR, FALLING); // Initialize the DFPlayer module if (!myDFPlayer.begin(FPSerial, /*isACK = */true, /*doReset = */true)) { Serial.println(F("Unable to begin:")); Serial.println(F("1. Please recheck the connection!")); Serial.println(F("2. Please insert the SD card!")); } // Display start message Serial.println(F("Let's Start Learning.")); // Clear Braille display and play introduction audio clear(); delay(1000); myDFPlayer.volume(30); myDFPlayer.play(27); delay(4000); // Perform initial setup by moving Braille dots up and down for(int i = 0; i < 5; i++){ up(); clear(); } play(); // Play the audio for the current Braille letter }
loop():
- This function runs repeatedly in a loop after the setup() function.
- It checks if the "Next" or "Previous" buttons are pressed using the nextPressed and previousPressed flags.
- If the "Next" button is pressed, it increments the position variable, clears the Braille display, and lifts the corresponding alphabet dots, plays the audio for the new Braille letter. It then resets the nextPressed flag.
- If the "Previous" button is pressed, it decrements the position variable, clears the Braille display, and lifts the corresponding alphabet dots, plays the audio for the new Braille letter. It then resets the previousPressed flag.
void loop() { // Check if "Next" button is pressed if (nextPressed) { position++; clear(); play(); // Play the audio for the new Braille letter nextPressed = false; // Reset the flag } // Check if "Previous" button is pressed if (previousPressed) { position--; clear(); play(); // Play the audio for the new Braille letter previousPressed = false; // Reset the flag } }
dot1Up() and dot1Down() to dot6Up() and dot6Down():
- These functions control the movement of each individual Braille dot using a servo motor.
- The dotXUp() functions move the specified dot up by gradually decreasing the servo angle, creating a rising motion.
- The dotXDown() functions move the specified dot down by gradually increasing the servo angle, creating a lowering motion.
- As you can see the dot1, 3 and 5 starts from last position that is 180° and decrements, because these motors are oriented in reverse order.
- Whereas dot2, 4 and 6 starts from 0° and increment.
void dot1Up(){ for (int pos = 180; pos >= 162; pos--) { myservo.write(servo1, pos); delay(5); } } void dot1Down(){ for (int pos = 162; pos <= 180; pos++) { myservo.write(servo1, pos); delay(5); } } . . . . . . void dot6Up(){ for (int pos = 0; pos <= 10; pos++) { myservo.write(servo6, pos); delay(5); } } void dot6Down(){ for (int pos = 10; pos >= 0; pos--) { myservo.write(servo6, pos); delay(5); } }
play():
- This function plays the audio associated with the current Braille letter.
- It checks the position variable and calls the corresponding function (e.g., a(), b()) to move the Braille dots and play the audio for that letter.
- If position is 27 (beyond the letter 'z'), it resets position to 1.
void play(){ if(position == 0){ position = 1; } if(position == 1){ a(); } if(position == 2){ b(); } . . . . . . if(position == 26){ z(); } if(position == 27){ position = 1; } }
clear():
- This function clears the Braille display by moving all dots down.
- It sequentially calls the dotXDown() functions for each Braille dot with a delay between each movement.
void clear(){ dot1Down(); delay(100); dot2Down(); delay(100); dot3Down(); delay(100); dot4Down(); delay(100); dot5Down(); delay(100); dot6Down(); delay(100); }
a() to z():
- These functions each correspond to a Braille letter from 'a' to 'z'.
- Each function calls the appropriate dotXUp() functions to raise the Braille dots into the configuration for that letter and plays the corresponding audio using the DFPlayer module.
void a(){ dot1Up(); myDFPlayer.play(2); delay(pause); } void b(){ dot1Up(); dot3Up(); myDFPlayer.play(3); delay(pause); } . . . . . void z(){ dot1Up(); dot4Up(); dot5Up(); dot6Up(); myDFPlayer.play(1); delay(pause);
up():
- This function raises all Braille dots by calling the dotXUp() functions for each dot.
void up(){ dot1Up(); dot2Up(); dot3Up(); dot4Up(); dot5Up(); dot6Up(); }
nextISR() and previousISR():
- These are interrupt service routines that set the nextPressed and previousPressed flags when the "Next" and "Previous" buttons are pressed, respectively.
void nextISR() { nextPressed = true; } // Interrupt service routine for "Previous" button void previousISR() { previousPressed = true; }
-
17Calibration
- These servo motors or the arm can have small error because of which the dots may not be lifting to the same height, so we have to calibrate the orientation of each motor.
- As you can see in the dotXUp() and dotXDown() functions the pos values are not same for each motor its because, I have adjusted the values according to my BrailleBot system, so you have to adjust these values according to your tactile sensations.
- Example dotXUp pos values :
for (int pos = 180; pos >= 162; pos--) for (int pos = 0; pos <= 20; pos++) for (int pos = 180; pos >= 165; pos--) for (int pos = 0; pos <= 16; pos++) for (int pos = 180; pos >= 160; pos--) for (int pos = 0; pos <= 10; pos++)
- Also make sure to adjust the same in dotXDown().
-
18Conclusion
And there you have it — we're all set to explore the Braille alphabets with BrailleBot.
If you encounter any questions or issues during the implementation, feel free to let me know in the comments section. If you've successfully created this project for yourself, remember to share it in the "I Made It" section below.
Throughout this BrailleBot tutorial, I've demonstrated how to create a straightforward Braille alphabet trainer (A to Z). This project offers ample opportunities for customization, so I encourage you to share your improved versions of the project. By doing so, you can contribute to helping others benefit from this tool and facilitate interactive learning for the visually impaired.
Thank you, and see you next time :)
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.