PDA

View Full Version : What does this error message mean?



keithv
- 7th December 2021, 23:25
[ASM ERROR] Argument out of range (2135 not between 0 and 2047) (0) : Error[126]

When I click "compile" the progress bar gets all the way up to 100% and then it goes from green to red and I get this message at the bottom.

Jerson
- 8th December 2021, 02:41
Since you haven't shown the relevant code fragment, I suspect you are getting an error at a branch instruction that is branching past the 2048 bytes page size.

keithv
- 8th December 2021, 17:48
How do I locate the relevant code fragment?

Jerson
- 9th December 2021, 14:14
Post your code. It is easier for experienced members to help you as they might be able to try out the code to see the issue you have.

keithv
- 9th December 2021, 20:26
Sorry. It's pretty long. This is for use with an electronic music effect device - and echo module. It's doing 3 main things. The first is a signal routing/bypass that uses A5, C3, and C5 to turn various JFETs on and off. The second is controlling a digital potentiometer to control the delay time of two delay chips in series. The delay time can be manipulated with either an analog pot which is read at pin A1. The other is by tapping out the tempo on a push button switch connected to A0. The third main thing that this program does is use an interrupt to count the time between tempo taps and translates that into the wiper position on the digital pot. There's a couple other minor things too, like making LEDs blink and such.

The base of this program works just fine. But recently, since production of semiconductors started back up after COVID, the specs of the delay chip I'm using are not as tight anymore. This has required me to add a "calibration" feature to the program. So it's only after adding this calibration feature that I've gotten the error messages.




#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,2 2,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,4 7,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,7 1,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,3 1,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,5 3,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,1 7,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,3 0,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,2 4,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

richard
- 9th December 2021, 21:19
the most vital info is missing , what pic chip ?

keithv
- 9th December 2021, 22:35
Duh. Sorry. I'm a pretty much a newb and it's been at least a year since I've used PBP. It took me like 2 days to figure everything that was going on here, and I was the one that wrote it.

I'm using the PC16F684

If it helps, here's link to the schematic http://byocelectronics.com/echoroyalschematic.pdf

keithv
- 9th December 2021, 22:48
I'm using the PIC16F684. The previous version of this code worked just fine when the PT2399 delay chip had a very precise delay time, but they have become inconsistent which causes the tap tempo feature to be slightly out of sync with the delay time. I'm trying to add a "calibration" feature to sync the actual delay time with the tap tempo by adding or subracting postions on the digital potentiometer.

I've reposted the code and highlighted the parts that have been added or modified in blue. Here's a link to the schematic http://byocelectronics.com/echoroyalschematic.pdf The idea is that if the user is holding down SW2 during power up, it will go into "calibration mode". SW2 should now add 1 movement on the digital pot and SW1 should remove one movement. Holding down SW2 for 3 seconds should WRITE calibrationcounter to memory and return to normal function.

I forgot to mention the VR6 "tap multiplier" function, in case you're wondering what all the weird lookup tables are there for. This is a feature commonly requested by guitar players when using a delay/echo effect. It's used with the tap tempo. It sets the delay time so that the echoes will beat at straight quarter note, dotted eighth note, triplet, or 16th intervals and the user only needs to tap out a straight quarter note beat.





#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,2 2,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,4 7,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,7 1,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,3 1,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,5 3,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,1 7,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,3 0,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,2 4,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

richard
- 9th December 2021, 23:14
I'm using the PIC16F684

i should have asked what version of pbp also , not that it matters in this case the problem is that the code will no longer fit in the chip
you need to trim the code down or get a bigger chip

keithv
- 9th December 2021, 23:22
i should have asked what version of pbp also , not that it matters in this case the problem is that the code will no longer fit in the chip
you need to trim the code down or get a bigger chip

I was worried about that. I'm using PBP3.0 midrange edition. I seem to recall a little counter in the lower left hand corner of the dev environment that told you how much space your code was using. I can't find it now.

richard
- 9th December 2021, 23:25
typo ?



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,3 1,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,5 3,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

richard
- 9th December 2021, 23:30
can't find it now.

you only get it if it's an ok compile

keithv
- 9th December 2021, 23:41
typo ?



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,3 1,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,5 3,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

Wow. Nice catch. Eighth is spelled incorrectly too.

keithv
- 9th December 2021, 23:43
you only get it if it's an ok compile

That explains a lot. I should have realized what the problem was since the flash on the 16F684 is 2048 and the compiler was complaining about something being more than 2047.

Jerson
- 10th December 2021, 02:26
A lot has transpired while I was asleep in my TimeZone. I think you found your answer.

richard
- 10th December 2021, 02:55
you can always replace pbp's highly inefficient lookups with asm tables for byte sized data
just make sure the index will not to exceed the table's number of entries

this is a slightly incomplete and untested example of asm table

since your table data never exceeds 7 bits a packed 14 bit "DA" table could be used also
halving the data size yet again [see my packed fonts for ssd1306 etc ] an unpacking routine
is simple and quick





#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,1 7,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,3 0,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,2 4,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 ..............................

keithv
- 10th December 2021, 20:52
Thank you very much for that lesson, Richard. I really need to work on learning ASM.

I checked the amount of flash used on the previous version. It's at exactly 2k words with the inefficient PBP look up tables. The 16F684 has 2048 words, so I'm assuming the new modification added 135 words based on the error msg. Is switching the look up tables to ASM going to free up enough space?

Switching to a 16F1xxx chip would obviously solve the problem, as they have more flash and they are actually cheaper! The 16F1613 for example is almost $1.25ea. less. I have to upgrade my version of PBP, but it will pay for itself pretty quickly. So I think I'm going to do that regardless of whether or not I can cram it all into a 16F684. The most practical solution to my real problem is to make R44 an internal trimpot, but that will have to wait till the next production run of PCBs.

richard
- 10th December 2021, 21:33
Is switching the look up tables to ASM going to free up enough space?

easily , the one i completed saved 15 words at least all four would get another 30 or 40 i expect

replacing your readpot routine with this gets another 40 by eliminating that costly divide

readpot:
adcin 1,x
x=x*/151 '***************
return

richard
- 11th December 2021, 00:47
One other thing I notice is that the tables mostly have 152 members , x is always between 0 and 150 as far as i can see

the second table had 153 members , typo ?

keithv
- 25th January 2022, 00:16
One other thing I notice is that the tables mostly have 152 members , x is always between 0 and 150 as far as i can see

the second table had 153 members , typo ?

Yep. That was a typo. Thanks for catching that.

Thanks so much for helping me with this. Sorry for not getting back sooner. I was out for two weeks with Covid and then I got sidetracked by a bunch of year-end stuff. Anyhow...The program doesn't work because of some mistake I made in the new calibration routine. But I did swap out the look up tables with your new ASM tables in the original "verified" program and they work perfectly. And saved 25 words!

So now I've got to work on the calibration routine. I should be able to make it work in 47 words. After setting it aside for a while, I think I'm going to start over and come at it from a different angle.