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
' ===================
LU_TMP var word temporary storage for tables
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
call lu1
@ MOVE?AB _x
endif
if w >= 102 and w < 153 then '1:2 ratio or eighth note
call lu2
@ MOVE?AB _x
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
lu1:
asm ; ok for pic 16 or 18
MOVE?BA _x ; x is the index watch its size
BANKSEL _LU_TMP
BCF STATUS,C
ifdef TBLPTRL
RLCF WREG,F
endif
CLRF _LU_TMP+1
addlw low(lu1_t)
movwf _LU_TMP
ifdef TBLPTRL
RLCF _LU_TMP+1,w
else
RLF _LU_TMP+1,w
endif
BANKSEL 0
addlw high(lu1_t )
movwf PCLATH
movf _LU_TMP,w
movwf PCL
lu1_t ;start of table data
RETLW 1
RETLW 1
RETLW 1
RETLW 1
RETLW 1
RETLW 1
RETLW 1
RETLW 1
RETLW 1
RETLW 2
RETLW 2
RETLW 2
RETLW 3
RETLW 3
RETLW 4
RETLW 5
RETLW 6
RETLW 7
RETLW 7
RETLW 8
RETLW 9
RETLW 10
RETLW 11
RETLW 12
RETLW 13
RETLW 13
RETLW 14
RETLW 15
RETLW 15
RETLW 16
RETLW 16
RETLW 17
RETLW 17
RETLW 17
RETLW 18
RETLW 19
RETLW 19
RETLW 20
RETLW 21
RETLW 22
RETLW 22
RETLW 23
RETLW 24
RETLW 24
RETLW 25
RETLW 25
RETLW 26
RETLW 27
RETLW 28
RETLW 28
RETLW 29
RETLW 30
RETLW 30
RETLW 31
RETLW 33
RETLW 33
RETLW 34
RETLW 35
RETLW 35
RETLW 36
RETLW 37
RETLW 37
RETLW 38
RETLW 38
RETLW 39
RETLW 39
RETLW 40
RETLW 40
RETLW 41
RETLW 42
RETLW 42
RETLW 43
RETLW 44
RETLW 45
RETLW 46
RETLW 47
RETLW 47
RETLW 48
RETLW 49
RETLW 50
RETLW 50
RETLW 51
RETLW 51
RETLW 52
RETLW 52
RETLW 53
RETLW 54
RETLW 54
RETLW 55
RETLW 55
RETLW 56
RETLW 57
RETLW 58
RETLW 58
RETLW 60
RETLW 60
RETLW 61
RETLW 61
RETLW 62
RETLW 63
RETLW 63
RETLW 64
RETLW 65
RETLW 66
RETLW 66
RETLW 66
RETLW 67
RETLW 68
RETLW 69
RETLW 69
RETLW 69
RETLW 70
RETLW 71
RETLW 72
RETLW 72
RETLW 72
RETLW 73
RETLW 74
RETLW 75
RETLW 75
RETLW 75
RETLW 76
RETLW 77
RETLW 77
RETLW 78
RETLW 78
RETLW 79
RETLW 80
RETLW 81
RETLW 82
RETLW 82
RETLW 82
RETLW 82
RETLW 83
RETLW 84
RETLW 84
RETLW 85
RETLW 86
RETLW 86
RETLW 87
RETLW 88
RETLW 89
RETLW 89
RETLW 90
RETLW 91
RETLW 92
RETLW 92
RETLW 92
RETLW 93
RETLW 93
RETLW 94
RETLW 94
ENDasm
lu2:
asm
MOVE?BA _x
BANKSEL _LU_TMP
BCF STATUS,C
ifdef TBLPTRL
RLCF WREG,F
endif
CLRF _LU_TMP+1
addlw low(lu2_t)
movwf _LU_TMP
ifdef TBLPTRL
RLCF _LU_TMP+1,w
else
RLF _LU_TMP+1,w
endif
BANKSEL 0
addlw high(lu2_t )
movwf PCLATH
movf _LU_TMP,w
movwf PCL
lu2_t
RETLW 1
RETLW 1
RETLW 1
RETLW 1
RETLW 1
RETLW 1
RETLW 1
RETLW 1
RETLW 1
RETLW 1
RETLW 1
RETLW 1
RETLW 1
ETC ETC ETC ..............................
Bookmarks