[personal profile] chebe
Gizmo can speak (albeit with a new accent), and Gizmo can move, now we have to tie the two together so they only move when they speak. And it's all software.

Again, we're following an adapted version of Furlexa project.

First we need a python script, a more structured version of the motor/motor.py from Part 3. Separate the parts into setup(), start_furby(), and stop_furby(), and add a main(). We'll also need the sound device status file path from Part 2, /proc/asound/card0/pcm0p/sub0/status.

Something like;
#!/usr/bin/env python

import RPi.GPIO as GPIO

# Declare the GPIO settings
GPIO.setmode(GPIO.BOARD)

# Turn off GPIO warnings
GPIO.setwarnings(False)

# Set path to playback soundcard
soundcard_status_file = '/proc/asound/card0/pcm0p/sub0/status'

STBY_PIN = 13
PWMA_PIN = 7
AIN1_PIN = 16
AIN2_PIN = 15

def setup():
    # set up GPIO pins
    GPIO.setup(PWMA_PIN, GPIO.OUT)
    GPIO.setup(AIN2_PIN, GPIO.OUT)
    GPIO.setup(AIN1_PIN, GPIO.OUT)
    GPIO.setup(STBY_PIN, GPIO.OUT)


def main():
    # Open device status file and check contents
    with open(soundcard_status_file, 'r') as fh:
        value = fh.read()
        if 'RUNNING' in value:
            start_furby()
        else:
            stop_furby()


def start_furby():
    # Drive the motor clockwise
    GPIO.output(AIN1_PIN, GPIO.HIGH)
    GPIO.output(AIN2_PIN, GPIO.LOW)
    
    # Set the motor speed
    GPIO.output(PWMA_PIN, GPIO.HIGH)
    
    # Disable standby
    GPIO.output(STBY_PIN, GPIO.HIGH)


def stop_furby():
    # Reset all GPIO pins by setting them to LOW
    GPIO.output(PWMA_PIN, GPIO.LOW)
    GPIO.output(AIN2_PIN, GPIO.LOW)
    GPIO.output(AIN1_PIN, GPIO.LOW)
    GPIO.output(STBY_PIN, GPIO.LOW)


if __name__ == '__main__':
    setup()
    main()


This script only sets the motors in motion (or stops them) based on the current state of the status file when invoked, and exits. It doesn't keep running while the motors do.

In order to keep track of the changes of the status file a monitor script is needed. (And because we made the changes to PulseAudio in Part 2 the status will actually change.)
#!/bin/bash

STATUS='/proc/asound/card0/pcm0p/sub0/status'
SCRIPT='python /home/pi/furby/furby.py'

content=''
while true
do
	new_content=`cat $STATUS`
	if [[ "$content" != "$new_content" ]]; then
		content=$new_content
		$SCRIPT
	fi
	sleep 0.25
done


Make the script executable with chmod +x output-monitor.sh, and run with ./output-monitor.sh. Then make some sounds in another ssh session. There you go, singing, dancing, Gizmo!


But hey, wouldn't it be nice to make this Gizmo's default behaviour without having to invoke it every time? Let's get it to run at startup. We're going to set it up with systemd as described here.

Create a Unit file;
sudo vim /lib/systemd/system/furby.service
With contents;
[unit]
Description=Make Furby move
After=multi-user.target

[Service]
Type=idle
ExecStart=/bin/bash /home/pi/furby/output-monitor.sh
Restart=always

[Install]
WantedBy=multi-user.target


Make it executable with sudo chmod 644 /lib/systemd/system/furby.service, and enable it in systemd;
sudo systemctl daemon-reload
sudo systemctl enable furby.service


Reboot to pickup changes. And finally, Furby/Gizmo is all singing, all dancing.

(Small caveat; Furby/Gizmo will do a little shimmy with every pop/click out of the speaker.)

You can install Alexa if you want, I won't be. I do have other plans to extend the project a bit but this is the bulk of the project, and plenty to freak your friends out. Bonus, you don't even have to close up and re-skin Furby/Gizmo. Don't believe me? Have a look for yourself.


Part 1 | Part 2 | Part 3 | Part 4 | Part 5
(will be screened)
(will be screened if not validated)
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

If you are unable to use this captcha for any reason, please contact us by email at support@dreamwidth.org