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.
perl -e 'use MIME::Base64; print decode_base64("4pmsIE5ldmVyIGdvbm5hIGdpdmUgeW91IHVwCiAgTmV2ZXIgZ29ubmEgbGV0IHlvdSBkb3duLi4uIOKZqwo=");'
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.
|