My first project of epic scale - foot sized Cap sensing piano under floor


Closed Thread
Results 1 to 2 of 2
  1. #1
    Join Date
    Jun 2008
    Location
    Milwaukee, WI
    Posts
    37

    Default My first project of epic scale - foot sized Cap sensing piano under floor

    this project started about 2 years ago. I had a large piece of perf board, a super simple, relaxation oscillator, non-interupting, 1-channel cap sensing routine running on a 16F628A, and a 16 to 1 analog multiplexer, and some time to kill, so I arranged 16 finger sized copper tape squares on the underside of the perf board and wired them to the multiplexer, and then wired the multiplexer to the cap sensor circuit. lo and behold, it worked, and I made a routine to scan the keys and use the SOUND command to output a tone corresponding to the key. I originally wanted to use the HPWM channel to generate the correct tones, (maybe more than one at at time!) and keep them sustained for the duration of the key press. What I ended up with was a little less impressive.. out of tune tones generated by the SOUND command that just went beep beep beep if you held your finger on one key at a time.


    The board has sat on my bench since then, collecting dust. But in that time, I've worked more and more with cap sensors, and I've always thought about putting cap sensors under the floor, and doing something cool with that. Fast forward to now, we are due to have our third kid around Christmas time, and my 7 year old daughter is moving her room from upstairs to the downstairs so the baby can have her old room.It's a little cold down there, there are spiders, and the window is tiny. So, I wanted to make her room special. I ripped up the old carpeting, re-painted, and now I'm installing laminate flooring. I thought 'Hey, here is my chance to put in cap sensors under the floor.. what should I do?'


    I ended up laying out 16 piano keys -10 white keys, B through D, and their black keys, so 16 in total. They are foot sized sensors on the laminate pad made with copper tape and wired to that same controller/multiplexer board which now sits in a cutout in the drywall, which will be eventually hidden by the trim. I spent most of last weekend on my hands and knees, but now it is working with my super simple code that I wrote long ago.


    Now that I've upgraded the hardware, I need to rethink the code. and how I can get different sounds, chords, and whatnot, without breaking the bank. I have an old keyboard that I could hack up and put fets or transistors on the key pads and control it that way... but that'll be a kludged together hack job.


    Right now, I'm thinking that I'll run 3 wires to the buried 16F628 controller, +5V, GND and a serial data line that will spit out 2 bytes, 16 bits corresponding to the pressed/unpressed states of the 16 keys. Then, I'll have another pic reading that data and (somehow) make the music happen.


    I'd love to have something like rmteo has posted:
    http://www.pic24.ru/doku.php/en/osa/.../pk2_osa_piano




    Any suggestions about how to go about making the music happen?


    I also got 2 meters of RGB LEDs and a cheap controller from ebay that has a remote. Eventually it would be nice to get the piano and the RGBs working together...but that is for another day.


    but anyway, here is the code that is running right now on the 16F628A, controlling the multiplexer and counting the pulses from the relaxation oscillator.


    if I count for 8mS, I get a count of about 3100, so the oscillator is running at about 380KHz. put your foot on the sensor, with the laminate in between, and it drops to about 2950~3000, since then, I changed to counting for 4mS.


    Any suggestions?


    I realize that what I call 'average' is not really an average, it's just a snapshot of the values it saw when it was first powered on..
    and, I see that my line to combine the timerH and timerL bytes is wrong, but I can't seem to get value=timerH.timerL to work.


    Code:
    'PIc and analog multiplexer capsense
    
    
    
    
    '    PIC16F628A Configuration
    '    ================
    
    
    
    
    @ __CONFIG  _INTRC_OSC_NOCLKOUT & _MCLRE_OFF  &  _LVP_OFF & _WDT_ON & _PWRTE_ON  & _BODEN_ON
    
    
    '    Hardware configuration
    '    ======================
    
    
    CLEARWDT
    
    
    DEFINE OSC 4				'4 MHz internal oscillator
    
    
    
    
    DEFINE DEBUG_REG PORTB		'RS-232 output on PORTB.4
    DEFINE DEBUG_BIT 7
    DEFINE DEBUG_BAUD 9600
    DEFINE DEBUG_MODE 0			'not inverted. using RS-232 chip, or pickit2
    DEFINE DEBUG_PACING 1000
    
    
    
    
    
    
    CMCON = %00000110           ' 2 common ref comparators with outputs  ..datasheet pdf page 64
    TRISB = %01000000           ' B.6= timer input = Comparator output freq
    TRISA = %00000111           ' Comparator inputs and Vref set to input
    VRCON = %11100011	    	' turn on Vref, output connected to RA2, Low range, Vref = .6 when Vcc = 5V
    			   			 	' ..datasheet pdf page 69
    
    
    
    
    '    RAM Assignments and Variables
    '    =============================
    
    
    
    
    DEBUGPIN  var    PORTB.4
    S0	      var    PORTB.0
    S1	      var    PORTB.1
    S2	  var    PORTB.5
    S3        var    PORTB.7
    EN    var    PORTB.2
    SPEAKER var  PORTB.3
    
    
    
    
    
    
    
    
    S0	  =0
    S1	  =0
    S2	  =0
    S3    =0
    EN    =1
    
    
    
    
    
    
    SenseTime   CON  4     ' how many milliseconds to run the cap sense counter for one sample
    
    
    
    
    Sleepy      var WORD    ' counter used with 'asleep'
    asleep   	CON  1000	' number of times around the main loop with no activity to put the chip to sleep.
    Sleeptime   CON  6       'Nap command period (5 = approx 480ms, 4 = approx 280ms)
    
    
    
    
    TONE var BYTE[16]
    
    
    
    
    TONE[15] = 48
    TONE[14] = 53
    TONE[13] = 56
    TONE[12] = 61
    TONE[11] = 64
    TONE[10] = 68
    TONE[9] =  72
    TONE[8] =  75 
    TONE[0] = 78
    TONE[1] = 81
    TONE[2] = 83
    TONE[3] = 86
    TONE[4] = 89
    TONE[5] = 90
    TONE[6] = 92
    TONE[7] = 94 
    
    
    Trip  CON 30
    playtime  con  12
    
    
    AVE		    VAR  WORD[16]	' current Capsense average
    Value	VAR  WORD[16]	' instantaneous Capsense count array
    
    
    
    
    
    
    SensorNumb  var BYTE
    
    
    
    
    pause 3000
    
    
    
    
    DEBUG REP $00\8,13,10,"Hello"
    
    
    Sleepy = 0
    
    
    
    
    GOSUB SCAN 
    
    
    FOR SensorNumb = 0 to 15
    	AVE[SensorNumb] = Value[SensorNumb]
    
    
    NEXT SensorNumb
    
    
    
    
    
    
    main:
    
    
    
    
    
    
    GOSUB SCAN 
    
    
    
    
    
    
    
    
    'DEBUG DEC Value[15], ",  ", DEC Value[14], ",  ", DEC Value[13], ",  ",DEC Value[12], ",  ",DEC Value[11], ",  ",DEC Value[10], ",  ", DEC Value[9],13,10
    
    
    
    
    FOR SensorNumb = 0 to 15
    
    
    	IF Value[SensorNumb] < (AVE[SensorNumb] - Trip) THEN
    		SOUND SPEAKER,[TONE[SensorNumb],playtime]
    		Sleepy = 0
    		goto main
    	ENDIF
    NEXT SensorNumb
    
    
    
    
    
    
    
    
    'Sleepy = Sleepy +1
    
    
    	
    IF Sleepy = asleep THEN 
    	DEBUG REP $00\8,13,10,"zz.."
    	CMCON=7                     		' disable internal comparator
    	VRCON = %00000000			' disable voltage reference
    
    
    	NAP Sleeptime				' places the microcontroller into low power mode 
    
    
    	CMCON = %00000110  			' enable internal comparator
    	VRCON = %11100011			' enable voltage reference
    	Sleepy = (asleep -1)		' Preload the the sleepy counter so it'll go right back to sleep after one reading
    
    
    ENDIF
    
    
    
    
    
    
    goto main
    
    
    ' -=-=-=-=-=-=  Scan sensors and put results into Value[X] -=-=-=-=-=-=-=-=-=-= 
    SCAN:
    
    
    FOR SensorNumb = 0 to 15
    
    
    
    
    		S0	  =SensorNumb.0
    		S1	  =SensorNumb.1
    		S2	  =SensorNumb.2
    		S3    =SensorNumb.3
    		EN    =0
    
    
    
    
    		TMR1H = 0							'Clear high and low timer1 registers
    		TMR1L = 0
    		T1CON = %00000111					'Start counter
    		pause SenseTime			  		    'wait 
    		T1CON = %00000110					'Stop counter
    
    
    		EN    =1
    
    
    		Value[SensorNumb] = ((255 * TMR1H) + TMR1L) 	'Combine high and low byte into one word sized variable
    
    
    
    
    NEXT SensorNumb
    
    
    RETURN
    
    
    End

  2. #2
    Join Date
    Jun 2008
    Location
    Milwaukee, WI
    Posts
    37


    Did you find this post helpful? Yes | No

    Default Re: My first project of epic scale - foot sized Cap sensing piano under floor

    no suggestions. OK. so that was a pretty long winded post. Sorry. but anyway, I'm moving away from the idea of hacking up my old keyboard and I'm thinking that I could spit out midi messages to a midi synth. I have never played with midi stuff before, but after reading some posts like the one called
    'button press AND hserout issues?!' it looks possible. well sort of, the OP of that post had some unresolved issues.

    if I put a 20MHz resonator on my 16F628A, then connect it to something like this:
    http://www.sparkfun.com/products/8953
    and then connect some powered speakers to the headphone jack, I'm thinking I could play different tones at the same time, and also switch instruments

    anybody have some insight on midi? would this work?

Members who have read this thread : 0

You do not have permission to view the list of names.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts