thunderace7
New Member
Hi. I want to find out a bit about shift registers and how they can be used for led sequencing. Does anyone know of a good tutorial? Or maybe there is a simple project I could take a look at?
Thanks.
Thanks.
Unfortunately, without seeing how your code is structured, members are unable offer much assistance. GoTo statements taking execution out of a subroutine and bypassing a return statement are usually fatal as far as programming goes. While it is possible to manage the use of GoTos, I avoid them like 'the' current virus! Please post your code.There are a few issues with this program but I think I have most of them resolved to the extent that it passes the syntax check and will run in the editor. There is, however, one issue I would like some help with, please.
The program has a subroutine that contains an IF-THEN test. If this is fulfilled the program flow jumps out of the subroutine with a GOTO command before it gets to the RETURN.
Is this going to cause a stack overflow error of some kind or will all the unused return locations fall off the bottom of the stack when it gets full?
If I have to move the IF-THEN test out of the subroutine it will add another couple of hundred lines of code to the program.
Thanks.
...
gosub MySub
if b1 <> 0 then DoAJump
....
MySub:
b1 = 0
....
if .... then ' need to "jump out"
b1 = 1
goto EndMySub
endif
......
EndMySub:
return
It is probably worth posting the code you have created and describing exactly what you need the program to do from the 'big picture' perspective because, as said; there is probably some easier way to achieve what you want to do.There is an interrupt subroutine that sets a flag and this routine checks for the flag being set and takes appropriate action.
initialise:
#picaxe 08m2
Setfreq M4
Symbol patternselect=b0
Symbol currentpattern=b1
Symbol i=b2
Symbol delay=b3
Symbol k=b4
Symbol val=w3
Symbol lsb=w4
Symbol pausetime=w5
Symbol sequence=w6
Let dirs=%00010101
Symbol dataline=C.0
Symbol clockline=C.4
Symbol latch=C.2
Symbol switch1=pinC.3
Symbol potentiometer=C.1
Let sequence=%0000000000000000
Gosub outsequence
Pause 400
Let patternselect=0
Setint %00001000,%00001000
main:
Readadc potentiometer,delay
pausetime=delay*2
If patternselect =1 Then
Goto pattern1
end if
If patternselect =2 Then
Goto pattern2
end if
If patternselect =3 Then
Goto pattern3
end if
If patternselect =4 Then
Goto pattern4
end if
If patternselect =5 Then
Goto pattern5
end if
If patternselect =6 Then
Goto pattern6
end if
If patternselect =7 Then
Goto pattern7
end if
If patternselect=8 Then
Goto pattern8
end if
If patternselect=9 Then
Goto pattern9
end if
If patternselect=10 Then
Goto pattern10
end if
If patternselect=11 Then
Goto pattern11
end if
If patternselect=12 Then
Goto pattern12
end if
If patternselect>=13 Then
Goto patternblank
end if
Goto main
outsequence:
Let val=sequence
For i=1 To 16
Let lsb=val&%000000000000001
If lsb=1 Then High dataline
Else Low dataline
endif
Pulsout clockline,1
Let val=val/2
Next i
Pulsout latch,1
Return
interrupt:
debounce1:
If switch1=1 Then
Goto debounce2
end if
Goto debounce1
debounce2:
If switch1=0 Then
Goto patterncount
end if
Goto debounce2
patterncount:
Inc patternselect
Setint %00001000,%00001000
Return
pattern1:
Let currentpattern=patternselect
Let sequence=%1000000110000001
Pause pausetime
Gosub outsequence
Let sequence=%1100001111000011
Pause pausetime
Gosub outsequence
If patternselect <> currentpattern Then
Goto main
endif
Let sequence=%1110011111100111
Pause pausetime
Gosub outsequence
Let sequence=%1111111111111111
Pause pausetime
Gosub outsequence
If patternselect <> currentpattern Then
Goto main
endif
Let sequence=%0111111001111110
Pause pausetime
Gosub outsequence
Let sequence=%0011110000111100
Pause pausetime
Gosub outsequence
If patternselect <> currentpattern Then
Goto main
endif
Let sequence=%0001100000011000
Pause pausetime
Gosub outsequence
Let sequence=%0000000000000000
Pause pausetime
Gosub outsequence
Goto main
pattern2:
Let currentpattern=patternselect
Let sequence=%1111000011110000
Pause pausetime
Gosub outsequence
If patternselect <> currentpattern Then
Goto main
endif
Let sequence=%0000111100001111
Pause pausetime
Gosub outsequence
Goto main
pattern3:
; code deleted to avoid breaking 10000 character limit
Goto main
pattern4:
Let currentpattern=patternselect
Let sequence=%1100110011001100
Pause pausetime
Gosub outsequence
If patternselect <> currentpattern Then
Goto main
endif
Let sequence=%0011001100110011
Pause pausetime
Gosub outsequence
Goto main
pattern5:
Let currentpattern=patternselect
Let sequence=%1000000000000010
Pause pausetime
Gosub outsequence
If patternselect <> currentpattern Then
Goto main
endif
Let sequence=%0100000000000001
Pause pausetime
Gosub outsequence
Goto main
pattern6:
Let currentpattern=patternselect
Let sequence=%0000000000000000
Gosub outsequence
Pause pausetime
Let sequence=%0000000000000001
Gosub outsequence
Pause pausetime
For k=1 To 15
If patternselect <> currentpattern Then
Goto main
endif
Let sequence=sequence * 2
Gosub outsequence
If patternselect <> currentpattern Then
Goto main
endif
Pause pausetime
Next k
Let sequence=%0000000000000000
Gosub outsequence
Pause pausetime
If patternselect <> currentpattern Then
Goto main
endif
Let sequence=%1000000000000000
Gosub outsequence
Pause pausetime
For k=1 To 15
If patternselect <> currentpattern Then
Goto main
endif
Let sequence=sequence/2
Gosub outsequence
Pause pausetime
Next k
Pause pausetime
Goto main
pattern7:
Let currentpattern=patternselect
Let sequence=%1110011111100111
Pause pausetime
Gosub outsequence
If patternselect <> currentpattern Then
Goto main
endif
Let sequence=%0001100000011000
Pause pausetime
Gosub outsequence
If patternselect <> currentpattern Then
Goto main
endif
Let sequence=%1110011001100111
Pause pausetime
Gosub outsequence
If patternselect <> currentpattern Then
Goto main
endif
Let sequence=%1111111111111111
Pause pausetime
Gosub outsequence
If patternselect <> currentpattern Then
Goto main
endif
Let sequence=%0111111001111110
Pause pausetime
Gosub outsequence
If patternselect <> currentpattern Then
Goto main
endif
Let sequence=%0011110000111100
Pause pausetime
Gosub outsequence
If patternselect <> currentpattern Then
Goto main
endif
Let sequence=%0001100000011000
Pause pausetime
Gosub outsequence
If patternselect <> currentpattern Then
Goto main
endif
Let sequence=%0000000000000000
Pause pausetime
Gosub outsequence
Goto main
pattern8:
; code deleted to avoid breaking 10000 character limit
Goto main
pattern9:
Let currentpattern=patternselect
Let sequence=%0000000000000000
Pause pausetime
Gosub outsequence
If patternselect <> currentpattern Then
Goto main
endif
Let sequence=%1111111111111111
Pause pausetime
Gosub outsequence
Goto main
pattern10:
; code deleted to avoid breaking 10000 character limit
Goto main
pattern11:
Let currentpattern=patternselect
Let sequence=%0010001000100010
Pause pausetime
Gosub outsequence
If patternselect <> currentpattern Then
Goto main
endif
Let sequence=%0001000100010001
Pause pausetime
Gosub outsequence
Goto main
pattern12:
Let currentpattern=patternselect
Let sequence=%0100010001000100
Pause pausetime
Gosub outsequence
If patternselect <> currentpattern Then
Goto main
endif
Let sequence=%1000100010001000
Pause pausetime
Gosub outsequence
Goto main
patternblank:
Let sequence=%0000000000000000
Gosub outsequence
Let patternselect=0
Goto main
outsequence:
if patternselect <> currentpattern Then
Goto main
endif
Let val=sequence
For i=1 To 16
Let lsb=val&%000000000000001
If lsb=1 Then High dataline
Else Low dataline
endif
Pulsout clockline,1
Let val=val/2
Next i
Pulsout latch,1
Return
interrupt:
debounce1:
If switch1=1 Then
Goto debounce2
end if
Goto debounce1
debounce2:
If switch1=0 Then
Goto patterncount
end if
Goto debounce2
patterncount:
Inc patternselect
Setint %00001000,%00001000
Return
#Picaxe 20M2
#No_Data
Symbol END_OF_PATTERN = $FF
Symbol PAUSE_TIME_MS = 500
Symbol PUSH_BUTTON = pinC.0
Symbol reserveW0 = w0 ; b1:b0
Symbol pauseTimer = w1 ; b3:b2
Symbol patternSelect = b4
Symbol stepSelect = b5
Symbol sequence = b6
Symbol buttonState = b7
MainLoop:
Do
Do
If stepSelect = END_OF_PATTERN Then
stepSelect = 0
End If
Select Case patternSelect
Case 0 : Gosub Pattern0
Case 1 : Gosub Pattern1
Case 2 : Gosub Pattern2
Else : Gosub NoMorePatterns
End Select
Loop While stepSelect = END_OF_PATTERN
Gosub OutputSequence
stepSelect = stepSelect + 1
Gosub PauseAndCheckButtonPush
Loop
NoMorePatterns:
patternSelect = 0
NoMoreSteps:
stepSelect = END_OF_PATTERN
Return
Pattern0:
Select Case stepSelect
Case 0 : sequence = %01010101
Case 1 : sequence = %10101010
Else : Gosub NoMoreSteps
End Select
Return
Pattern1:
Select Case stepSelect
Case 0 : sequence = %00001111
Case 1 : sequence = %11110000
Else : Gosub NoMoreSteps
End Select
Return
Pattern2:
Select Case stepSelect
Case 0 : sequence = %00000001
Case 1 : sequence = %00000010
Case 2 : sequence = %00000100
Case 3 : sequence = %00001000
Case 4 : sequence = %00010000
Case 5 : sequence = %00100000
Case 6 : sequence = %01000000
Case 7 : sequence = %10000000
Else : Gosub NoMoreSteps
End Select
Return
PauseAndCheckButtonPush:
pauseTimer = 0
Do
If PUSH_BUTTON <> buttonState Then
buttonState = buttonState ^ 1
If buttonState = 1 Then
patternSelect = patternSelect + 1
stepSelect = 0
Return
End If
End If
#IfDef SIMULATING
Pause PAUSE_TIME_MS
Return
#EndIf
Pause 10
pauseTimer = PauseTimer + 10
Loop Until pauseTimer >= PAUSE_TIME_MS
Return
Outputsequence:
dirsB = $FF
pinsB = sequence
Return
True enough, but an interrupt will not be triggered within an interrupt unless you have again executed the SETINT command. That is why you don't do that until immediately before the RETURN. Pausing within an interrupt is usually discouraged, but in this case if you are getting bounce retriggerings when you leave the interrupt, you might inside the interrupt loop until the button is released (PAUSE 200: DO WHILE switch=1: LOOP) and then pause say 200ms to get past any release bounce.Interrupts, however, are a different matter and more susceptible to the inconsistencies of human behaviour.
main:
do
pause 1000
inc b0
sertxd("Entered loop ",#b0,cr,lf)
sertxd("Gosub main ",#b0,cr,lf)
gosub main
sertxd("Return",#b0,cr,lf)
return
sertxd("Loop end",#b0,cr,lf)
loop
Great idea. Something likeIt is easy, worthwhile and interesting to do a simple breadboard experiment to see how long switch bounce interrupts complete switch closure
setfreq m32
w1=1000 ' initial count period
For b4 = 1 to 20
do while switch=0: loop
count pinx.y,w1,w0
sertxd("Period: ",#w1," bounces: ",#w0)
do while switch=1: loop
w1=w1-50
next b4
At what SETFREQ speed? If m32, that would mean bouncing for nearly 200ms.Bouncing seems to stop at 1500