My main motivator for this project was that it was a way to help my grandma out around the house. In the past year, she has had difficulty getting around, and I thought that this project could help her just a little bit around the house. The trash can she has in her kitchen is currently supposed to be motion-activated, but it no longer functions. With that as the main idea, I thought that making a voice-activated trash can could be more useful than another motion-activated one.
FunctionsThe trash can has two main functions: to open and close using voice and to show the user how full it is.
For the voice recognition aspect, there is a small USB microphone attached to the USB portion of the PocketBeagle. To get it to work correctly the VB and V1 pins and the ID and GND pins had to be bridged together. The microphone was attached using a micro-USB to USB Type-A adapter. With the microphone. The user would push and hold a button to record their voice. Then, using the PyAudio and SpeechRecognition libraries, the user's voice would be recorded and the program. Once the audio was processed, depending on whether or not the user input "open" or "close", the attached servo would then open or close the trash can.
There is also a limit switch attached to the bottom of the trash can that when pressed turns on a red LED to signal that the can is full. The limit switch essentially acts as a button that turns on the LED.
Build InstructionsFirst, you must assemble the PocketBeagle. Make sure to solder all the headers on correctly and bridge the gap between the VB and V1 and the ID and GND pins.
Once that is assembled, the you should wire the button up to their breadboard correctly using the resistor and a simple wire. You then should make sure that the button is connected to a GPIO pin on the PocketBeagle
After the button is hooked up, you attach the leds to the breadboard and wire up the limit switch similar to the button.
From there you should attach the servo to the PocketBeagle using the 3.3 V SYS pins and the PWM pins.
Once that is done, you implement the code!
Future ImprovementsOne of the main issues I ran into with this project was getting everything to integrate with the pre-fabricated trash can well. In the future I would recommend making a custom can with prefabricated sections for the servo and limit switch.
I would also like to get rid of the button entirely. With this project based around opening a trash can with as little movement as possible, removing the button would mean the user wouldn't have to move their limbs at all.
VideoCode
"""
--------------------------------------------------------------------------
Speech Recognition
--------------------------------------------------------------------------
License:
Copyright 2024 Chase Alvarado
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------
"""
import time
import speech_recognition as sr
import servo as motors
import button as button
import pyaudio
import wave
import Adafruit_BBIO.ADC as ADC
import Adafruit_BBIO.GPIO as GPIO
import Adafruit_BBIO.PWM as PWM
# Class to handle the audio recording via microphone
class AudioRecorder:
def __init__(self, button):
# Audio settings
self.format = pyaudio.paInt16 # Audio format
self.channels = 1 # Mono channel
self.rate = 44100 # Sampling rate
self.chunk = 4096 # Buffer size
self.filename = "test_recording.wav" # File to save the recording
self.record_seconds = 10 # Duration of the recording
self.button = button # Button to trigger recording
# Function to record audio from the microphone
def record(self):
audio = pyaudio.PyAudio() # Create a PyAudio object
# Open a stream for audio input
stream = audio.open(format=self.format, channels=self.channels,
rate=self.rate, input=True,
frames_per_buffer=self.chunk)
print("Press the button to start recording")
self.button.wait_for_press() # Wait for button press to start recording
print("Recording for 10 seconds...")
frames = []
# Record audio in chunks for the set duration
for _ in range(0, int(self.rate / self.chunk * self.record_seconds)):
data = stream.read(self.chunk, exception_on_overflow=False)
frames.append(data)
print("Finished recording.")
# Stop and close the audio stream
stream.stop_stream()
stream.close()
audio.terminate()
# Save the recorded audio to a file
wf = wave.open(self.filename, 'wb')
wf.setnchannels(self.channels)
wf.setsampwidth(audio.get_sample_size(self.format))
wf.setframerate(self.rate)
wf.writeframes(b''.join(frames))
wf.close()
print(f"File saved: {self.filename}")
return self.filename
class speech:
def __init__(self):
pass
# End def
def _setup(self):
pass
def recognize(self, recording):
r = sr.Recognizer()
with recording as source:
audio = r.record(source)
text = r.recognize_sphinx(audio)
return text
# End def
def record(self,audiofile):
recording = sr.AudioFile(audiofile)
return recording
# End def
def run(self,file):
servo = mc.motors()
recording = self.record(audiofile=file)
text = self.recognize(recording=recording)
if text == 'open':
motors.movebackward()
print('backward')
elif text == 'close':
motors.moveforward()
print('forward')
# End def
# ------------------------------------------------------------------------
# Main script
# ------------------------------------------------------------------------
if __name__ == '__main__':
Speech = speech()
try:
AudioRecorder.run
Speech.run(file='test_recording.wav')
except KeyboardInterrupt:
pass
Comments