Some time ago, i saw those fake "emergency stop" buttons on Amazon that play a funny audio sample when you press them. But they were too expensive and - much more important - you can't change the sound on them. So i implemented my own.
First i hooked up a real (non-latching) emergency button to a Raspberry Pi GPIO pin and a set of rather ancient and crappy Desktop speakers to the analog out of the Pi. I also prepared some audio files in raw format: Decoding MP3 costs performance, so it is not as instantaneous as playing a raw file, also the Pi runs some other performance critical stuff and using raw files instead of wav/mp3 fixed some timing issues.
List of audio files (not uploading them here due to copyright):
- bullshit1.raw
- bullshit2.raw
- bullshit3.raw
- jeopardy.raw
And here is the script that ties it all together:
#!/usr/bin/env perl #---AUTOPRAGMASTART--- use 5.012; use strict; use warnings; use diagnostics; use mro 'c3'; use English qw( -no_match_vars ); use Carp; our $VERSION = 1.5; no if $] >= 5.017011, warnings => 'experimental::smartmatch'; #---AUTOPRAGMAEND--- no utf8; use Device::BCM2835; use Time::HiRes qw[sleep alarm time]; use Data::Dumper; # Make sure the process name is maplat_failbutton $0 = 'maplat_failbutton'; my $SHUTDOWN = 0; $SIG{INT} = sub{print "GOT SIGINT, exiting...\n"; $SHUTDOWN=1;}; $SIG{TERM} = sub{print "GOT SIGTERM, exiting...\n"; $SHUTDOWN=1;}; if(!Device::BCM2835::init()) { die("Can't open device!"); } my $testpinnumber = 13; # BCM internal pin number; 21 = GPIO Pin 40 my $sndidx = 1; # Select as input device Device::BCM2835::gpio_fsel($testpinnumber, &Device::BCM2835::BCM2835_G +PIO_FSEL_INPT); # Select Pull up resistor mode Device::BCM2835::gpio_set_pud($testpinnumber, &Device::BCM2835::BCM283 +5_GPIO_PUD_UP); my $lastswitch = -1; # "Unknown" my $lastswitchtime = time; while(!$SHUTDOWN) { my $switch = Device::BCM2835::gpio_lev($testpinnumber); if($switch != $lastswitch) { my $now = time; print "SWITCH SET TO $switch\n"; if($lastswitch == -1) { $lastswitch = $switch; sleep(0.5); next; } $lastswitch = $switch; if($switch) { print "Switch pressed...\n"; $lastswitchtime = $now; } else { my $cmd; my $presslength = $now - $lastswitchtime; print "PL: $presslength\n"; if($presslength < 0.8) { print " short click\n"; $cmd = '/usr/bin/aplay -r 44100 -f S16_LE /home/cavac/ +src/maplat_failalert/bullshit' . $sndidx . '.raw'; $sndidx++; if($sndidx == 4) { $sndidx = 1; } } else { print " long click\n"; $cmd = '/usr/bin/aplay -r 44100 -f S16_LE /home/cavac/ +src/maplat_failalert/jeopardy.raw'; } print "Running $cmd\n"; `$cmd`; print "...done.\n"; } } sleep(0.1); }
A short button press plays one of the 3 "bullshit detected" samples. Holding the button for about 1 second before releasing plays the 30 second jeopardy "thinking" music.
Note: This is actually the "dumb" version of the script. My local implementation also triggers some LED display for the bullshit alerts and runs an analog meter (via an Arduino) from 100% to 0% while the jeopardy music ticks down the seconds.
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Implementing a 2-mode "Audiobutton" on the Raspberry Pi
by holli (Abbot) on Oct 26, 2018 at 08:17 UTC | |
by cavac (Parson) on Oct 29, 2018 at 15:37 UTC | |
by hippo (Bishop) on Oct 29, 2018 at 16:08 UTC |