'{$STAMP BS2} '{$PBASIC 2.5} ' ************************************************************** ' * The "Thereping" a sonar-based Theremin-like Instrument * ' * (c) 2005/2006 Vern Graner SSE, Texas Information Services * ' ************************************************************** ' * Code for BSII to measure distance on the PING sensor and * ' * play a corresponding note on the audio out. * ' ************************************************************** ' * Created: V0.2 11-05-2005 * ' ************************************************************** ' ************************ ' * Pin Assignments * ' ************************ Btn1 PIN 0 Btn2 PIN 1 Btn3 PIN 2 PING PIN 3 LED1 PIN 4 SPEAKER PIN 5 SYNC PIN 6 LED2 PIN 7 LED3 PIN 8 LED4 PIN 9 ' LCD PIN 0 ' Serial LCD panel ' SPEAKER PIN 1 ' Speaker/Amp ' PING PIN 12 ' PING)) Sensor ' Btn1 PIN 14 ' "Start" button ' Btn2 PIN 13 ' "Start" button ' SYNC PIN 15 ' Sync Pulse ' ******************************** ' * Pin Assignments * ' * BSII PInewood Timer Hardware * ' ************************************************************************* ' P0- Servo (Flag) ' p1- "Pulled Up" N.O. pushbutton to gnd (Start) ' P2- "Pulled Down" N.O. pushbutton to V+ (lane 1 sense) ' P3- "Pulled Down" N.O. pushbutton to V+ (lane 2 Sense) ' P4- ' P5- ' P6- ' P7- ' P8- ' P9- Speaker Out 'P10- Red LED 'P11- Yellow LED 'P12- Yellow LED 'P13- Green LED 'P14- Seetron Serial LCD ' ************************ ' * Constants * ' ************************ N9600 CON $4054 ' LCD Baudmode-9600 bps inverted. Use $40F0 for BS2-SX. I CON 254 ' LCD Instruction prefix value. CLR CON 1 ' LCD clear-screen instruction. LINE2 CON 192 ' LCD Address of 1st char of 2nd line. TOP CON 2 ' LCD CRSR to home position LOWPos CON 50 ' Sonar Value for closest note HIGHPos CON 1100 ' Sonar Value for furthest note NNotes CON 14 ' Number of notes to play in the blues scale ' ************************ ' * Variables * ' ************************ sample VAR Word ' time value cntI VAR Byte ' used in FOR loops Duration VAR Word ' used to hold MS of time the note is played Freq VAR Word ' Frequency to play Note VAR Word ' Note Number (0-7) NotePos VAR Byte ' Number of division in space above the sensor Rest VAR Word ' Number of ticks measured on the sync pulse NoteTicks VAR Byte ' Number of notes to play between sync btnWrk VAR Byte ' Button Workspace ' ************************ ' * Note Table * ' ************************ ' The naming convention for note constants is <(s)sharp/(b)flat/(n)atural> ' So, for "C Sharp in the 4th octave" it would be "Cs4". ' Notes are in HZ values (rounded to nearest Hz) 'C# and Bb and 'D# and Eb are the same in all octaves Cn4 CON 262 Cs4 CON 277 'dup Db4 CON 277 'dup Dn4 CON 294 Ds4 CON 311 'dup Eb4 CON 311 'dup En4 CON 330 Fn4 CON 349 Fs4 CON 370 'dup Gb4 CON 370 'dup Gn4 CON 392 Gs4 CON 415 'dup Ab4 CON 415 'dup An4 CON 440 As4 CON 466 'dup Bb4 CON 466 'dup Bn4 CON 494 Cn5 CON 523 Cs5 CON 554 'dup Db5 CON 554 'dup Dn5 CON 587 Ds5 CON 622 'dup Eb5 CON 622 'dup En5 CON 659 Fn5 CON 698 Fs5 CON 740 'dup Gb5 CON 740 'dup Gn5 CON 784 Gs5 CON 830 'dup Ab5 CON 830 'dup An5 CON 880 As5 CON 932 'dup Bb5 CON 932 'dup Bn5 CON 988 Cn6 CON 1047 Cs6 CON 1109 'dup Db6 CON 1109 'dup Dn6 CON 1175 Ds6 CON 1245 'dup Eb6 CON 1245 'dup En6 CON 1319 Fn6 CON 1397 Fs6 CON 1480 'dup Gb6 CON 1480 'dup Gn6 CON 1568 Gs6 CON 1661 'dup Ab6 CON 1661 'dup An6 CON 1760 As6 CON 1865 'dup Bb6 CON 1865 'dup Bn6 CON 1976 Cn7 CON 2093 Cs7 CON 2217 'dup Db7 CON 2217 'dup Dn7 CON 2349 Ds7 CON 2489 'dup Eb7 CON 2489 'dup En7 CON 2637 Fn7 CON 2794 Fs7 CON 2960 'dup Gb7 CON 2960 'dup Gn7 CON 3136 Gs7 CON 3322 'dup Ab7 CON 3322 'dup An7 CON 3520 As7 CON 3729 'dup Bb7 CON 3729 'dup Bn7 CON 3951 Cn8 CON 4186 ' ************************ ' * Initialize * ' ************************ Clock CON 240 ' The clock frequency in MS from rise to fall of SQ wave OffSet CON 10 Notepos = (HighPos - LowPos) / NNotes ' Determine how many discrete positions ' above the sensor there should be cntI = 0 HIGH LED3 HIGH LED2 ' ************************ ' * Main Code * ' ************************************************************************* SyncWait: BUTTON SYNC, 1, 255, 0, BtnWrk, 0, SyncWait ' Wait for a sync pulse AROUND: ' Loop return point TOGGLE LED1 'TOGGLE LED2 'TOGGLE LED3 'TOGGLE LED4 DO WHILE BTN1=0 ' Check for "drone" button and play drone sound if pressed LOW LED2 Duration = Clock FREQOUT Speaker,Duration,Cn4/2, Cn4 'Actually play the note! PAUSE offset HIGH LED2 LOW LED3 Duration = Clock FREQOUT Speaker,Duration,Cn4/2, Cn4 'Actually play the note! PAUSE offset HIGH LED3 LOW LED1 Duration = Clock FREQOUT Speaker,Duration,Cn4/2, Cn4 'Actually play the note! PAUSE offset HIGH LED1 LOW LED4 Duration = Clock FREQOUT Speaker,Duration,Cn4/2, Cn4 'Actually play the note! PAUSE offset HIGH LED4 LOW LED1 Duration = Clock FREQOUT Speaker,Duration,Cn4/2, Cn4 'Actually play the note! PAUSE offset HIGH LED1 LOW LED3 Duration = Clock FREQOUT Speaker,Duration,Cn4/2, Cn4 'Actually play the note! PAUSE offset HIGH LED3 LOW LED2 Duration = Clock FREQOUT Speaker,Duration,Cn4/2, Cn4 'Actually play the note! PAUSE offset HIGH LED2 LOW LED1 Duration = Clock FREQOUT Speaker,(Duration-10),As4/4, As4/2 'Actually play the note! HIGH LED1 SyncWait2: BUTTON SYNC, 1, 255, 0, BtnWrk, 0, SyncWait2 ' Wait for a sync pulse LOOP cntI=1 'Set number of notes per clock pulse to 1 (1/4 notes) Duration = Clock *2 IF btn2 = 0 THEN cntI = 2 'Set number of notes per clock pulse to 2 (1/8 notes) Duration = Clock 'Set 1/8 note duration ' LOW LED4 ' HIGH LED2 ENDIF IF btn3 = 0 THEN cntI = 4 'Set number of notes per clock pulse to 4 (1/16 notes) Duration = Clock/2 'Set 1/8 note duration note: timing is getting tricky, ' LOW LED2 ' HIGH LED4 ENDIF FreePlay: PULSOUT PING, 5 ' Send a ping to check hand position PULSIN PING, 1, Sample ' read the return time and store it in "Sample1" IF Sample > HighPos THEN SyncWait ' Don't play if the hand is not present ' This line pics the note based on the sensed hand position Note = (SAMPLE - LowPos) / NotePos ' C blues scale C - Eb - F - Gb - G - Bb - C ' Pitch DEcreases as distance decreases 'LOOKUP NOTE, [Bb5, Cn6, Eb6, Fn6, Gb6, Gn6, Bb6, Cn7, Eb7, Fn7, Gb7, Gn7, Bb7, Cn8], FREQ ' Pitch INcreases as distance decreases - More "Theremin-like" LOOKUP NOTE, [Cn8, Bb7, Gn7, Gb7, Fn7, Eb7, Cn7, Bb6, Gn6, Gb6, Fn6, Eb6, Cn6, Bb5], FREQ LOW CntI+6 'LED light sequence PlayNote: FREQOUT Speaker,Duration-5,Freq, (freq/4)-5 'play note and 2 octaves down minus 5 hz for chorusing 'PAUSE offset +5 HIGH CntI+6 'LED light sequence cntI = cntI - 1 IF cntI > 0 THEN FreePlay GOTO SyncWait ' ************************ ' * Reference Section * ' ************************************************************** 'Notes: 'Another cool website: 'http://www.phy.mtu.edu/~suits/notefreqs.html ' From this web site: ' http://www.jazclass.aust.com/scales/scablu.htm ' 1. C Blues scale ' C - Eb - F - Gb - G - Bb - C ' 2. G Blues scale ' G - Bb - C - Db - D - F - G ' 3. D Blues scale (Down - Up - Top) ' D - F - G - Ab - A - C - D ' 4. A Blues scale ' A - C - D - Eb - E - G - A ' 5. E Blues scale ' E - G - A - Bb - B - D - E ' 6. B Blues scale (Down - Up - Top) ' B - D - E - F - F# - A - B ' 7. F# AND Gb Blues scales ' F# - A - B - C - C# - E - F# ' Gb - A - B - C - Db - E - Gb ' 8. Db AND C# Blues scales ' Db - E - Gb - G - Ab - B - Db ' C# - E - F# - G - G# - B - C# ' 9. Ab Blues scale (Down - Up - Top) ' Ab - B - Db - D - Eb - Gb - Ab ' 10. Eb Blues scale ' Eb - Gb - Ab - A - Bb - Db - Eb ' 11. Bb Blues scale ' Bb - Db - Eb - E - F - Ab - Bb ' 12. F Blues scale ( Down - Up - Top) ' F - Ab - Bb - B - C - Eb - F