Monday, December 5, 2011

"Echo Box" using PICAXE 08M (Complete)

What is an "Echo Box" you ask? Simple. You tap on the box and a few seconds later the box echos those taps back to you. The video below shows the rigs operation. Keep reading if you want the build details.
-----

-----
I have programmed a PICAXE 08M microcontroller to monitor for current on a piezo disk. The piezo disk outputs a current when it is struck (or tapped). The PICAXE sample and holds the cadence of the taps with software. If there are no taps for about a second or so the program assumes the tapping is complete and echos the taps back to you on the box.

The piezo sits inside a tube of PVC pipe between two pieces of wine cork that are cut to barely touch the roof of the box. This does a great job of transferring the taps from the top of the box to the piezo input. Here is a picture of the piezo disk resting on top of a wine cork.

-----
And here is the piezo input disk in its final configuration with another piece of wine cork placed on top of it. Basically creating a "piezo sandwich" with wine cork.
-----
Below is how the input from the piezo traces out on the 'scope. A diode in parallel with the piezo protects the PICAXE from getting hit with a negative voltage spike. A 1M resistor also helps to tame the input and make it more predictable.
-----
A DC motor with an offset counter weight spins to shake the box and provide the feedback for the echo.
-----
The circuit perf board is shown below. The red LED is simply there to provide a visual clue that the piezo tap was processed by the PICAXE. It is used only for debug of the project and could be removed. You can also see two 470uF capacitors on the board. Take note that the motor will not get enough instantaneous energy to start without these capacitors. One final note, a transistor as heavy as the 2N6284 is not required, but I had one handy. The more common 2N2222 should be fine.
-----
The rig is powered with 5VDC provided by a rescued Blackberry charger. The headphone jack is not for audio; this jack is used to download the control program into the PICAXE 08M. This jack allows you to easily change the personality of the Echo Box.
-----
The completed Echo Box:
---
-----
Here are two videos of the rig working on the bench.




-----
For those that have hung in there so far with the details, the circuit schematic and code is shown below:
-----
; *******************************
; ***** www.whiskeytangohotel.com *****
; *******************************
; Project Name: Echo Echo
; [with thanks to AndyGadget & the PICAXE Forum]
;
; Start Date: November 15, 2011
; Completed: December 4, 2011
;
; *******************************

#picaxe 08m2
#com 11


' Assign names to pins, variables to registers,and constants.

symbol rnd = w6 'Word variable : Current random number
symbol kdel = w5 'Word variable : Delay between last and current knock input

symbol cnt1 = b0
symbol kcnt = b1 'Number of knocks
symbol pptr = b2 'Pointer to knock delay storage array

symbol tmp1 = b6 'Reusable variable
symbol tmp2 = b7 'Reusable variable

symbol mic = pin2 'Microphone input (can also be output)
symbol knock = 4 'Knock motor output
symbol led = 0 'Indicator LED for testing

symbol pstart = $50 'Start of storage area
symbol tmax = 800 'Time-out value for delay - About 1.5 seconds
symbol settle = 80 'Settling time for microphone


'This section is where the person knocks.
'The time between successive knocks is stored
' until there is a pause of 1.5 seconds or so.

do 'Start of main loop
kcnt = 0 'Initialise knock counter
input 2 'Define mic as input to detect knocks
do
for kdel = 1 to tmax 'KDel is counting loops to determine time between knocks
if mic = 1 then 'Detect HI on microphone input
inc kcnt 'Add 1 to number of knocks
high led 'Flash LED to help debugging
pause settle 'Wait for oscillations to stop
low led
kdel = kdel + settle 'Add settle time to loop counter for accuracy
pptr = kcnt * 2 + pstart'KCnnt is a word variable so need to add 2 to pointer
poke pptr,word kdel 'Write the delay from last knock to storage area
kdel = 0 'Reset kdel ready for next knock
end if
next kdel
loop until kdel >= tmax 'If no knocks for over TMax loops then leave loop
'This section will operate sepending on the number of knocks detected.
'If there are no knocks it will exit.
'The maximum number of knocks is 23 to fill buffer. Incorrect count after that.
select case kcnt

case 0 'Do nothing if no knocks have occurred
case 21 'Put Box in 'Irritate Mode'.
gosub twoknock 'gosub twoknow to confirm routine was entered.
wait 10 'Do nothing for xx seconds
gosub twoknock
wait 9
gosub twoknock
wait 8
gosub twoknock
wait 7
gosub twoknock
wait 6
gosub twoknock
wait 5
gosub twoknock
wait 4
gosub twoknock
wait 3
gosub twoknock
wait 2
gosub twoknock
wait 1
gosub twoknock

else 'Any other number of knocks will be echoed

for tmp1 = 1 to kcnt 'Loop for the number of knocks
pptr = tmp1 * 2 + pstart 'Step in twos through buffer
peek pptr,word kdel 'Read back delay value words from buffer
pause kdel 'Wait the delay time (in milli-seconds)
gosub DoKnock 'Perform a knock
next tmp1 'Loop for next knock
pause 200
endselect
loop


'This section contains the knocking routines

DoKnock:
high knock 'Turn on motor
pause 70 'Wait 70 milli-seconds
low knock 'Turn off motor
return

TwoKnock: 'More compact to do this as subroutine
pause 550 'Two knocks with timed delays between for tune
gosub doknock
pause 700
gosub doknock
pause 700
return
-----