I really wanted to use a Raspberry Pi and an instance of Alexa installed on the Raspberry Pi rather than commandeer my Echo Dot. My project ended up using: 1) A Raspberry Pi with an Adafruit Motor HAT to drive the mouth and head, 2) Alexa installed on the Raspberry Pi, 3) the speaker inside Billy Bass for Alexa and 4) the battery pack inside Billy Bass to power both the Billy Bass Speaker and Motors. A sound sensor taped down on the speaker inside Billy Bass provided the triggers to move the mouth and head when Alexa spoke. Everything but the Pi fit neatly into Billy Bass and I drilled a hole in the back to thread the wires out to the Raspberry Pi. I also remixed/made a 3D printed case to house the Raspberry Pi and Motor HAT.
I wrote a short python script that reads the sound sensor that is taped onto the speaker. When the sound goes above a certain threshold, the head will lift, and the mouth will move. It moves in time with the words pretty well if the threshold it adjusted correctly. It should be pretty easy to add in some code for the tail as well, but I was OK with just these movements for now.
All the code can be downloaded from my Github, and the parts and walk though are detailed below. Here is a video of the completed project:
Big Mouth Billy Bass (check ebay, Amazon or a local thrift store)
Adafruit Motor Hat
Adafruit Microphone Amplifier MAX4466 AKA sound sensor (Amazon or Adafruit)
MCP3800 8-Channel 10-Bit ADC with XPI
Adafruit Class D Audio Amplifier MAX 9744 (Amazon or Adafruit )
Playstation Eye Microphone
Raspberry Pi (Amazon or Adafruit)
male/male audio/headphone type cable
Although I got a lot of supplies from Adafruit, similar items are available from other outlets and manufacturers - I like to support Adafruit because of all their great tutorials and project ideas. This also assumes that the Raspberry Pi has already been loaded up with the latest version of Raspbian (not the light version as a browser is needed to activate Alexa) and that all the normal accessories are available for it - sd card, power, wifi, etc. An audio jack is needed so a Pi Zero won't work unless some mods are made to it.
Gut Billy Bass
Hook up the Motors
Hook up the Billy Bass Speaker
Hook up the Sound Sensor
Grab the Billy Bass python script
Make Billy Bass pretty again
Gutting Billy Bass
This tutorial was helpful for me in gutting Billy Bass. Basically, I unscrewed the back and cut all the wires. As I cut, I made sure I left enough wire in case I wanted to reuse them. There was also a little circuit board screwed down on the inside that I cut all the wires from and discarded. The stuff I re-purposed for this project were the motors, speakers, battery pack and the motion sensor on/off switch in the back (but not the actual motion sensor). I had two motors in my Billy Bass. One motor was used to drive the mouth, and the other motor was used to drive the head and tail, depending on which way the motor is ran. If you have a Billy Bass with three motors (head, tail and mouth) this project should still work with a couple tweaks.
|Billy Bass Front Inside|
|Billy Bass Back Inside|
I had an Adafruit Motor HAT from a previous project so I decided to use it to drive the motors. The Motor HAT fits right on top of the Raspberry Pi and can drive up to four DC motors. Adafruit has a nice Python library to drive the motors, and since Python is my programming language of choice, this made it an easy choice for me.
- Followed the Adafruit tutorial on assembling the Motor HAT and installing the Python library
- Connected the Head/Tail motor to the Motor 1 terminal
- Connected the Mouth motor to the Motor 2 terminal
I decided to use the Billy Bass battery pack and the motion sensor on/off switch to power the Motor HAT. See below for how I wired it up:
If it's wired up correctly, when the motion sensor switch is on, the Motor HAT LED will light up green like the picture above.
I wrote a little script, MotorCheck.py to test the motors once they were hooked up. The head and mouth should move when the script runs. If the tail does, it simply requires switching the wires in Motor HAT terminal 1.
Hook up the Speaker
I decided to install Alexa on the Raspberry Pi rather than use my Echo Dot. Alexa needs a speaker so you can hear her talking. Since the Raspberry Pi doesn't have a speaker, I decided to re-purpose the Billy Bass speaker for Alexa's voice. In order to do this, I used a Class D Audio Amplifier - Max9744 from Adafruit. This let me connect the headphone jack from the Rasbperry Pi and route the audio to the raw speaker inside Billy Bass. Although there were other amplifiers available, I choose the Max9744 because it was small, and can take 5 Volts, which the internal Billy Bass battery pack is capable of supplying.
- Followed the Adafruit instructions on how to assemble the Max9744
- Connect the 2.5mm audio jack to the Raspberry Pi
Hook up the Sounds Sensor
I needed a way to "trigger" the mouth and head when Alexa talked. As I mentioned before, I saw a picture from this Teddy Ruxpin write up that showed a sensor taped onto the top of an Echo. After seeing this, I wanted to write a python script that monitored a sensor taped down to the Billy Bass speaker. When it detected Alexa talking, the python script would turn on the mouth and head motors for Billy Bass.
The first sound sensor I tried was this red one from Atomic Market. I choose it because it had a Digital Out pin which would be relatively easy to hook up to one of the Raspberry Pi's GPIO pins. I could not seem to get the sensor dialed in correctly. It was either extremely sensitive and triggered all the time, or nothing at all. I could not get it to work as I wanted. Maybe you'll have more luck?
After fussing with that I decided to try the Adafruit Microphone Amplifier MAX4466 which ended up working beautifully. The downside was that it required more wiring then a simple Digital Out pin, but, in my opinion was worth the extra effort as the mouth movement ended up syncing nicely with Alexa. To convert the analog signal for the Raspberry Pi, I used an MCP3800 chip and followed the wiring diagram I found here.The chip uses SPI, so I had to enable SPI through the raspi-config interface:
I wrote a python script, SensorCheck.py that will test the sensor by outputting the sound values. The sensor is not meant to hear noise on the other side of the room, which makes it perfect for responding to noise coming just from the Billy Bass speaker which it will be taped onto.
Installing Alexa on the Raspberry Pi was super easy and free. I followed the detailed instructions on the Amazon Alexa github page. The micro USB microphone suggested on the Github page was OK, but I kinda had to shout to get Alexa to hear me. I also had to trouble shoot it to get it to work by editing the asoundrc file. I had a Playstation Eye microphone laying around that I thought worked better. Although it's a bit bigger and bulkier, it worked right off the bat, and I didn't have to shout. Once Alexa was up and running , the next step was to get the Billy Bass mouth to sync with her voice.
Billy Bass Python Script
The BillyBass.py python script is responsible for monitoring the sound sensor, moving the mouth and lifting the head when it hears Alexa speak. The sensitivity level can by adjusted in the script by changing the variable SENSITIVITY. If the mouth seems to lag or not move, the sensitivity may need to be adjusted up (IE - moved from 900 to 1000). If the mouth is moving like crazy, the sensitivity needs to be adjusted down (IE - from 1000 to 800). I found that I had to play around with this until I found just the right setting to sync the words and mouth movement.
It was a little tricky getting the head to pop up and stay up as the head needs be lifted when Alexa is quite and listening to the user's request. I set a timeout feature that will raise the head when it first hears sound (IE, the trigger word "Alexa"), then starts counting the number of loops while it's quite. After its been quite for a certain amount of time (loops), the head lowers. This value can be adjusted with the variable HEAD_PAUSE. If it's too low, the head will move back down while you are still talking to the fish - to high and his head will remain up for a long time after Alexa is done talking. Once again, trial and error helped find the correct value.
On a side note, after I got everything put back into Billy Bass and was testing it, the fish head kept bouncing back and forth against the back board even though nothing was being said. I kept thinking to myself "Quit hitting yourself, Quit hitting yourself". It turned out that each time the head lowered it knocked the board hard enough to register a noise on the sound sensor causing the head to pop back up again. This was fixed easily enough in the code by having the script sleep for a few seconds while the head lowered before checking for sensor values.
Make Billy Bass Pretty Again
When everything was working as wanted, I put all the components except for the Raspberry Pi back into the Billy Bass housing. I drilled a hole to thread the wires through that needed to be plugged into the Pi and the switch on the back can be used to turn the motors and speakers on/off.
Now I can ask Billy Bass to add items to my shopping list, tell me jokes and add items to my shopping list. Who wouldn't want that?
Next Steps/Outstanding Issues
I would like to get the script to start and stop based on the Alexa wake word. This will make it less likely to respond when it hears ambient noise or voices.
I noticed some feedback from the motors over the speakers. Switching the motors to their own power supply fixes this. I probably need to do some better wiring to stop the feedback.