As the subjects says: I’m having problems with double subroutines, when i press a button to go to a subroutine, the program always runs the routine twice.
I read a lot of topics here about the subject, one solution is adding a bigger pause (200ms) but then the arm moves very shaky!
an other solution to the problem that is discussed here is the code on the bottom:
But the problem is,that I don’t understand this!!
can somebody explain this??
Ill ad my own code as well, I guess that the experienced people have then all the information, regarding hardware and all. And hopefully someone can help me with the solution.
Thank you
;ControlInput:
;
; low PS2SEL
; shiftout PS2CMD,PS2CLK,FASTLSBPRE,$1\8,$42\8]
; shiftin PS2DAT,PS2CLK,FASTLSBPOST,[DualShock(0)\8, DualShock(1)\8, DualShock(2)\8, DualShock(3)\8, |
; DualShock(4)\8, DualShock(5)\8, DualShock(6)\8]
; high PS2SEL
; pause 10
;
; ; Switch bot on/off
; IF (DualShock(1).bit3 = 0) and LastButton(0).bit3 THEN ;Start Button test
; …
; ENDIF
;
;
;
;
; … end of function.
; ;Store previous state
; LastButton(0) = DualShock(1)
; LastButton(1) = DualShock(2)
;return moving arm by ps2 controller.bas (6.29 KB)
Yes the commented out code in your post is used to process a button press only once. I will try to explain it in steps. First if your code looks something like this:
Loop:
; get the PS2 inputs...
IF (DualShock(1).bit3 = 0) THEN ;Start Button test
; do your stuff
ENDIF
Goto Loop
what happens when you press the PS2 button a corresponding bit in either DualShock(1) or DualShock(2) will go low. So in the above code it will detect that the level is low and do your stuff. If when it finishes this and goes back up to start of the loop to get the PS2 state again if you are still pressing the button, the bit will still be low and the “do your stuff” will again be executed. The idea in some posts of waiting a longer period of time is that your fingers are fast enough to get it back off the button before it checks it again.
Now in the commented out code you posted. The difference is we remember the state of the buttons from the previous pass through the code and only execute “Your stuff” when the previous pass through the button was off and now it is on. To do this it needed to save away the state of the buttons from the previous pass, which is done:
;Store previous state
LastButton(0) = DualShock(1)
LastButton(1) = DualShock(2)
The transition is detected in the line: IF (DualShock(1).bit3 = 0) and LastButton(0).bit3 THEN ;Start Button test
Which you could have been written as: IF (DualShock(1).bit3 = 0) and (LastButton(0).bit3 = 1) THEN
and Paraphrased as: If MyButton is Down and last time the button was up then…
With the Playstation 2 controller, there are 16 buttons, each of which have one bit associated with them. There is lots of information about this up in the forums including this post: store.curiousinventor.com/guides/PS2
If you are not really interested in the exact details I simply want to process is as 247 you can do so. But to explain Bit3… If you look at your number 247 (base 10), it can also be represented as: 0xf7 (hex) and %11110111 (binary). The binary one is interesting here. If you look at the binary digits from right to left starting at 0 you will find that the 0 in the number is in bit 3 which is what we were testing for. In the previous code DualShock is an array of bytes that was read in from the PS2 controller. Note: if you look at the Curious Inventor site are array does not contain the first three bytes of the packet.
Another way to write the code would be something like:
...
if temp(1)=247 and PrevTemp(1)=255 then
gosub servo_home
endif
PrevTemp(1) = Temp(1)
It may not hit all cases, that is if you are holding another button down when you first press the button you are testing for, the previous value will not be 255, but for 99% of the cases it should work fine.