PS2 Robot Control: Establishing Communication.

For Mini Atom Bot Board/BotBoard II.
For BASIC Atom 28/BASIC Atom Pro 28.

BASIC Atom IDE v2.2.1.1/5.3.1.0
BASIC Atom Pro IDE v8.0.1.3+

04/17/2008

By James Frye.

Establishing a fast and reliable connection between a PS2 style controller and a Basic Atom 28 or BASIC Atom Pro 28 processor with a Mini Atom Bot Board or Bot Board II. (The Basic Stamp 2 processor cannot properly read the left vertical joystick.)


Too cool!
 
Step 1. Plug in the PS2 cable as shown. Be extremely careful to observe polarity on the power connector. Black is ground and yellow is +5vdc. The black wire is actually the red/shield with black heat shrink covering them. Figure 1-1 shows what each of the PS2 cable wires are.


Figure 1-1.


Figure 1-2.
 

Step 2. Copy & paste the program from the bottom of the page into the editor. There are two sections that need to be tailored to your setup. At the top of the program, in the "Bot Board Selection" section, you select either Mini-Atom Bot Board, or the Bot Board II. Remove the semicolons in front of the four lines that match your board, and add semicolons in front of the four lines that do NOT match your board. At the bottom of the program, in the "Basic Micro IDE Terminal" section you select the IDE you are using. You will need to do this twice - once under "sending carriage return", and once under "sending all the data". Remove the semicolons from the 1 line in both places to match your IDE, and add semicolons in front of the lines that do NOT match your IDE.

The program uses the Bot Board II, Basic Atom 28 and the 5.3.0.0 editor as the default. If this is your setup, no changes need to be made.

Once all changes are made, program the Atom. After the program is running, click on the Terminal1 tab (item #28 in Figures 2-1 and 2-2 below). Change the Baud Rate to 57.6kbs (item #1). Then click Connect (item #6). If all is well, you should see numbers similar to the ones shown. Note that the program automatically puts the controller in Analog mode. Refer to Table 2-1 for a description of the bytes returned by the PS2 controller. Note that items 8 and 9 are the Digital representation of button presses. Refer to Table 2-2 for a Bit representation of button presses.

 

Figure 2-1: IDE v2.2.1.1.

 

Figure 2-1: IDE v5.3.1.0 and v8.0.1.3.

 
1 Set the Baud Rate to 57.6kbs 17 on the D-Pad (000 - 255; 255 = full on)
Variable = temp(10)
2 Set to COM1 18 button (000 - 255; 255 = full on)
Variable = temp(11)
3 Set to No Parity (No Parity or 8N1) 19 O button (000 - 255; 255 = full on)
Variable = temp(12)
4 Set to NoFlow Ct 20 X button (000 - 255; 255 = full on)
Variable = temp(13)
5 Set to Echo 21 button (000 - 255; 255 = full on)
Variable = temp(14)
6 Press to Connect / Disconnect 22 L1 (000 - 255; 255 = full on)
Variable = temp(15)
7 Controller Mode (Analog is 79)
Variable = mode
23 R1 (000 - 255; 255 = full on)
Variable = temp(16)
8 On / Off for: D-Pad (on = 127), (191), (223), (239); Start (247); R3 (251); L3 (253); Select (254).
Off = 255
Variable = temp(1)
24 L2 (000 - 255; 255 = full on)
Variable = temp(17)
9 On / Off for: (on = 127); X (191); O (223); (239); R1 (247); L1 (251); R2 (253); L2 (254).
Off = 255
Variable = temp(2)
25 R2 (000 - 255; 255 = full on)
Variable = temp(18)
10 Right Joystick X axis
(000 - ~128 = left; ~128 - 255 = right)
Variable = temp(3)
26 Build
11 Right Joystick Y axis
(000 - ~128 = up; ~128 - 255 = down)
Variable = temp(4)
27 Debug
12 Left Joystick X axis
(000 - ~128 = left; ~128 - 255 = right)
Variable = temp(5)
28 Use Terminal1
13 Left Joystick Y axis
(000 - ~128 = up; ~128 - 255 = down)
Variable = temp(6)
29 Terminal2
14 on the D-Pad (000 - 255; 255 = full on)
Variable = temp(7)
30 Terminal3
15 on the D-Pad (000 - 255; 255 = full on)
Variable = temp(8)
31 Terminal4
16 on the D-Pad (000 - 255; 255 = full on)
Variable = temp(9)
   

 Table 2-1


Table 2-2 and 2-3 illustrate which bits go low when the corresponding button is pressed.
 
The arrow buttons are on what is commonly called the "D-Pad," which is the button pad on the left. L3 and R3 are the little-known Left and Right joystick buttons; trigger these by pressing down on the joysticks. R1, R2, L1, and L2 are the "shoulder buttons," that is, they are located on the controller's "shoulders."
Item 8 in Figure 3 (Active Low)
Variable = temp(1)
High Byte Low Byte
Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
Start R3 L3 Select
Table 2-2
 
Item 9 in Figure 3 (Active Low)
Variable = temp(2)
High Byte Low Byte
Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
X O R1 L1 R2 L2
Table 2-3
 
The two analog joysticks on a Sony-brand controller will not neatly return to a middle value of 128. The following value ranges are what the joysticks have been known to return to. If you need better accuracy with the analog joysticks, we recommend our Lynxmotion wireless RC-01 controller. We have also had good results with Madcatz or Pelican-brand controllers. They always returned to the middle value of 128.
  
Left X Left Y Right X Right Y
125 - 140 125 - 140 125 - 140 110 - 125

Table 2-4

 

Step 3. Code by Laurent Gay. As a demonstration of the internal vibrating motors, the following program turns on the motors with button presses. For example, the smaller motor is turned on by the D-pad button, and is either on or off. The larger motor is turned on by the D-pad button, and is variable speed proportional to the pressure applied to the button. Note that the green wire on the PS2 controller cable needs to have 7.2 vdc applied for this to work with Sony-brand controllers. It's not required for the Lynxmotion one.

 
;-----------Bot Board Selection----------
;PS2 Controller / BotBoard I
;DAT con P4
;CMD con P5
;SEL con P6
;CLK con P7

;PS2 Controller / BotBoard II
DAT con P12
CMD con P13
SEL con P14
CLK con P15
;-----------------------------

index var byte
temp var byte(19)
mode var byte
Small_Motor var byte
Large_Motor 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 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_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 1

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,$5A\8,$5A\8,$5A\8,$5A\8,$5A\8] ;CONFIG_MODE_EXIT_DS2_NATIVE
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_MODE_EXIT
high SEL
pause 1

main

;-----------PS2 Mode----------
low SEL
; asking "mode" to PS2 controller
shiftout CMD,CLK,FASTLSBPRE,[$1\8]
; reading "mode" from PS2 controller
; 73(hex) is dualshock1 (digital buttons)
; 79(hex) is dualshock2 (analog buttons)
shiftin DAT,CLK,FASTLSBPOST,[mode\8]
high SEL
;-----------------------------

pause 1

;-----------PS2 Data----------
low SEL
; asking data to PS2 controller
shiftout CMD,CLK,FASTLSBPRE,[$1\8,$42\8]
; reading data from controller
; (don't use a "for-next" loop, it's too slow to read PS2 data)
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

;-----------PS2 Vibration motors----------
Small_Motor = 1 - Temp(1).bit5 ; Numeric right arrow button (Small Motor on/off)
Large_Motor = Temp(8) ; Analog left arrow button (Large Motor speed)

low SEL
; asking data to PS2 controller (again)
; sending at the same time the vibration motors speed to perform
; (using the previously read analog buttons position ( <- : large motor, -> : small motor )
; the more you press on these buttons, the more the corresponding motor vibrates fast
; some wireless PS2 controllers react only to the large motor command and some have no motor at all.
shiftout CMD,CLK,FASTLSBPRE,[$1\8,$42\8,$0\8,Small_Motor\8,Large_Motor\8]
; we don't care about reading the data from the controller here.
; so, why not use this to read PS2 data the first time? because it's not working:
; as the PS2 controller is starting to send data just after receiving the
; "shiftout CMD,CLK,FASTLSBPRE,[$1\8,$42\8..."<------here
; and as we are sending after that some data for motors "... ,$0\8,temp(7)\8,temp(8)\8]"
; it's now too late to read all the data from the PS2 controller
; because there's already some bytes sent by it and lost (no buffer here).
high SEL
;-----------------------------

;-----------Basic Micro IDE terminal----------
; sending carriage return (CR = 13) and the PS2 mode(hex) to the PC
;serout S_OUT,i57600,[13, hex2 mode\2] ; Basic Micro IDE <= 02.2.1.1
serout S_OUT,I8N1_57600,[13, hex2 mode\2] ; Basic Micro IDE <= 05.3.0.0
;serout S_OUT,i57600,[13, hex2 mode\2] ; Basic Micro Pro IDE <= 08.0.1.7

for index = 1 to 18 ; temp(0) contains a dummy variable so we don't send it to the PC
; sending all the data to the PC
;serout S_OUT,i57600,[" ", dec3 temp(index)\3] ; Basic Micro IDE <= 02.2.1.1
serout S_OUT,I8N1_57600,[" ", dec3 temp(index)\3] ; Basic Micro IDE <= 05.3.0.0
;serout S_OUT,i57600,[" ", dec3 temp(index)\3] ; Basic Micro Pro IDE <= 08.0.1.7
next
;-----------------------------

goto main