PS2 viberation not working

I asked Laurent to look at your code to see if you may have found something here.

Hey Bane ! you found something,

using “old” PS2 DualShock 1 mode ($73) makes the Lynxmotion Pad to be able to vibrate :stuck_out_tongue: .

so, here’s some explanations about your program which was not working :

  • Temp( 7 ) and temp( 8 ) were not read, so they were filled with random values
  • using for-next loop is too slow to read PS2 flow, so we must read all data within a line
  • “large” and “small” variables were inverted in the “shiftout” line, the first one to be sent is “small” then “large”

some pauses are added
temp array is reduced to 7 bytes
temp1 and cntr variables deleted

please note :
using DS1 mode ($73), all buttons are numeric, no more analog.
so here’s the corrected code (SEL and CLK lines were swapped to see pin assignment incremental)

Thanks for your help solving this :wink:

[code]; PS2 Controller Program for BB1/BB2
; PS2 mode $73, Dualshock 1 mode, compatible with DS1 and DS2 PAD
; 16 numeric buttons and 2 X 2 axis analog joysticks
; vibration compatible with PS2 Lynxmotion controller
;
; push right arrow to enable the small vibration motor (only “on” or “off”)
;
; push left arrow to allow the large vibration motor, keep pressed
; then move the right joystick vertically to control the large motor speed

;BotBoard I
DAT con P4
CMD con P5
SEL con P6
CLK con P7

; BotBoard II
;DAT con P12
;CMD con P13
;SEL con P14
;CLK con P15

index var byte
temp var byte(7)
mode var byte

small var byte
large var byte

high CLK

low SEL
shiftout CMD,CLK,FASTLSBPRE,$1\8,$43\8,$0\8,$1\8,$0\8] ;Config Enable
high SEL
pause 1

low SEL
shiftout CMD,CLK,FASTLSBPRE,$01\8,$44\8,$00\8,$01\8,$03\8,$00\8,$00\8,$00\8,$00\8] ;Set Mode and Fix(Analog
high SEL
pause 100

low SEL
shiftout CMD,CLK,FASTLSBPRE,$01\8,$4D\8,$00\8,$00\8,$01\8,$ff\8,$ff\8,$ff\8,$ff\8] ;Vibration Enable
high SEL
pause 1

low SEL
shiftout CMD,CLK,FASTLSBPRE,$01\8,$43\8,$00\8,$00\8,$00\8,$00\8,$00\8,$00\8,$00\8] ;Config Exit
high SEL
pause 1

main

low SEL
shiftout CMD,CLK,FASTLSBPRE,$1\8]
shiftin DAT,CLK,FASTLSBPOST,[mode\8]
high SEL

low SEL
shiftout CMD,CLK,FASTLSBPRE,$1\8,$42\8]
shiftin DAT,CLK,FASTLSBPOST,[temp(0)\8,temp(1)\8,temp(2)\8]
high SEL

low SEL
shiftout CMD,CLK,FASTLSBPRE,$1\8,$42\8,$0\8,small\8,large\8]
shiftin DAT,CLK,FASTLSBPOST,[temp(3)\8,temp(4)\8,temp(5)\8,temp(6)\8]
high SEL

serout S_OUT,i57600,[13,hex2 mode\2]
for index = 1 to 6
serout S_OUT,i57600," ",dec3 temp(index)\3]
next

small = 1 - temp(1).bit5
if temp(1).bit7 then
Large = 0
else
large = 255 - temp(4)
endif

goto main[/code]

Yes! It’s about time things start working on my project :smiley: .

Are you saying that its not possable to have temp array to 19 bytes (full capasity of controller)?

If not, can i just make the modification to the code that the viberation doesn’t work on?

Thanks for helping me out on this, i spent quite a bit of time fooling around with the code (with no clue what i’m doing :imp: ), I’m still a noob at all this advanced basic coding.

Bane

I think he just reduced it to the minimum required for the purpose. You can increase it if necessary.

Bytes 8 to 19 were analog buttons positions…as Dualshock 1 mode ($73)
doesn’t handle analog buttons you just need 7 bytes.

DS1 mode uses 16 numeric buttons and 2 X 2 axis analog joysticks

using DS2 mode ($79 as before) will allow analog buttons but will not allow the vibration on the Lynxmotion PS2 Pad.

Anyway, none of the projects is using analog buttons for now.

Laureatus, have you ever had a problem with the PS2 data repeating commands? Thats what mine is doing, heres an example:

[code]…
IF temp(8) <128 then
goto walkforward
elseif temp(8) > 128
goto walkbackward
endif

[/code]
What will happen is then temp(8) meets one of those conditions it repeats the what ever is after the condition twice.

Any Ideas?

Bane

I’m not sure to understand,

if you mean your robot is performing “walkforward” and “walkbackward” at the same time…

it’s false…and true :wink:
let me explain,
it’s false in the fact that your code is correct, so it can’t perform both “goto” in the same loop.
So, looking at this small part of code we could think all is correct.

But :

Your program is looping on itself i suppose, so this code is called many times per second, this is where problems starts.

the PS2 controller is not so accurate, it goes both side of the 128 value many times per seconds even if you don’t move it :confused:
so it’s true in the fact that both “goto” are called within a second, each different one in a different “main” loop.

that’s why you should add a “Deadzone” 8)

in fact you already have programmed a “Deadzone”, because if the value is 128, none of the “goto” are called because you are using “> 128” and “< 128” (strictly < or >), but this is too small range.

try this :

IF temp(8) < 115 then goto walkforward elseif temp(8) > 141 goto walkbackward endif

now the “Deadzone” width is 27 values, this is a good range for most of the controllers

Let me make this clearer on whats happening.
I’ve tested a few things to make sure that this is happening all my TEMP variables.
Example.

If temp(13) > 228 then sound 9, [50\5000] pause 500 endif
Take this simple code for an example. If temp(13) is greater than it should play the tone once and continue with the program, which it does only instead of playing it once it playes it twice. Now i’ve added the pause there so that it doesn’t have a timing issue. But even with the pause (if i press one button quickly) that should be enough time for temp(13) to equal 0 again.

What my thoughts are on this is that the somehow the shiftin is repeating data twice for some reason. I think that if there was if a filter could possibly be applied to Temp(byte). For instance, If temp(8) > 115 then let temp(8) equal what ever number it is but only for 10 mS or something.

Heres (prehaps)another solution

[code]if temp(8) > 115 then
randomvar = 1
elseif temp(8) < 141 then
randomvar = 2
endif

if randomvar = 1 then
gosub walkforward
randomvar = 0
elseif randomvar = 2
gosub walkbackward
randomvar = 0
endif[/code]

This way regardless of how many times temp(8) value repeats its still only going to do the intended command once

BTW thanks for all your help :smiley:

Bane

Oh !

I’ve never heard this one, anyway, the problem is not in this part of the code.

so, first, you’re not using vibration with this code uh ? because temp( 8 ) and temp ( 13 ) are not used in the “vibration” code for lynxmotion PS2 pad…just to check :wink:

You should try to use a bigger pause for the test, like “pause 2000”
if it does the same, try this

If temp(13) > 228 then temp(13) = 0 sound 9, [50\5000] pause 2000 endif

if it’s still not working add a “pause 30” just after the “main” label that you loop on (i suppose), the PS2 pad can’t be asked for new data too often anyway…

if it’s still not working, please post the whole program (the shortest “non working” version please)
i will take a look…

[code];-----------Bot Board Selection----------
;PS2 Controller / BotBoard II
DAT con P12
CMD con P13
SEL con P14
CLK con P15

index var byte
temp var byte(18)
mode var byte

;PS2Init
high CLK

low SEL
shiftout CMD,CLK,FASTLSBPRE,$1\8,$43\8,$0\8,$1\8,$0\8] ;CONFIG_MODE_ENTER
high SEL
pause 10

low SEL
shiftout CMD,CLK,FASTLSBPRE,$01\8,$44\8,$00\8,$01\8,$03\8,$00\8,$00\8,$00\8,$00\8] ;SET_MODE_AND_LOCK
high SEL
pause 100

low SEL
shiftout CMD,CLK,FASTLSBPRE,$01\8,$4F\8,$00\8,$FF\8,$FF\8,$03\8,$00\8,$00\8,$00\8] ;SET_DS2_NATIVE_MODE
high SEL
pause 10

low SEL
shiftout CMD,CLK,FASTLSBPRE,$01\8,$43\8,$00\8,$00\8,$5A\8,$5A\8,$5A\8,$5A\8,$5A\8] ;CONFIG_MODE_EXIT_DS2_NATIVE
high SEL
pause 10

low SEL
shiftout CMD,CLK,FASTLSBPRE,$01\8,$43\8,$00\8,$00\8,$00\8,$00\8,$00\8,$00\8,$00\8] ;CONFIG_MODE_EXIT
high SEL
pause 10

main
pause 30

;-----------PS2 Mode----------
low SEL
shiftout CMD,CLK,FASTLSBPRE,$1\8]

shiftin DAT,CLK,FASTLSBPOST,[mode\8]
high SEL
;-----------------------------

pause 1

;-----------PS2 Data----------
low SEL

shiftout CMD,CLK,FASTLSBPRE,$1\8,$42\8]
PAUSE 1

shiftin DAT,CLK,FASTLSBPOST,[temp(0)\8,temp(1)\8,temp(2)\8,temp(3)\8,temp(4)\8,temp(5)\8,temp(6)\8,temp(7)\8,temp(8)\8, |
temp(9)\8,temp(10)\8,temp(11)\8,temp(12)\8,temp(13)\8,temp(14)\8,temp(15)\8,temp(16)\8,temp(17)\8,temp(18)\8]
high SEL
PAUSE 1

;-----------Basic Micro IDE terminal----------

serout S_OUT,i57600,[13, hex2 mode\2]

for index = 1 to 18
serout S_OUT,i57600," ", dec3 temp(index)\3]
next

;-----------Proces Code--------------------

if temp(6) < 114 then
sound 9, [50\10000]
pause 2000

elseif temp(6) > 142
sound 9, [50\5000]
pause 2000
endif

goto main
[/code]

Nope, it still repeats it. Can you try it on yours?

Bane

Here’s some mods,

the datas are not duplicated, i was able to make it beep once with the original program, when it beep twice or more, the temp(6) variable is always different but < or > to the threshold value.

i have corrected some issue in the code, the temp bytes table must be defined to temp( 19 ) rather than 18
temp( 19 ) means 19 bytes from temp( 0 ) to temp( 18 ), this way you’re not overwritting the next variable stored in memory after the temp bytes table when using shiftin.

anyway here’s the code corrected, but i’m not sure it’s the way to go :confused:
this way the WalkForward code will be called only one time if the joystick is pushed up…then to call it again you’ll have to release the joystick then push it again.

“normal” behavior should be to define a WalkForward code to move one step then return to main loop, then if the joystick is still pushed up it calls again the WalkForward code and move one step more etc…

I’m not understanding how you will define the Walkforward code the way you do.
see the next post for another way…

[code];-----------Bot Board Selection----------
;PS2 Controller / BotBoard II
DAT con P12
CMD con P13
SEL con P14
CLK con P15

index var byte
temp var byte(19) ; this byte table must be defined to 19 bytes long…from temp(0) to temp(18)
mode var byte
LastButtonAnalog var word

;PS2Init
high CLK

low SEL
shiftout CMD,CLK,FASTLSBPRE,$1\8,$43\8,$0\8,$1\8,$0\8] ;CONFIG_MODE_ENTER
high SEL
pause 10

low SEL
shiftout CMD,CLK,FASTLSBPRE,$01\8,$44\8,$00\8,$01\8,$03\8,$00\8,$00\8,$00\8,$00\8] ;SET_MODE_AND_LOCK
high SEL
pause 100

low SEL
shiftout CMD,CLK,FASTLSBPRE,$01\8,$4F\8,$00\8,$FF\8,$FF\8,$03\8,$00\8,$00\8,$00\8] ;SET_DS2_NATIVE_MODE
high SEL
pause 10

low SEL
shiftout CMD,CLK,FASTLSBPRE,$01\8,$43\8,$00\8,$00\8,$5A\8,$5A\8,$5A\8,$5A\8,$5A\8] ;CONFIG_MODE_EXIT_DS2_NATIVE
high SEL
pause 10

low SEL
shiftout CMD,CLK,FASTLSBPRE,$01\8,$43\8,$00\8,$00\8,$00\8,$00\8,$00\8,$00\8,$00\8] ;CONFIG_MODE_EXIT
high SEL
pause 10

LastButtonAnalog = 0

main

;-----------PS2 Mode----------
low SEL
shiftout CMD,CLK,FASTLSBPRE,$1\8]

shiftin DAT,CLK,FASTLSBPOST,[mode\8]
high SEL
;-----------------------------

pause 1

;-----------PS2 Data----------
low SEL

shiftout CMD,CLK,FASTLSBPRE,$1\8,$42\8]
PAUSE 1

shiftin DAT,CLK,FASTLSBPOST,[temp(0)\8,temp(1)\8,temp(2)\8,temp(3)\8,temp(4)\8,temp(5)\8,temp(6)\8,temp(7)\8,temp(8)\8, |
temp(9)\8,temp(10)\8,temp(11)\8,temp(12)\8,temp(13)\8,temp(14)\8,temp(15)\8,temp(16)\8,temp(17)\8,temp(18)\8]
high SEL
PAUSE 1

;-----------Basic Micro IDE terminal----------

serout S_OUT,i57600,[13, hex2 mode\2]

for index = 1 to 18
serout S_OUT,i57600," ", dec3 temp(index)\3]
next

;-----------Process Code--------------------

; use LastButtonAnalog.bit0 to bit15 for temp(3) to temp(18)
; so use bit3 for temp(6)
if temp(6) < 114 then
if LastButtonAnalog.bit3 then
sound 9, [50\8000]
LastButtonAnalog.bit3 = 0
; goto WalkForward
endif
elseif temp(6) > 142
if LastButtonAnalog.bit3 then
sound 9, [50\5000]
LastButtonAnalog.bit3 = 0
; goto WalkBackward
endif
else
LastButtonAnalog.bit3 = 1
endif

goto main [/code]

If i was misunderstanding and if the only problem was that you wanted only one call for a quick joystick push up, but more calls if the joystick is keep pressed up (or down)

in this one , only the pause after the main loop is increase to 100, you can increase it more if you want…

as your program will grow, you’ll have to decrease this pause, because your program will take more time to loop.

try this

[code];-----------Bot Board Selection----------
;PS2 Controller / BotBoard II
DAT con P12
CMD con P13
SEL con P14
CLK con P15

index var byte
temp var byte(19) ; this byte table must be defined to 19 bytes long…from temp(0) to temp(18)
mode var byte

;PS2Init
high CLK

low SEL
shiftout CMD,CLK,FASTLSBPRE,$1\8,$43\8,$0\8,$1\8,$0\8] ;CONFIG_MODE_ENTER
high SEL
pause 10

low SEL
shiftout CMD,CLK,FASTLSBPRE,$01\8,$44\8,$00\8,$01\8,$03\8,$00\8,$00\8,$00\8,$00\8] ;SET_MODE_AND_LOCK
high SEL
pause 100

low SEL
shiftout CMD,CLK,FASTLSBPRE,$01\8,$4F\8,$00\8,$FF\8,$FF\8,$03\8,$00\8,$00\8,$00\8] ;SET_DS2_NATIVE_MODE
high SEL
pause 10

low SEL
shiftout CMD,CLK,FASTLSBPRE,$01\8,$43\8,$00\8,$00\8,$5A\8,$5A\8,$5A\8,$5A\8,$5A\8] ;CONFIG_MODE_EXIT_DS2_NATIVE
high SEL
pause 10

low SEL
shiftout CMD,CLK,FASTLSBPRE,$01\8,$43\8,$00\8,$00\8,$00\8,$00\8,$00\8,$00\8,$00\8] ;CONFIG_MODE_EXIT
high SEL
pause 10

main

pause 100

;-----------PS2 Mode----------
low SEL
shiftout CMD,CLK,FASTLSBPRE,$1\8]

shiftin DAT,CLK,FASTLSBPOST,[mode\8]
high SEL
;-----------------------------

pause 1

;-----------PS2 Data----------
low SEL

shiftout CMD,CLK,FASTLSBPRE,$1\8,$42\8]
PAUSE 1

shiftin DAT,CLK,FASTLSBPOST,[temp(0)\8,temp(1)\8,temp(2)\8,temp(3)\8,temp(4)\8,temp(5)\8,temp(6)\8,temp(7)\8,temp(8)\8, |
temp(9)\8,temp(10)\8,temp(11)\8,temp(12)\8,temp(13)\8,temp(14)\8,temp(15)\8,temp(16)\8,temp(17)\8,temp(18)\8]
high SEL
PAUSE 1

;-----------Basic Micro IDE terminal----------

serout S_OUT,i57600,[13, hex2 mode\2]

for index = 1 to 18
serout S_OUT,i57600," ", dec3 temp(index)\3]
next

;-----------Process Code--------------------

if temp(6) < 114 then
sound 9, [50\8000]
; goto WalkForward
elseif temp(6) > 142
sound 9, [50\5000]
; goto WalkBackward
endif

goto main [/code]

YES!! :smiley: :smiley: Your a genius! Yep, now i can finish the program for my biped. Because it was repeating commands it was really screwing the walking sequence. If you don’t mind of course, explain how the “LastButtonAnalog.bit3” works. I was looking though my BasicMicro hand book and really couldn’t find how this was making a difference… :question: :question: Is the .bit3 counting something or changes when the value of the variable changes?

Bane

LastButtonAnalog is defined as word, it’s a 16 bits variable which is able to handle the 4 joysticks axis + the 12 analog buttons.

first we set all bits to 0 once before the main loop with “LastButtonAnalog = 0”
then the external if-then-endif structure is left as is :

if temp(6) < 114 then ... elseif temp(6) > 142 ... else LastButtonAnalog.bit3 = 1 endif

there’s an “else” added which will be executed every time the value is >= 114 and <=142, so in the “deadzone”, meaning the joystick is at neutral (centered)
it sets a bit to 1 in the LastButtonAnalog variable to say “hey i’m returned to neutral position”
using one different bit by axis/button allows to handle all of them without collisions

then; when an analog value is < 114 for example
it goes in this part of the code and will encounter a nested if-then-endif structure

if temp(6) < 114 then if LastButtonAnalog.bit3 then sound 9, [50\8000] LastButtonAnalog.bit3 = 0 ; goto WalkForward endif elseif ...

it allows to execute the internal code only if the LastButtonAnalog bit3 is set to 1
(“if LastButtonAnalog.bit3 then” is a shortcut for “if LastButtonAnalog.bit3 = 1 then”)
as the only way for this bit to be equal to 1 is to have been set by the “else” part of the structure, so the only way to enter here is to have been to the neutral position before…

then to avoid another call during the next main loop while the joystick is still pushed up we set the LastButtonAnalog variable bit3 to 0,
so it won’t enter this if-then-endif structure again until is goes again to the neutral position, enter the “else” code and set the bit3 to 1

it’s like a revolver trigger,
(bit3 set to 1 because the trigger is released)
push the trigger (ok to shoot because bit3 = 1) => BAaam (bit3 set to 0)
you can’t shoot more because (bit3 = 0 now)
then you need to release the trigger (bit3 set to 1)
then push it (ok to shoot because bit3 = 1) to shoot again

if you need to handle more axis use bit4 for temp(7) etc…

Thanks again. :slight_smile: I’ve applied that to the buttons as well. I have a relay that controls the main power to my bipeds servos and I had X to turn it on and O to turn it off. Now all i have to do is use the toggle command for one button :smiley:.

Bane