This week, I added a microphone sensor to the microcontroller board I designed two weeks ago. My goal was to test if I could detect sound using the microphone and trigger an LED based on sound levels. After some debugging, I successfully detected sound events like snaps or speech, which caused the LED to light up once the sound passed a certain threshold.
The following code reads sound values from the sensor and blinks the LED whenever the sound exceeds the threshold.
const int led = D9; // Pin connected to LED
const int soundSensor = A2; // Pin connected to sound sensor OUT pin
int samples[5] = {0}; // Array to store the last 5 samples
int sampleIndex = 0; // Current index for circular buffer
void setup() {
pinMode(led, OUTPUT); // Initialize LED pin as output
Serial.begin(115200); // Start serial communication
}
void loop() {
int sample = analogRead(soundSensor); // Read the sound sensor value
Serial.write(sample); // Print the value to Serial Monitor
// Store the current sample in the circular buffer
samples[sampleIndex] = sample;
sampleIndex = (sampleIndex + 1) % 5; // Move to the next index (wrap around)
// Calculate the average of the last 5 samples
int average = 0;
for (int i = 0; i < 5; i++) {
average += samples[i];
}
average /= 5; // Compute the average
// Check if the absolute deviation from the average exceeds the threshold (150)
if (abs(sample - average) > 150) {
blinkLED(); // Blink LED if threshold is crossed
}
}
// Function to blink the LED once
void blinkLED() {
digitalWrite(led, HIGH); // Turn the LED on
delay(50); // Keep it on for 50ms
digitalWrite(led, LOW); // Turn the LED off
delay(50); // Short off delay
}
Whenever I snapped my fingers or talked into the mic, the LED lit up once the sound exceeded the threshold. This code uses a circular buffer to store the last 5 sound samples and calculate an average. If the new sound sample deviates significantly from the average, the LED blinks.
Building on the microphone testing, I experimented with capturing audio data from the microcontroller and sending it to my laptop for speech recognition. Here’s the code I used:
import serial
import numpy as np
import soundfile as sf
import time
import pyaudio
import speech_recognition as sr
def read_and_transcribe():
try:
ser = serial.Serial(port='/dev/cu.usbmodem101', baudrate=115200, timeout=1)
r = sr.Recognizer()
print("Connected to device. Starting transcription...")
CHUNK_SIZE = 16000
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 16000
while True:
data = []
start_time = time.time()
while time.time() - start_time < 1:
bytes_data = ser.read(2)
if len(bytes_data) == 2:
value = int.from_bytes(bytes_data, byteorder='big')
data.append(value)
if not data:
continue
data_array = np.array([x - 65536/2 for x in data], dtype=np.int16)
data_array = apply_noise_reduction(data_array)
sf.write("temp_audio.wav", data_array, RATE)
try:
with sr.AudioFile("temp_audio.wav") as source:
audio = r.record(source)
text = r.recognize_google(audio)
print(f"Transcription: {text}")
except sr.UnknownValueError:
print("No speech detected")
except sr.RequestError as e:
print(f"Could not request results; {e}")
except serial.SerialException as e:
print(f"Error connecting to device: {e}")
except KeyboardInterrupt:
print("\nStopping transcription...")
finally:
if 'ser' in locals():
ser.close()
def apply_noise_reduction(data, window_size=5):
kernel = np.ones(window_size) / window_size
smoothed_data = np.convolve(data, kernel, mode='same')
smoothed_data -= np.mean(smoothed_data)
max_amplitude = np.max(np.abs(smoothed_data))
if max_amplitude > 0:
smoothed_data *= (32767 / max_amplitude)
return smoothed_data.astype(np.int16)
if __name__ == "__main__":
read_and_transcribe()
This code reads sound data from the microcontroller over serial communication and processes it in real-time using Python. It applies noise reduction and attempts to transcribe the speech using Google’s speech-to-text service. This experiment was a step toward my final project, where I aim to record and transcribe conversations automatically.
The Python code used to read and process sound data is available here: Download input.py
This week was a great learning experience as I explored both microcontroller programming and speech recognition. I learned how to manage sound input and write threshold-based logic to trigger events. Working with serial communication gave me insight into handling data streams effectively.
There were challenges with noise in the recordings, but I implemented noise reduction techniques that improved the transcription accuracy. The next step will be refining this process further for use in my AR glasses project.
Thanks to Yuval and Sam Bruce for their help this week. Their guidance was invaluable!