Beginner: Need help in connection PS2 and AL5B

Hello,

I try to connecting the PS2 controller with AL5B using coding below, I follow the instruction at:
lynxmotion.com/images/html/build091.htm

but the robot not moving like i miss something with the connection. :question:
pls anyone can help me with this. :confused:
I take some picture for the connection that i make below:
sorry for my english… :blush:

;====================================================================
;[SETUP]
;disable(0)/enable(1) the FSR Gripper 
EnableFSR con 0	

USE_SSC32 con 1

;Select Arm type
;NOTE: Enable only one arm!
;AL5A con 1
AL5B con 1
;AL5C con 1
;AL5D con 1


;--------------------------------------------------------------------
;[TABLES]
GetACos bytetable 	255,253,252,251,250,248,247,246,244,243,242,241,239,238,237,235,234,233,232,230,229,228,226,|
					225,224,223,221,220,219,217,216,215,213,212,211,209,208,207,206,204,203,201,200,199,197,196,|
					195,193,192,191,189,188,186,185,184,182,181,179,178,177,175,174,172,171,169,168,166,165,163,|
					162,160,159,157,156,154,153,151,149,148,146,145,143,141,140,138,136,135,133,131,129,128,126,|
					124,122,120,118,116,115,113,111,109,106,104,102,100,98,96,93,91,89,86,83,81,78,75,73,70,66,63,|
					60,56,52,48,44,38,33,26,15,0
;--------------------------------------------------------------------
;[CONSTANTS]
c2DEC		con 100
c4DEC		con 10000

TRUE 		con 1
FALSE 		con 0

BUTTON_DOWN con 0
BUTTON_UP 	con 1

;calibrate steps per degree. 
stepsperdegree1 con 1666 ; steps per degree in 10ths...

;=========================================================================
;=========================================================================
;=========================================================================
#ifdef USE_SSC32
;[BB2 PIN NUMBERS]
GripperFSRPin	con P16	;Force Sensing Resistor for the Gripper

;PS2 Controller
PS2DAT 		con P12		;PS2 Controller DAT (Brown)
PS2CMD 		con P13		;PS2 controller CMD (Orange)
PS2SEL 		con P14		;PS2 Controller SEL (Blue)
PS2CLK 		con P15		;PS2 Controller CLK (White)
PadMode 	con $79

; SSC32
cSSC_OUT    con P11     ;Output pin for (SSC32 RX) on BotBoard (Yellow)
cSSC_IN     con P10     ;Input pin for (SSC32 TX) on BotBoard (Blue)
cSSC_BAUD   con i115200	;SSC32 BAUD rate 38400 115200

; [SSC32 pins]
BasePin 	con 0
ShoulderPin con 1
ElbowPin 	con 2
WristPin 	con 3
GripperPin 	con 4
WristRotatepin con 5


;=========================================================================
;=========================================================================
;=========================================================================
; [BAP28 only mode]
#else
;--------------------------------------------------------------------
;[PS2 Controller]
PS2DAT 		con P12		;PS2 Controller DAT (Brown)
PS2CMD 		con P13		;PS2 controller CMD (Orange)
PS2SEL 		con P14		;PS2 Controller SEL (Blue)
PS2CLK 		con P15		;PS2 Controller CLK (White)
PadMode 	con $79
;--------------------------------------------------------------------
;[PIN NUMBERS]
BasePin 		con P0	;Base Connection
ShoulderPin 	con P1	;Shoulder Connection
ElbowPin  		con P2	;Elbow Connection
WristPin		con P3	;Wrist Connection
GripperPin		con P4	;Gripper Connection
WristRotatePin	con P5	;Wrist Rotation Connection (Optional)


GripperFSRPin	con P16	;Force Sensing Resistor for the Gripper

;--------------------------------------------------------------------
;[SERVO OFFSETS]
Base_Offset 		con 0
Shoulder_Offset 	con 0
Elbow_Offset 		con 0
Wrist_Offset 		con 0
Gripper_Offset 		con 0
WristRotate_Offset 	con 0
#endif
;=========================================================================
;=========================================================================
;=========================================================================

;--------------------------------------------------------------------
;[ANALOG SWITCHING POINT]
GripperHoldPressure	con 800 ;+/-1000 = neutral
;--------------------------------------------------------------------
;[MIN/MAX ANGLES] Degrees * 10
Base_MIN		con -900	;Mechanical limits of the Base
Base_MAX		con 900

Shoulder_MIN	con -780	;Mechanical limits of the Shoulder
Shoulder_MAX	con 900

Elbow_MIN		con -710	;Mechanical limits of the Elbow
Elbow_MAX		con 450

Wrist_MIN		con -900	;Mechanical limits of the Wrist
Wrist_MAX		con 900

Gripper_MIN		con -720	;Mechanical limits of the Gripper
Gripper_MAX		con 680

WristRotate_MIN	con -760	;Mechanical limits of the WristRotate
WristRotate_MAX	con 830
;--------------------------------------------------------------------
;[BODY DIMENSIONS]
BaseLength		con 69	;Length of the Base [mm]

#IFDEF AL5A
  HumerusLength		con 94	;Length of the Humerus [mm]
  UlnaLength		con 108	;Length of the Ulna [mm]
  InitWristPosX 	con 20	;Init position X
  InitWristPosY 	con 145 ;Init position Y
  InitGripperAngle1 con -400;Init Angle gripper  
  
#ELSEIFDEF AL5B
  HumerusLength		con 119	;Length of the Humerus [mm]
  UlnaLength		con 127	;Length of the Ulna [mm]
  InitWristPosX 	con 30	;Init position X
  InitWristPosY 	con 130 ;Init position Y
  InitGripperAngle1 con -450;Init Angle gripper 
   
#ELSEIFDEF AL5C
  HumerusLength		con 156	;Length of the Humerus [mm]
  UlnaLength		con 154	;Length of the Ulna [mm]
  InitWristPosX 	con 35	;Init position X
  InitWristPosY 	con 145 ;Init position Y
  InitGripperAngle1 con -450;Init Angle gripper
  
#ELSEIFDEF AL5D
  HumerusLength		con 147	;Length of the Humerus [mm]
  UlnaLength		con 187	;Length of the Ulna [mm] 
  InitWristPosX 	con 55	;Init position X
  InitWristPosY 	con 120 ;Init position Y
  InitGripperAngle1 con -550;Init Angle gripper
#ENDIF
;--------------------------------------------------------------------
;[REMOTE]
DeadZone		con 4	;The deadzone for the analog input from the remote
;====================================================================
;[ANGLES]
BaseAngle1 			var sword	;Actual Angle of the Base servo
ShoulderAngle1 		var sword	;Actual Angle of the Shoulder servo
ElbowAngle1  		var sword	;Actual Angle of the Elbow servo
WristAngle1			var sword	;Actual Angle of the Wrist servo
Gripper1			var sword	;Actual Angle of the Gripper servo
WristRotateAngle1	var sword	;Actual Angle of the Wrist Rotation servo
;--------------------------------------------------------------------
;[POSITIONS]
WristPosX			var slong	;Position of the Gripper used for input
WristPosY			var slong
GlobalGripperAngle1	var sword	;Angle of the Gripper used for input
;--------------------------------------------------------------------
;[Gripper]
GripperPressure		var word	;Analog value from the FSR input
;--------------------------------------------------------------------

;--------------------------------------------------------------------
;[VARIABLES]

;GetArcCos
Cos4			var sword		;Input Cosinus of the given Angle, decimals = 4
AngleRad4		var sword		;Output Angle in radians, decimals = 4

;GetArcTan2
ArcTanX 		var sword		;Input X
ArcTanY 		var sword		;Input Y
ArcTan4			var slong		;Output ARCTAN2(X/Y)

;Arm Inverse Kinematics
IKWristPosX	    	var slong	;Input position of the Wrist X
IKWristPosY	    	var slong	;Input position of the Wrist Y
IKGripperAngle1		var slong	;Input Angle of the Gripper referring to the base
IKSW2				var long	;Length between Shoulder and Wrist
IKA14		    	var long	;Angle of the line S>W with respect to the ground in radians
IKA24		    	var long	;Angle of the line S>W with respect to the humerus in radians
Temp1				var long
Temp2				var long
IKSolutionWarning 	var bit		;Output true if the solution is NEARLY possible
IKSolutionError		var bit		;Output true if the solution is NOT possible
IKSolutionErrorBeep	var	bit		;Have we beeped yet when we have an error?
IKWristAngle1   	var sword	;Output Angle of Wrist in degrees
IKElbowAngle1   	var sword	;Output Angle of Elbow in degrees
IKShoulderAngle1   	var sword	;Output Angle of Shoulder in degrees
IKBaseAngle1		var sword	;Output Angle of Base in degrees
;--------------------------------------------------------------------
;[Ps2 Controller]
DualShock 	var Byte(7)
LastButton 	var Byte(2)
DS2Mode 	var Byte
PS2Index	var byte

;[Speed limitation] ; variables to limit max angle step to limit speed
TargetWristAngle1	var sword
MaxStepWristAngle	con 40
TargetGripper1		var sword
MaxStepGripper		con 40
;--------------------------------------------------------------------
;[GLOBAL]
ControlMode 	var bit			;Switch Between Rover and Arm
RoverOn			var bit			;Switch to turn on the Rover
Prev_RoverOn	var bit			;Previous loop state
ArmOn	 		var bit			;Switch to turn on the Arm
Prev_ArmOn		var bit			;Previous loop state 

;[TIMING]
lCurrentTime		var long	
lTimerStart			var long	;Start time of the calculation cycles
lTimerEnd			var long 	;End time of the calculation cycles

;====================================================================

;====================================================================
;[INIT]

;Initialize servo positions
gosub InitTimer		; initialize a timer for the program
enable
Gosub InitArm

;PS2 controller
high PS2CLK
gosub Ps2Init
LastButton(0) = 255
LastButton(1) = 255

ArmOn = FALSE
IKSolutionErrorBeep = TRUE ; kje setup to beep when the arm has a problem
;====================================================================
;[MAIN]	
main:
  GOSUB GetCurrentTime], lTimerStart 

#IF EnableFSR=1
	;Read analog input
	adin GripperFSRPin, GripperPressure
#ELSE
	GripperPressure=1000
#ENDIF

  ;Read remote input
  GOSUB Ps2Input
  
 

;[ARM CALCULATIONS]
  

  ;Inverse Kinematic calculations
  GOSUB ArmIK [WristPosX, WristPosY, GlobalGripperAngle1]  
  ShoulderAngle1 = -IKShoulderAngle1+900
  ElbowAngle1 = IKElbowAngle1+900
  WristAngle1 = -IKWristAngle1

  GOSUB CheckLimits

  GOSUB WaitForPrevMove ;Wait for servos to finish the previous move
  
  IF ArmOn THEN  
    IF ArmOn AND Prev_ArmOn=0 THEN
      Sound P9,[60\4000,80\4500,100\5000]
	  gosub InitArm
	  
	  GlobalGripperAngle1=0
  	ENDIF

  	IF IKSolutionError = FALSE then						; KJE - Added test to not do movement if there is an error
  	  IKSolutionErrorBeep = FALSE						; reset if we have output any warning beeps 
	  GOSUB Movement-BaseAngle1, -ShoulderAngle1, -ElbowAngle1, -WristAngle1, -Gripper1, -WristRotateAngle1, 100] ; kje - convert to integers
    
    ELSEIF IKSolutionErrorBeep = FALSE
      IKSolutionErrorBeep = TRUE						; KJE added beep if the arm tries to move to an error location.
      Sound P9,[60\4000,60\4000]
    ENDIF
    	
  ELSE
  
    ;Turn the bot off
    IF Prev_ArmOn THEN
    
	  gosub InitArm    
      Sound P9,[100\5000,80\4500,60\4000]
      
    ENDIF
  ENDIF	
  
  ;Store previous ArmOn State
  IF ArmOn THEN
    Prev_ArmOn = 1
  ELSE
    Prev_ArmOn = 0
  ENDIF
  
goto main
;====================================================================
;[INITARM] Initialization for the AL5x Arm
InitArm:

  ;Gripper Positions
  WristPosX = InitWristPosX		;Start positions of the Gripper
  WristPosY = InitWristPosY
  GlobalGripperAngle1 = InitGripperAngle1
  
  ;Inverse Kinematic calculations
  GOSUB ArmIK [WristPosX, WristPosY, GlobalGripperAngle1]  
  ShoulderAngle1 = -IKShoulderAngle1+900
  ElbowAngle1 = IKElbowAngle1+900
  WristAngle1 = -IKWristAngle1

  GOSUB CheckLimits
  
  gosub movement [0,  -ShoulderAngle1,  -ElbowAngle1,  -WristAngle1,  0,  0,  600]    
  
  pause 1000

return
;--------------------------------------------------------------------
;[PS2INIT] Initialization for the PS2 remote
Ps2Init:
  low PS2SEL
  shiftout PS2CMD,PS2CLK,FASTLSBPRE,$1\8]
  shiftin PS2DAT,PS2CLK,FASTLSBPOST,[DS2Mode\8]
  high PS2SEL
  pause 1
  
  if DS2Mode <> PadMode THEN
	low PS2SEL
	shiftout PS2CMD,PS2CLK,FASTLSBPRE,$1\8,$43\8,$0\8,$1\8,$0\8] ;CONFIG_MODE_ENTER
	high PS2SEL
	pause 1

	low PS2SEL
	shiftout PS2CMD,PS2CLK,FASTLSBPRE,$01\8,$44\8,$00\8,$01\8,$03\8,$00\8,$00\8,$00\8,$00\8] ;SET_MODE_AND_LOCK
	high PS2SEL
	pause 1

	low PS2SEL
	shiftout PS2CMD,PS2CLK,FASTLSBPRE,$01\8,$4F\8,$00\8,$FF\8,$FF\8,$03\8,$00\8,$00\8,$00\8] ;SET_DS2_NATIVE_MODE
	high PS2SEL
	pause 1

	low PS2SEL
	shiftout PS2CMD,PS2CLK,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 PS2SEL
	pause 1

	low PS2SEL
	shiftout PS2CMD,PS2CLK,FASTLSBPRE,$01\8,$43\8,$00\8,$00\8,$00\8,$00\8,$00\8,$00\8,$00\8] ;CONFIG_MODE_EXIT
	high PS2SEL
	pause 100
		
	sound P9,[100\4000, 100\4500, 100\5000]
	
	goto Ps2Init ;Check if the remote is initialized correctly
  ENDIF
return
;--------------------------------------------------------------------
;[PS2Input] reads the input data from the Wiiremote and processes the
;data to the parameters.
Ps2Input:

  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	
  
  
  IF (DualShock(1).bit3 = 0) and LastButton(0).bit3 THEN	;Start Button test
 	 IF(ArmOn) THEN
	    ;Turn off
	    ArmOn = False

	    ;Reset Gripper Positions
	    WristPosX=InitWristPosX		;Reset IK postitions of the Gripper
	    WristPosY=InitWristPosY
	  
	    BaseAngle1=0		;Reset servo angles.
	    GlobalGripperAngle1=-550
	    TargetGripper1=0	    	  
	    Gripper1=0
		TargetWristAngle1=0
	    WristRotateAngle1=0
	ELSE
	    ;Turn on
	    ArmOn = True	
	  
	    ;Put gripper horizontal
	    GlobalGripperAngle1=0
	ENDIF
  ENDIF	

  IF ArmOn THEN

;	  IF (DualShock(1).bit4 = 0) and LastButton(0).bit4 THEN	;D-Up Button test
;	  ENDIF
		
;	  IF (DualShock(1).bit6 = 0) and LastButton(0).bit6 THEN	;D-Down Button test
;	  ENDIF
	
;	  IF (DualShock(1).bit7 = 0) and LastButton(0).bit7 THEN	;D-Left Button test
;	  ENDIF
	
;	  IF (DualShock(1).bit5 = 0) and LastButton(0).bit5 THEN	;D-Right Button test
;	  ENDIF

;	  IF (DualShock(2).bit5 = 0) and LastButton(1).bit5 THEN	;Circle Button test
;	  ENDIF	
	
;	  IF (DualShock(2).bit7 = 0) and LastButton(1).bit7 THEN	;Square Button test
;	  ENDIF	
	
 	IF (DualShock(2).bit4 = 0) and LastButton(1).bit4 THEN	;Triangle Button test
	    TargetWristAngle1 = 0 ;Put the wrist rotate servo to the middle position
	ENDIF	

	IF (DualShock(2).bit6 = 0) and LastButton(1).bit6 THEN	;Cross Button test
	    IF (Gripper1 <> Gripper_MAX) THEN
	      TargetGripper1 = Gripper_MAX ;Fully open Gripper
#IF EnableFSR=1	 	      
	    ELSE
	      TargetGripper1 = Gripper_MIN
#ENDIF	  	      
	    ENDIF
	ENDIF	
			
	IF (DualShock(2).bit2 = 0) AND (GripperPressure>GripperHoldPressure) THEN	;L1 Button test
	    Gripper1 = (Gripper1-80) min Gripper_MIN ;Gripper Close
	ENDIF
	
	IF (DualShock(2).bit0 = 0)THEN ;L2 Button test
	    TargetGripper1 = (TargetGripper1+40) max Gripper_MAX ;Gripper Open
	ENDIF		
	
	IF (DualShock(2).bit3 = 0) THEN	;R1 Button test
	    TargetWristAngle1 = (TargetWristAngle1-40) min WristRotate_MIN ;Wrist Rotate CW
 	ENDIF

  	IF (DualShock(2).bit1 = 0) THEN ;R2 Button test
	    TargetWristAngle1 = (TargetWristAngle1+40) max WristRotate_MAX ;Wrist Rotate CCW
	ENDIF	

	IF ABS(Dualshock(5) - 128) > DeadZone THEN ;Left Stick L/R
	    IF IKSolutionWarning THEN ;Allow only movement to the base
	      WristPosX = WristPosX -((Dualshock(5) - 128)/18) MIN 0 ;X Position
	    ELSE  
	      WristPosX = WristPosX -(Dualshock(5) - 128)/18 ;X Position
	    ENDIF
	ENDIF
  
	IF ABS(Dualshock(6) - 128) > DeadZone THEN ;Left Stick U/D
	    IF IKSolutionWarning THEN
	      IF WristPosY > BaseLength THEN ;Allow only downward movement
	        WristPosY = WristPosY -((Dualshock(6) - 128)/18) MIN 0	        
	      ELSE ;Allow only upward movement
	        WristPosY = WristPosY -((Dualshock(6) - 128)/18) MAX 0      
	      ENDIF
	    ELSE
	      WristPosY = WristPosY -(Dualshock(6) - 128)/18 ;Y Position
	    ENDIF
	ENDIF
  
	IF ABS(Dualshock(3) - 128) > DeadZone THEN ;Right Stick L/R
        BaseAngle1 = BaseAngle1 -(Dualshock(3) - 128)/4 ;Base Rotation
	ENDIF
	  
	IF ABS(Dualshock(4) - 128) > DeadZone THEN ;Right Stick U/D
	    GlobalGripperAngle1 = GlobalGripperAngle1-(Dualshock(4) - 128)/2 ;Gripper Angle
	ENDIF	  
	  	
	  ;Limit wristrotate max speed  
	  IF (ABS(WristRotateAngle1-TargetWristAngle1) > MaxStepWristAngle) THEN
	    IF ((WristRotateAngle1-TargetWristAngle1) >= 0) THEN
	      WristRotateAngle1 = WristRotateAngle1 - MaxStepWristAngle
	  	ELSE
	      WristRotateAngle1 = WristRotateAngle1 + MaxStepWristAngle	  	
	  	ENDIF
	  ELSE
	  	WristRotateAngle1 = TargetWristAngle1
	  ENDIF
	  
	  ;Limit gripper max speed
	  IF (ABS(Gripper1-TargetGripper1) > MaxStepGripper) THEN
	    IF ((Gripper1-TargetGripper1) >= 0) THEN
	      IF (GripperPressure>GripperHoldPressure) THEN
	        Gripper1 = Gripper1 - MaxStepGripper
	      ENDIF
	  	ELSE
	      Gripper1 = Gripper1 + MaxStepGripper	  	
	  	ENDIF
	  ELSE
	  	Gripper1 = TargetGripper1
	  ENDIF
	  
	  
    ENDIF
  
  LastButton(0) = DualShock(1)
  LastButton(1) = DualShock(2)
return
;--------------------------------------------------------------------
;[GETARCCOS] Get the sinus and cosinus from the angle +/- multiple circles
;Cos4    	- Input Cosinus
;AngleRad4 	- Output Angle in AngleRad4
GetArcCos[Cos4]

  Cos4 = (Cos4 max c4DEC) min -c4DEC
  IF Cos4>=0 THEN
    AngleRad4 = GetACos(Cos4/78+1) ;78=table resolution (1/127)
    AngleRad4 = AngleRad4*62 ;62=acos resolution (pi/2/255)
  ELSE
    AngleRad4 = GetACos(-Cos4/78+1)  
    AngleRad4 = 31416-AngleRad4*62 ;62=acos resolution (pi/2/255)
  ENDIF

return AngleRad4
;--------------------------------------------------------------------
;[ARCTAN2] Gets the Inverse Tangus from X/Y with the where Y can be zero or negative
;ArcTanX 		- Input X
;ArcTanY 		- Input Y
;ArcTan4  		- Output ARCTAN2(X/Y)
GetArcTan2 [ArcTanX, ArcTanY]
	IF(ArcTanX = 0) THEN	; X=0 -> 0 or PI
		IF(ArcTanY >= 0) THEN
			ArcTan4 = 0
		ELSE
			ArcTan4 = 31415
		ENDIF
	ELSE	
		IF(ArcTanY = 0) THEN	; Y=0 -> +/- Pi/2
			IF(ArcTanX > 0) THEN
				ArcTan4 = 15707
			ELSE
				ArcTan4 = -15707
			ENDIF
		ELSE
			IF(ArcTanY > 0) THEN	;ARCTAN(X/Y)
				ArcTan4 = TOINT(FATAN(TOFLOAT(ArcTanX) / TOFLOAT(ArcTanY))*10000.0)
			ELSE	
				IF(ArcTanX > 0) THEN	;ARCTAN(X/Y) + PI	
					ArcTan4 = TOINT(FATAN(TOFLOAT(ArcTanX) / TOFLOAT(ArcTanY))*10000.0) + 31415
				ELSE					;ARCTAN(X/Y) - PI	
					ArcTan4 = TOINT(FATAN(TOFLOAT(ArcTanX) / TOFLOAT(ArcTanY))*10000.0) - 31415
				ENDIF
			ENDIF
		ENDIF
	ENDIF
return ArcTan4
;-------------------------------------------------------------------- 
;[ARM INVERSE KINEMATICS] Calculates the angles of the Humerus and Ulna for the given position of the Gripper
;IKGripperPosX		- Input position of the Gripper X
;IKGripperPosY		- Input position of the Gripper Y
;IKGripperPosZ		- Input Position of the Gripper Z
;IKGripperAngle1	- Input Angle of the Gripper referring to the base
;IKSolutionWarning 	- Output true IF the solution is NEARLY possible
;IKSolutionError	- Output true IF the solution is NOT possible
;IKUlnaAngle1  		- Output Angle of Ulna in degrees
;IKHumerusAngle1   	- Output Angle of Humerus in degrees
;IKBaseAngle1		- Output Angle of Base in degrees
ArmIK [IKWristPosX, IKWristPosY, IKGripperAngle1]
	
	;IKSW - Length between Shoulder and wrist
	IKSW2 = SQR((((IKWristPosY-BaseLength)*(IKWristPosY-BaseLength))+(IKWristPosX*IKWristPosX))*(c4DEC/4))	; KJE - value 1/2 what it should be now	
	
	;IKA1 - Angle between SW line and the ground in rad
	GOSUB GetArcTan2 (IKWristPosY-BaseLength), IKWristPosX], IKA14
	
	;IKA2 - Angle of the line S>W with respect to the humerus in radians
	Temp1 = (((HumerusLength*HumerusLength) - (UlnaLength*UlnaLength))*(c4DEC/4) + (IKSW2*IKSW2))			; KJE - Value is 1/4 of what it should be.
	Temp2 = ((2*HumerusLength)*c2DEC * IKSW2)																; KJE - value is 1/2
	GOSUB GetArcCos (Temp1 / (Temp2/c4DEC)) *2 ], IKA24													; KJE - corrected for 1/4value / 1/2 value

	;Elbow Angle
	Temp1 = (((HumerusLength*HumerusLength) + (UlnaLength*UlnaLength))*(c4DEC/4) - (IKSW2*IKSW2))			; KJE 1/4
	Temp2 = (2*HumerusLength*Ulnalength)
	GOSUB GetArcCos (Temp1 / Temp2) * 4]																	; kje fixed for 1/4
	IKElbowAngle1 = -(1800-AngleRad4*180/3141)

	;Shoulder Angle
	IKShoulderAngle1 = (IKA14 + IKA24) * 180 / 3141

	;Wrist Angle
	IKWristAngle1 = IKGripperAngle1-IKElbowAngle1-IKShoulderAngle1
		
	;Set the Solution quality	
  IKSolutionWarning = ((IKSW2*2) > ((UlnaLength+HumerusLength-40)*c2DEC)) ; kje fixed for 1/2 
  IKSolutionError = ((IKSW2*2) > ((UlnaLength+HumerusLength)*c2DEC)) ; kje fixed for 1/2
	
return
;--------------------------------------------------------------------
;[CHECK ANGLES] Checks the mechanical limits of the servos
CheckLimits:
  BaseAngle1  = 	(BaseAngle1  min Base_MIN) max Base_MAX
  ShoulderAngle1 = 	(ShoulderAngle1 min Shoulder_MIN) max Shoulder_MAX
  ElbowAngle1 = 	(ElbowAngle1 min Elbow_MIN)  max Elbow_MAX
  WristAngle1  = 	(WristAngle1  min Wrist_MIN) max Wrist_MAX
  Gripper1 = 		(Gripper1 min Gripper_MIN) max Gripper_MAX
  WristRotateAngle1 =(WristRotateAngle1 min WristRotate_MIN)  max WristRotate_MAX
return


;=====================================================================
; Timer support...
;====================================================================
lTimerCnt			var long	

;--------------------------------------------------------------------
;[TIMER INTERRUPT INIT]
#ifdef BASICATOMPRO28
TIMERINT	con	TIMERAINT
ONASMINTERRUPT TIMERAINT, HANDLE_TIMERA_ASM 

;--------------------------------------------------------------------
;[InitTimer] - Initializes the timer for the program
InitTimer:
;Timer
; Timer A init, used for timing of messages and some times for timing code...
  TIMERINT	con	TIMERAINT

  WTIMERTICSPERMSMUL con 64	; BAP28 is 16mhz need a multiplyer and divider to make the conversion with /8192
  WTIMERTICSPERMSDIV con 125  ; 
  TMA = 0	; clock / 8192					; Low resolution clock - used for timeouts...
  ENABLE TIMERINT
return

;==============================================================================
;[Handle_Timer_asm] - Handle timer A overflow in assembly language.  Currently only
;used for timings for debuging the speed of the code
;Now used to time how long since we received a message from the remote.
;this is important when we are in the NEW message mode, as we could be hung
;out with the robot walking and no new commands coming in.
;==============================================================================
BEGINASMSUB 
HANDLE_TIMERA_ASM 
	push.l 	er1                  ; first save away ER1 as we will mess with it. 
	bclr 	#6,@IRR1:8               ; clear the cooresponding bit in the interrupt pending mask 
	mov.l 	@LTIMERCNT:16,er1      ; Add 256 to our counter 
	add.l	#256,er1 
	mov.l 	er1, @LTIMERCNT:16 
	pop.l 	er1 
	rte 
ENDASMSUB 

return		; Put a basic statement before...
;==============================================================================
;[GetCurrentTime] - Gets the Timer value from our overflow counter as well as the TCA counter.  It
;                makes sure of consistancy. That is it is very posible that 
;                after we grabed the timers value it overflows, before we grab the other part
;                so we check to make sure it is correct and if necesary regrab things.
;==============================================================================
GetCurrentTime:
  lCurrentTime = lTimerCnt + TCA
	
  ; handle wrap
  if lTimerCnt <> (lCurrentTime & 0xffffff00) then
	lCurrentTime = lTimerCnt + TCA
  endif

return lCurrentTime

#else ; Arc32 or Bap40
TIMERINT	con	TIMERB1INT
ONASMINTERRUPT TIMERB1INT, HANDLE_TIMERB1_ASM 

;--------------------------------------------------------------------
;[InitServoDriver] - Initializes the servo driver including the main timer used in the phoenix code
InitTimer:
;Timer
; Timer A init, used for timing of messages and some times for timing code...
  TIMERINT	con	TIMERB1INT
  WTIMERTICSPERMSMUL con 256	; Arc32 is 20mhz need a multiplyer and divider to make the conversion with /8192
  WTIMERTICSPERMSDIV con 625  ; 
  TMB1 = 0	; clock / 8192					; Low resolution clock - used for timeouts...
  ENABLE TIMERINT
return

;==============================================================================
;[Handle_Timer_asm] - Handle timer A overflow in assembly language.  Currently only
;used for timings for debuging the speed of the code
;Now used to time how long since we received a message from the remote.
;this is important when we are in the NEW message mode, as we could be hung
;out with the robot walking and no new commands coming in.
;==============================================================================
   BEGINASMSUB 
HANDLE_TIMERB1_ASM 
	push.l 	er1                  ; first save away ER1 as we will mess with it. 
	bclr 	#5,@IRR2:8           ; clear the cooresponding bit in the interrupt pending mask 
	mov.l 	@LTIMERCNT:16,er1    ; Add 256 to our counter 
	add.l	#256,er1 
	mov.l 	er1, @LTIMERCNT:16 
	pop.l 	er1 
	rte 
	ENDASMSUB 

BEGINASMSUB 

return		; Put a basic statement before...
;==============================================================================
;[GetCurrentTime] - Gets the Timer value from our overflow counter as well as the TCA counter.  It
;                makes sure of consistancy. That is it is very posible that 
;                after we grabed the timers value it overflows, before we grab the other part
;                so we check to make sure it is correct and if necesary regrab things.
;==============================================================================
GetCurrentTime:
  lCurrentTime = lTimerCnt + TCB1
	
  ; handle wrap
  if lTimerCnt <> (lCurrentTime & 0xffffff00) then
	lCurrentTime = lTimerCnt + TCB1
  endif

return lCurrentTime


#endif

;-------------------------------------------------------------------------------------
;[ConvertTimeMS]
_ttconv	var	long
ConvertTimeMS[_ttconv]:
	return (_ttconv * WTIMERTICSPERMSMUL)/WTIMERTICSPERMSDIV 


#ifdef USE_SSC32
;--------------------------------------------------------------------
;[MOVEMENT] Does a servo groupmove to ensure that all servos reach
;the destination at the same time. 
BasePosition1			var slong
ShoulderPosition1 	var slong
ElbowPosition1 		var slong
WristPosition1		var slong
GripperPosition1		var slong
WristRotatePosition1	var slong
MaxSpeed 				var slong 
PrevSpeed				var slong
Movement [BasePosition1,ShoulderPosition1,ElbowPosition1,WristPosition1,GripperPosition1,WristRotatePosition1,MaxSpeed] 
    ; Warning... using simple conversion from HSERVO type calc to usec...
	disable TIMERINT	; disable interrupt duing serout as to keep from corrupting data.
    serout cSSC_OUT, cSSC_BAUD, "#", dec BasePin, "P", sdec 1500 + (BasePosition1*stepsperdegree1)/(100 * 16), |
           "#", dec ShoulderPin, "P", sdec 1500 + (ShoulderPosition1*stepsperdegree1)/1600, | 
           "#", dec ElbowPin, "P", sdec 1500 + (ElbowPosition1*stepsperdegree1)/1600, | 
           "#", dec WristPin, "P", sdec 1500 + (WristPosition1*stepsperdegree1)/1600, | 
           "#", dec GripperPin, "P", sdec 1500 + (GripperPosition1*stepsperdegree1)/1600, | 
           "#", dec WristRotatepin, "P", sdec 1500 + (WristRotatePosition1*stepsperdegree1)/1600, |
           "T", dec MaxSpeed, 13]
	enable TIMERINT		; allow the interrupt again

    PrevSpeed = MaxSpeed       
	return

CycleTime	var long
WaitForPrevMove:
	do 
      GOSUB GetCurrentTime], lTimerEnd   
      GOSUB ConvertTimeMS[lTimerEnd-lTimerStart], CycleTime
    while CycleTime < PrevSpeed  
	return





#else
;--------------------------------------------------------------------
;[MOVEMENT] Does a servo groupmove to ensure that all servos reach
;the destination at the same time. 
_mindex 				var byte
BasePosition1			var slong
ShoulderPosition1 	var slong
ElbowPosition1 		var slong
WristPosition1		var slong
GripperPosition1		var slong
WristRotatePosition1	var slong
MaxSpeed 				var slong 
_mPrev_BasePos1			var slong
_mPrev_ShoulderPos1 	var slong
_mPrev_ElbowPos1  		var slong
_mPrev_WristPos1		var slong
_mPrev_GripperPos1		var slong
_mPrev_WristRotatePos1	var slong
_mBaseSpeed				var slong
_mShoulderSpeed 		var slong
_mElbowSpeed  			var slong
_mWristSpeed			var slong
_mGripperSpeed			var slong
_mWristRotateSpeed		var slong
_mMaxSpeed1				var slong
_mlongestmove1 			var slong 
Movement [BasePosition1,ShoulderPosition1,ElbowPosition1,WristPosition1,GripperPosition1,WristRotatePosition1,MaxSpeed] 

  if(MaxSpeed<>0)then 
	;Get the longest move
    gosub getlongest[BasePosition1	 -_mPrev_BasePos1, | 
					 ShoulderPosition1 -_mPrev_ShoulderPos1, | 
					 ElbowPosition1	 -_mPrev_ElbowPos1, | 
					 WristPosition1	 -_mPrev_WristPos1, | 
					 GripperPosition1	 -_mPrev_GripperPos1, | 
					 WristRotatePosition1 -_mPrev_WristRotatePos1], _mlongestmove1 

  ; kje - converted to return maxspeed *10 - 
  _mMaxspeed1 = ((_mlongestmove1*stepsperdegree1)/(MaxSpeed/2)) 

  ;Calculate speed for each servo
  gosub getspeed[BasePosition1,		_mPrev_BasePos1,	_mlongestmove1,		_mMaxSpeed1],	_mBaseSpeed
  gosub getspeed[ShoulderPosition1,	_mPrev_ShoulderPos1,_mlongestmove1,		_mMaxSpeed1],	_mShoulderSpeed 
  gosub getspeed[ElbowPosition1,	_mPrev_ElbowPos1,	_mlongestmove1,		_mMaxSpeed1],	_mElbowSpeed 
  gosub getspeed[WristPosition1,	_mPrev_WristPos1,	_mlongestmove1,		_mMaxSpeed1],	_mWristSpeed
  gosub getspeed[GripperPosition1,	_mPrev_GripperPos1,	_mlongestmove1,		_mMaxSpeed1],	_mGripperSpeed
  gosub getspeed[WristRotatePosition1,	_mPrev_WristRotatePos1,_mlongestmove1,_mMaxSpeed1],	_mWristRotateSpeed      

  else 
	_mBaseSpeed = 0
	_mShoulderSpeed = 0
	_mElbowSpeed = 0
	_mWristSpeed = 0
	_mGripperSpeed = 0
	_mWristRotateSpeed = 0
  endif 
 
   ;Drive servos
   
   hservo [BasePin\		(BasePosition1*stepsperdegree1)/100 + Base_Offset\_mBaseSpeed, | 
           ShoulderPin\	(ShoulderPosition1*stepsperdegree1)/100 + Shoulder_Offset\_mShoulderSpeed, | 
           ElbowPin\	(ElbowPosition1*stepsperdegree1)/100 + Elbow_Offset\_mElbowSpeed, | 
           WristPin\	(WristPosition1*stepsperdegree1)/100 + Wrist_Offset\_mWristSpeed, | 
           GripperPin\	(GripperPosition1*stepsperdegree1)/100 + Gripper_Offset\_mGripperSpeed, | 
           WristRotatepin\(WristRotatePosition1*stepsperdegree1)/100 + WristRotate_Offset\_mWristRotateSpeed] 
    serout s_out, i115200,[sdec shoulderposition1, " ", sdec ((shoulderposition1 * stepsperdegree1)/100), |
                          " ", sdec (((shoulderposition1 * stepsperdegree1)/100)+ shoulder_offset)," ", sdec _mshoulderspeed, 13];|
                         ; "  elbow - ", sdec elbowposition1, " ", sdec ((elbowposition1 * stepsperdegree1)/100), |
                         ; " ", sdec (((elbowposition1 * stepsperdegree1)/100)+ elbow_offset), 13]

return
;--------------------------------------------------------------------
;[WAITFORPREVMOVE] Loop that wait for the previous servo move to be finished
idle var byte
finished var byte
junk var word
WaitForPrevMove
	; Simple loop to check the status of all of servos.  This loop will
	; terminate when all of the servos say that they are idle.  I.E.
	; they reached their new destination.   
	do 
		finished = hservoidle(BasePin) and hservoidle(ShoulderPin) and hservoidle(ElbowPin) and hservoidle(WristPin) 	and hservoidle (GripperPin) and hservoidle(WristRotatePin)
		
	while (NOT finished)	

	if(NOT finished)then WaitForPrevMove

	_mPrev_BasePos1			= BasePosition1
	_mPrev_ShoulderPos1 	= ShoulderPosition1
	_mPrev_ElbowPos1  		= ElbowPosition1
	_mPrev_WristPos1		= WristPosition1
	_mPrev_GripperPos1		= GripperPosition1
	_mPrev_WristRotatePos1	= WristRotatePosition1
	
return

;--------------------------------------------------------------------
;[GETLONGEST] Returns the longest value
one var slong 
two var slong 
three var slong 
four var slong 
five var slong 
six var slong 
GetLongest[one,two,three,four,five,six] 
   if(one<0)then 
      one=-1*one 
   endif 
   if(two<0)then 
      two=-1*two 
   endif 
   if(three<0)then 
      three=-1*three 
   endif 
   if(four<0)then 
      four=-1*four 
   endif 
   if(five<0)then 
      five=-1*five 
   endif 
   if(six<0)then 
      six=-1*six 
   endif 
   if(one<two)then 
      one=two 
   endif 
   if(one<three)then 
      one=three 
   endif 
   if(one<four)then 
      one=four 
   endif 
   if(one<five)then 
      one=five 
   endif 
   if(one<six)then 
      one=six 
   endif 
return one  
;--------------------------------------------------------------------    
;[GetSpeed] Calculate the speed for each servo
newpos1 var slong 
oldpos1 var slong 
longest1 var slong 
maxval1 var slong 
GetSpeed[newpos1,oldpos1,longest1,maxval1] 

   if(newpos1>oldpos1)then 
      return ((((newpos1-oldpos1)*maxval1)/longest1)/10 Max 200)
   endif 

return ((((oldpos1-newpos1)*maxval1)/longest1)/10 Max 200)
;--------------------------------------------------------------------
#endif ; USE_SSC32



If anyone can spot a simple solution, that would be great. However, since we don’t have instructions using that specific board, and the PS2 controller you have may also have issues. I have not know of PS2s being hacked directly to the board (the voltages may be entirely wrong). Set up the PS2 receiver with the Basic Micro board and disconnect the SSC-32. Check that connection by finding code which reads and interprets the PS2 signals.

If that works well, we suggest establishing that the arm is correctly configured by using ONLY the SSC-32 servo controller and installing / running the Servo Sequencer software (free):
lynxmotion.com/p-895-free-do … tudio.aspx
Keep in mind you will need to put the serial jumpers back in place

Next, connect the Basic Micro board to the SSC-32. Ensure you have the GND to GND and the serial out of the Basic board to the Rx of the SSC-32. Create simple code to send SSC-32 commands from the Basic Atom board, such as “#0P1500” Refer to the SSC-32 user guide if you have any questions. This will help ensure that connection is correct.

I can not tell for sure about your connections for the PS2. In particular the DAT line P12, when the BAP28 is installed in the Bot Board 2, by default there is a Pull-up resistor connected up to this IO pin, which is needed for it to work properly. If you have any resistors sitting around, try connecting P12 to +5v through something like a 1K resistor and see if that helps

I will try to check the connection again. I think i will try to connect the PS2 controller direct to basic micro. if nothing happen, i think the PS2 is not compatible with it.
thanks CBenson and kurte. :slight_smile: