Propellor Demo Board Clap Switch With Code
Well I know there are TONS of people asking how to do a clap on/off switch with the propellor demo board built in MIC and while not terribly difficult as a first project it was a challenge. I have used this to turn my christmas tree on and off with a relay to switch mains power
It works decently well if someone could suggest a better method for detecting the second clap that would be great... as it seems there is a slight delay in the while loop which makes the second clap harder to detect.
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
env_rate = 20 'Envelope is evaluated this many times per second.
sample_rate = 8000 'Microphone is sampled this many times per second.
gain = 256 'Envelope is multiplied by this amount.
mic_inp = 8 'Microphone input pin.
mic_fbk = 9 'Microphone feedback pin.
led_pin = 16 ' LED That will light when clap---clap is heard/relay is on
relay_pin = 0 ' Pin For External Relay
time_led = 23 ' led will light when loud noise(clap) is heard and the program starts waiting for second clap(set to 0 to disable)
' The Led Then Turns off when the clapper routine resets and a new clap -- clap can be done
VAR
long value,delay,i
byte button,oldbutton,clap
PUB Clapper
start
dira[led_pin]~~ 'Set as output
outa[led_pin]~ 'Output to LOW
dira[relay_pin]~~
outa[relay_pin]~
if time_led > 0
dira[time_led]~~
outa[time_led]~
repeat
clap := envelope
if (clap == 255)
if time_led > 0
outa[time_led]~~ 'Indicate First Clap
waitcnt(clkfreq/5 + cnt)
repeat while i < 10000
i++
clap := envelope
if clap == 255
button := 1 - button ' 1 - 0 = 1 and 1 - 1 = 0
if (button == 1) & (oldbutton == 0)
outa[led_pin]~~
outa[relay_pin]~~
if (button == 0) & (oldbutton == 1)
outa[led_pin]~
outa[relay_pin]~
i := 0
if time_led > 0
outa[time_led]~ ' Turn LED OFF
oldbutton := button
PUB start
'Start routine for object.
mic_dt := clkfreq / sample_rate
env_cyc := sample_rate / env_rate
cognew(@env_det, @value)
PUB envelope
'Return a value between 0 and 255 for loudness.
return (value * gain) >> 16 <# 255
DAT
org 0
env_det mov ctra,ctra0
mov dira,dira0
mov frqa,#1
mov bias,mic_dt 'Guess at adc bias level:
shr bias,#1 ' dt / 2.
mov mic_time,cnt
add mic_time,mic_dt
mov pamp,phsa
env_lp mov accum,#0
mov env_cnt,env_cyc
mic_lp call #sample
addabs accum,amp
djnz env_cnt,#mic_lp
wrlong accum,par
jmp #env_lp
'-------[* sample ]-------------------------------------------------------------
' Read the ADC (microphone) input.
sample waitcnt mic_time,mic_dt 'Wait for adc value to be accumulated.
mov amp,phsa 'Read it.
sub amp,pamp 'Subtract the previous reading.
add pamp,amp 'pamp := pamp + amp - pamp == pamp
sub amp,bias 'Subtract the DC bias.
shl bias,#4 'Compute running average of bias.
add bias,amp
shr bias,#4
sample_ret ret
env_cyc long $-$
mic_dt long $-$
dira0 long 1 << mic_fbk
ctra0 long 001 << 26 | mic_fbk << 9 | mic_inp
bias res 1
accum res 1
env_cnt res 1
mic_time res 1
pamp res 1
amp res 1
It works decently well if someone could suggest a better method for detecting the second clap that would be great... as it seems there is a slight delay in the while loop which makes the second clap harder to detect.

Comments
Welcome to the Parallax Forums! feel free to ask any questions here. This is a nice group of people that are more than willing to help solve a problem.
Great project! I did something similar for my father in law a few years ago, but I soon realized that it was a bad idea to have a clapper controlling a Christmas tree in the same room as a bunch of football fans ... I'll let you paint the mental image there. :-)