I'm trying to make a tap tempo for an echo sound effect. The delay time (length of time between echoes) is set by a digital potentiometer. The user interfaces with the PIC either by an actual analog potentiometer (using the ADC of the PIC16F676) or by tap tempo. Tap tempo is when you press a button to tap out the beat of how fast or slow you want the echoes to occur.
The PIC checks to see first if the analog potentiometer has been moved. If the analog pot has been moved, then it moves the digital pot to mimic the analog pot. If it hasn't been moved, it waits for a button press.
If the button has been pressed, it then begins counting the time between the first button press and the second. When it detects the second button press, it moves the digital potentiometer according to how much time has elapsed between the two button presses. It's using the TMR0 interrupt to count, so the "ticks" variable is always counting whether or not the PIC is waiting for a second button press. The ticks variable is simply reset to zero when it receives its first button press.
The one complicated part about this program is handling the waiting time between when the program begins running and the first button press, and the waiting time between the last time the user used the tap tempo the next time the user uses the tap tempo. I don't want the echo time to change on the first button press, only on the second button press or subsequent button presses that occur before 265 ticks have elapsed.
I tried to handle this by making the ticks variable loop between 256 and 900 once it counts up to 900, so that when the first button press occurs, it knows that if tapcount is greater than 255, then this is the "first" tap and not the second tap.
Everything is working perfectly except I cannot get it to reset ticks on the "first" tap. For some reason it always goes to the movedigipot1 subroutine on the first tap, so when I press the button for the first time, it changes the echo time. It works correctly on the second buttonpress and all subsequent buttonpresses, but it should not move the digipot on the first press.
Any ideas as to what it is I'm doing wrong here?
Code:#config __CONFIG _CP_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT& _MCLRE_OFF #endconfig ADCON1 = %00000000 ANSEL = %00000111 CMCON = %00000111 TRISA = %00001111 TRISC = %00000000 ' Set TMR0 to interrupt every 16.384 milliseconds OPTION_REG = $55 ' Set TMR0 configuration and enable PORTB pullups INTCON = $a0 ' Enable TMR0 interrupts On Interrupt Goto tickint ' ' Hardware connection ' =================== ' lug 1 of pot to Vdd, lug 3 of pot to Vss CS VAR PORTC.0 SCK VAR PORTC.1 SDI VAR PORTC.2 pushbutton var PORTA.3 'tap tempo button buttonON var PORTC.5 'tap tempo press LED ' ' Variables definition ' =================== x var byte xprevious var byte tapcount var byte ticks var byte ' ' Software/Hardware initialisation ' ================================ cs = 1 ' disable MCP PAUSE 100 ' safe settle time gosub readpot gosub movedigipot1 xprevious = x buttonON = 0 main: tapcount = ticks gosub readpot xprevious = x pause 10 if pushbutton = 0 then goto tappress endif gosub readpot if xprevious != x then 'check to see if potentiometer has moved. If it has moved... gosub movedigipot1 'change delay time endif pause 10 if tapcount > 900 then 'prevent tapcount/ticks variables from becoming too big while waiting for buttonpress ticks = 256 '256 is maximum number of ticks between taps before resetting endif goto main tappress: if tapcount > 255 then 'if more then 255 ticks have elapsed since last tap.... ticks = 0 '.....clear oddtap and return to main gosub debounce else x = tapcount gosub movedigipot1 'change delay time to tap tempo ticks = 0 'clear tapcount and return to main gosub debounce endif goto main debounce: buttonON = 1 do until pushbutton = 1 pause 10 loop buttonON = 0 return movedigipot1: ' subroutine to move 127 step MCP4232 SPI digital potentiometer CS=0 shiftout SDI, SCK, 1, [010001, x + 7] ' move wiper A CS=1 return readpot: adcin 0,x 'read voltage of "delaytime" pot x = x/2 ' convert to 7 bit return ' Interrupt routine to handle each timer tick Disable ' Disable interrupts during interrupt handler tickint: ticks = ticks + 1 ' Count 1/60 of second on every interrupt endif tiexit: INTCON.2 = 0 ' Reset timer interrupt flag Resume end




Bookmarks