The inspiration for this project comes from my personal experience. I was diagnosed with hearing loss at the age of seven, and since then, one of my biggest challenges has been identifying the source of sounds—especially while walking or moving around. Often, I found it so difficult to determine when someone is speaking to me and from which direction.
Driven by this need, I am developing a wearable device designed to restore the user's sense of auditory orientation. The system detects the source of loud sounds and uses strategic haptic feedback (vibration patterns) to indicate exactly where they are coming from.
Furthermore, this project aims to go beyond safety and assistance; it integrates a feature that transforms music into vibrations. This enriches the sensory experience, allowing people with profound hearing loss or deafness to 'feel' the music and reconnect with their environment in a new way.
Fig 1. Project sketch
The project will use basic microphones placed on different sides of the wearable to detect surrounding sounds. By comparing the signals, the system will estimate from which side the sound is coming.
A small microcontroller, such as a XIAO series board, will be used to read the microphone data and make simple decisions based on sound intensity and direction.
Small vibration motors will provide feedback to the user. Each vibration pattern will represent a direction, helping the user understand where the sound is coming from through touch.
The device will be powered by a compact battery, allowing it to be wearable and portable. Basic voltage regulation will be included to safely power the electronics.
The structure will be designed as a wearable object (like a clip or band) and fabricated using 3D printing or flexible materials to comfortably hold the electronic components.
To achieve the final result, I have mapped the development of the device to the weekly assignments:
First, it was essential to design a board that included all the necessary outputs to test the components required for the final project, such as the vibration motor and the microphone.
This board was designed during the Electronics Design week.
During the Input Devices week, I used an analog microphone module based on the MAX4466. I connected the module’s output to an ADC pin on my board, which uses a XIAO RP2350 microcontroller. The microcontroller samples these continuous voltage fluctuations and converts them into digital values, allowing the system to measure real-time sound intensity.
const int micPin = D0; // Pin of the microphone
const float volt = 3.3; // Voltage power of the XIAO
void setup() {
analogReadResolution(12); // Reading precision
Serial.begin(115200); // Serial communication
while(!Serial);
}
void loop() {
unsigned int sampleWindow = 50; // Use 50 milliseconds to listen for sound
unsigned int signalMax = 0; // Variable to store the highest sound level
unsigned int signalMin = 4095; // Variable to store the lowest sound level
unsigned long startMillis = millis(); // Record the exact time we start listening
// Collect sound data for 50 milliseconds
while (millis() - startMillis < sampleWindow) {
int sample = analogRead(micPin); // Read the current value from the microphone
if (sample > signalMax) { // If current value is higher than our max
signalMax = sample; // Update signalMax
}
if (sample < signalMin) { // If current value is lower than our min
signalMin = sample; // Update signalMin
}
}
// Calculate the difference between the loudest and quietest moments
int peakToPeak = signalMax - signalMin;
// Convert the digital intensity into real Voltage
float volts = (peakToPeak * volt) / 4095.0;
Serial.print("Intensity: "); // Intensity
Serial.print(peakToPeak); // Digital value
Serial.print(" | Voltage: "); // Voltage
Serial.println(volts); // Print the voltage
Serial.print(" V | ");
int numR = map(peakToPeak, 0, 2000, 0, 30);
for (int i = 0; i < numR; i++) {
Serial.print(">");
}
Serial.println();
delay(50);
}
During week 9, I also tested a different microphone, the MP34DT01, a high-performance digital MEMS microphone. This will be the one used in my final project, since unlike analog modules, this digital approach eliminates the need for an external amplifier, improving signal quality.
I connected it to the digital pins of the XIAO RP2350, which uses its internal PIO or PDM interface to decode the bitstream into usable audio data.
const int micPin = D0; // Pin of the microphone
const float volt = 3.3; // Voltage power of the XIAO
void setup() {
analogReadResolution(12); // Reading precision
Serial.begin(115200); // Serial communication
while(!Serial);
}
void loop() {
unsigned int sampleWindow = 50; // Use 50 milliseconds to listen for sound
unsigned int signalMax = 0; // Variable to store the highest sound level
unsigned int signalMin = 4095; // Variable to store the lowest sound level
unsigned long startMillis = millis(); // Record the exact time we start listening
// Collect sound data for 50 milliseconds
while (millis() - startMillis < sampleWindow) {
int sample = analogRead(micPin); // Read the current value from the microphone
if (sample > signalMax) { // If current value is higher than our max
signalMax = sample; // Update signalMax
}
if (sample < signalMin) { // If current value is lower than our min
signalMin = sample; // Update signalMin
}
}
// Calculate the difference between the loudest and quietest moments
int peakToPeak = signalMax - signalMin;
// Convert the digital intensity into real Voltage
float volts = (peakToPeak * volt) / 4095.0;
Serial.print("Intensity: "); // Intensity
Serial.print(peakToPeak); // Digital value
Serial.print(" | Voltage: "); // Voltage
Serial.println(volts); // Print the voltage
Serial.print(" V | ");
int numR = map(peakToPeak, 0, 2000, 0, 30);
for (int i = 0; i < numR; i++) {
Serial.print(">");
}
Serial.println();
delay(50);
}
During the Outputs week, I designed a custom module to control the vibration motor that I will use in my final project, using two essential components: a MOSFET and a diode. This setup is necessary because the motor requires more current than a microcontroller pin can safely provide.
// Pin definitions
const int micPin = D0; // Microphone OUT connected to A0
const int modulePin = D5; // Motor Module connected to D5
+
// Settings
const float threshold = 2.5; // Noise limit (Voltage) to trigger the motor
const float voltiosReferencia = 3.3;
void setup() {
analogReadResolution(12); // 12-bit resolution for RP2350
pinMode(modulePin, OUTPUT); // Set module pin as output
digitalWrite(modulePin, LOW); // Start with motor OFF
Serial.begin(115200);
while(!Serial);
}
void loop() {
unsigned int sampleWindow = 50; // 50ms window to catch sound waves
unsigned int signalMax = 0;
unsigned int signalMin = 4095;
unsigned long startMillis = millis();
// Step 1: Record sound to find Peak-to-Peak amplitude
while (millis() - startMillis < sampleWindow) {
int sample = analogRead(micPin);
if (sample > signalMax) signalMax = sample;
if (sample < signalMin) signalMin = sample;
}
// Step 2: Calculate intensity and real voltage
int peakToPeak = signalMax - signalMin;
float volts = (peakToPeak * voltiosReferencia) / 4095.0;
Serial.print("Intensity: ");
Serial.print(peakToPeak);
Serial.print(" | Voltage: ");
Serial.println(volts);
// Step 3: Logic to activate the External Module
if (volts >= threshold) {
// If sound is LOUD: Turn ON the module
digitalWrite(ledPin, HIGH);
digitalWrite(modulePin, HIGH);
Serial.println(">>> MOTOR MODULE ACTIVATED <<<");
delay(400); // Keep vibrating for 400ms
}
else {
// If sound is QUIET: Turn OFF everything
digitalWrite(ledPin, LOW);
digitalWrite(modulePin, LOW);
}
delay(10);
}