Code:
#config
__CONFIG _CP_OFF & _WDTE_OFF & _BOREN_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF
#endconfig
ADCON0 = %00000000
ADCON1 = %00110000
ANSEL = %00000110
define ADC_SAMPLEUS 50
define ADC_BITS 8
DEFINE ADC_CLOCK 3
CMCON0 = %00000111
TRISA = %00001111
TRISC = %00000000
' Set TMR0 interrupt prescaler to 1:32
OPTION_REG = %10000100 ' Set TMR0 configuration and enable PORTB pullups
INTCON = %10100000 ' Enable TMR0 interrupts
On Interrupt Goto tickint
define WRITE_INT 1
'
' Hardware connection
' ===================
CS VAR PORTA.5
SCK VAR PORTC.2
SDI VAR PORTC.1
tempoLED var PORTC.0
tempobutton var PORTA.0
bypassbutton var PORTA.3
bypassLED var PORTC.4
fetA var PORTC.5
fetB var PORTA.4
fetC var PORTC.3
;pot is on porta.2 an2
'
' Variables definition
' ===================
x var word
y var word
w var byte
z var byte
a var byte ' ADC in variable for tempo LED calibration
b var byte ' tempo LED calibration variable used in main program
c var byte ' ADC in variable for tap calibration
d var byte ' tap calibration variable used in main program
plusORminus var bit
plusORminus1 var bit
plusORminus2 var bit
plusORminus3 var bit
ticks var word
LEDcounter var word
LEDrate var word
trailsmodecounter var word
trailsmode var bit
xprevious var byte
override var bit
analogpot var bit
footswitch var bit
analogpot = 1
footswitch = 0
LEDadj var byte
LEDadj1 var byte
tapadj var byte
tapadj1 var byte
calibrationcounter var byte
calibrationon var bit
' Calibration check
'================================================================
calibrationon = 0
read 1, calibrationcounter
if bypassbutton = 0 then 'hold down bypass button on power up to calibrate
goto bypassbuttonrelease
calibrationon = 1
endif
'
' begin in "bypass" state
' ====================
tempoLED = 0
fetA = 0
fetB = 0
fetC = 1
bypassLED = 0
trailsmode = 0
override = analogpot
pause 1000
gosub readpot
gosub movepot
pause 100
' MAIN PROGRAM
'=================================================================
main:
gosub potcheck
if LEDcounter < 3 then
tempoLED = 1
else
tempoLED = 0
endif
if tempobutton = 0 then
if calibrationon = 1 then
goto subtractfromcalibrationcounter
else
goto tempopress
endif
endif
if ticks > 400 then
ticks = 300
endif
if LEDcounter > LEDrate then
LEDcounter = 0
endif
if bypassBUTTON = 0 then
if calibrationon = 1 then
gosub addtocalibrationcounter
else
gosub bypasspress
endif
gosub bypassbuttonrelease
ENDif
goto main
potcheck:
gosub readpot
if abs (xprevious-x) > 4 then
override = analogpot
gosub movepot
endif
return
readpot:
adcin 1,x
x = x * 10
x = x/17
'x = 1 max x
return
movepot:
x = x + calibrationcounter
CS = 0
shiftout SDI, SCK, 1, [00000000,x]
shiftout SDI, SCK, 1, [00010000,x]
CS = 1
x = x - calibrationcounter
if override = analogpot then 'checks to see if the delay time was set by the pot or switch
xprevious = x
endif
gosub tempoLEDadjust
return
tempoLEDadjust: ' compensate for TMR0 not being 1:1 with actual delay time
if x < 25 then
LEDrate = x + 16
elseif x >= 25 and x < 50 then
LEDrate = x + 18
elseif x >= 50 and x < 75 then
LEDrate = x + 20
elseif x >= 75 and x < 95 then
LEDrate = x + 22 'noon to 2 o'clock
elseif x >= 95 and x < 130 then
LEDrate = x + 24 '2 o'clock to 3 o'clock
elseif x > 130 then
LEDrate = x + 26 '3 o'clock to FTCW
endif
return
tempopress:
if ticks >= 180 then ' if longer than 3 45bpm since last press assume this is first press and start ticks counter over
ticks = 0
gosub tempobuttonrelease
goto main
endif
if ticks <= 157 and ticks > 60 then ' set delay time on this press based on how much time has elapsed since last press
x = ticks - 20 ' compensate for TRM0 being slightly faster than 10ms when tempo is slower than 100bpm
gosub division
override = footswitch
gosub movepot
ticks = 0
gosub tempobuttonrelease
goto main
endif
if ticks <= 60 and ticks > 57 then 'tempo between 100bpm and 110bpm
x = ticks - 7
gosub division
override = footswitch
gosub movepot
ticks = 0
gosub tempobuttonrelease
goto main
endif
if ticks < 57 and ticks > 15 then 'tempo faster than 110bpm
x = ticks - 15
gosub division
override = footswitch
gosub movepot
ticks = 0
gosub tempobuttonrelease
goto main
endif
if ticks < 180 and ticks > 157 then ' if tap duration is slighlty longer than max delay time, then set to max delay time.
x = 157 - 7
gosub division
override = footswitch
gosub movepot
ticks = 0
gosub tempobuttonrelease
goto main
endif
if ticks <= 15 then 'tap too fast
x = 3
gosub division
override = footswitch
gosub movepot
ticks = 0
gosub tempobuttonrelease
goto main
endif
goto main
division: ' tap multiplier subroutine
div var byte
adcin 2, w ' read toggle switch on channel 1 and store in w
if w < 51 then ' 1:1 ratio or quarter note
x = x
endif
if w >= 51 and w < 102 then ' 1:1.5 ratio or dotted eigth note
lookup x, [1,1,1,1,1,1,1,1,1,2,2,2,3,3,4,5,6,7,7,8,9,10,11,12,13,13,14,15,15,16,16,17,17,17,18,19,19,20,21,22,22,23,_
24,24,25,25,26,27,28,28,29,30,30,31,33,33,34,35,35,36,37,37,38,38,39,39,40,40,41,42,42,43,44,45,46,47,47,48,49,_
50,50,51,51,52,52,53,54,54,55,55,56,57,58,58,60,60,61,61,62,63,63,64,65,66,66,66,67,68,69,69,69,70,71,72,72,72,73,74,75,75,75,_
76,77,77,78,78,79,80,81,82,82,82,82,83,84,84,85,86,86,87,88,89,89,90,91,92,92,92,93,93,94,94], div
x = div
endif
if w >= 102 and w < 153 then '1:2 ratio or eigth note
lookup x, [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,3,3,4,4,5,5,6,6,7,7,8,8,8,9,10,11,11,12,13,14,14,15,_
15,15,16,16,16,17,17,18,18,19,19,20,20,21,22,22,23,23,23,24,24,25,25,25,26,26,27,27,28,28,29,29,30,31,32,33,33,34,34,35,35,36,36,_
37,37,38,39,39,39,40,40,41,42,42,42,43,43,44,44,45,45,46,46,46,47,47,48,48,48,49,49,50,50,51,51,52,53,53,53,54,54,54,55,55,55,57,_
57,58,58,58,58,60,60,60,60,62,62,62,62,4,64,64,64,66,66,66,66,68,68,68,68], div
x = div
endif
if w >= 153 and w < 204 then '1:3 ratio (triplets)
lookup x, [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,4,_
4,4,5,5,5,5,6,6,7,7,7,8,8,9,9,10,10,11,11,12,12,12,13,13,13,14,14,14,15,15,15,16,16,16,17,17,17,17,17,18,18,19,19,_
20,20,20,21,21,21,22,22,22,23,23,23,24,24,24,25,25,25,26,26,26,26,27,27,27,27,27,28,28,28,29,29,30,30,30,31,31,32,33,33,33,34,_
34,35,35,35,35,36,36,36,36,37,37,37,37,38,38,38,38,39,39,39,39,40,40,40,40], div
x = div
endif
if w > 204 then ' 1:4 ratio or 16th note
lookup x, [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,_
3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,7,7,7,8,8,9,9,9,10,10,11,11,12,12,12,12,13,13,13,14,14,14,14,15,15,15,15,16,16,16,16,16,_
17,17,17,17,17,17,18,18,18,18,19,19,19,19,20,20,21,21,21,21,21,21,22,22,22,22,23,23,23,23,24,24,24,24,24,25,25,25,25,25,25,26,26,26,_
27,27], div
x = div
endif
return
tempobuttonrelease: ' debounce subroutine for tempo button
returnTOpotCounter var word
returnTOpotCounter = 0
tempoLED = 1
do until returnTOpotCounter >= 200
if tempobutton = 1 then exit
pause 10
pause 10
pause 10 ' pause 30ms. Break up into 10ms to not interfer with interrupt timer
returnTOpotCounter = returnTOpotCounter + 3
loop
tempoLED = 0
pause 10
pause 10
pause 10
if returnTOpotCounter >= 200 then
gosub returnTOpot
endif
return
returnTOpot:
gosub readpot
gosub movepot
onORoff var bit
onORoff = bypassLED
m var byte
for m = 1 to 5
bypassLED = 1
pause 200
bypassLED = 0
pause 200
next m
bypassLED = onORoff
return
bypasspress:
pause 10
pause 10
trailsmodecounter = 0 ' waits to see if you want to switch between normal or trails mode
do until trailsmodecounter = 200
if bypassbutton = 1 then exit
pause 10
trailsmodecounter = trailsmodecounter + 1
loop
if trailsmodecounter = 200 then
goto trailmodechange
endif
if trailsmode = 1 then
gosub trailsbypass
elseif trailsmode = 0 then
gosub normalbypass
endif
return
trailmodechange: ' subroutine that occurs when bypass button is held long enough to change between normal or trails mode
if trailsmode = 1 then
trailsmode = 0
elseif trailsmode = 0 then
trailsmode = 1
endif
for z = 1 to 5
tempoLED = 1
pause 200
tempoLED = 0
pause 200
next z
goto main
normalbypass: ' subroutine for normal bypass
if bypassLED = 0 then
fetA = 1
fetB = 1
fetC = 0
bypassLED = 1
elseif bypassLED = 1 then
fetA = 0
fetB = 0
fetC = 1
bypassLED = 0
endif
return
trailsbypass: 'subroutine for trails bypass
if bypassLED = 0 then
fetA = 1
fetB = 1
fetC = 0
bypassLED = 1
elseif bypassLED = 1 then
fetA = 0
fetB = 1
fetC = 1
bypassLED = 0
endif
return
bypassbuttonrelease: ' debounce subroutine when bypass button is pressed
do until bypassbutton = 1
pause 10
pause 10
pause 10
loop
return
addtocalibrationcounter:
bypassbuttoncounter var word
bypassbuttoncounter = 0
do until bypassbutton = 1
pause 10
pause 10
pause 10
bypassbuttoncounter = bypassbuttoncounter + 1
loop
if bypassbuttoncounter > 200 then
write 1, calibrationcounter
calibrationon = 0
else
calibrationcounter = calibrationcounter + 1
endif
return
subtractfromcalibrationcounter:
calibrationcounter = calibrationcounter - 1
do until tempobutton = 1
pause 10
pause 10
pause 10
loop
return
Disable ' Disable interrupts during interrupt handler
tickint: ' Interrupt routine to handle each timer tick
ticks = ticks + 1
LEDcounter = LEDcounter + 1
tiexit:
INTCON.2 = 0 ' Reset timer interrupt flag
Resume
enable
end
Bookmarks