Working code

Control of steering & drive of the vehicle using the PS3 controller via the Adafruit PWM module

Req updating to latest version

from __future__ import division
import time
import Adafruit_PCA9685 # Import the PCA9685 module.
import pygame

# Initilize pygame to use the JS functions

pygame.init()

pwm = Adafruit_PCA9685.PCA9685() # Initialise the PCA9685 using the default address (0x40).
 # Alternatively specify a different address and/or bus:
 # pwm = Adafruit_PCA9685.PCA9685(address=0x41, busnum=2)

# Set some presets from here
done = False # Loop until the user stops
clock = pygame.time.Clock() # Used to slowdown the loop and not overload the CPU
servo_min = 150 # Min pulse length out of 4096
servo_max = 600 # Max pulse length out of 4096
mode = 0 # Set mode to zero at start
NumAxis = 4 # Number of JS Axis to be used
NumOP = 12 # Number of OPs to be used

FR = 280 # Value for Front Right servo travel
FL = 450 # Value for Front Left servo travel
FC = 365 # Value for Front Centre servo travel 
RR = 440 # Value for Rear Right servo travel
RL = 270 # Value for Rear Left servo travel
RC = 355 # Value for Rear Centre servo travel

Fwd = 600 # Motors max speed Fwd value
Rev = 150 # Motors max speed Rev value
Off = 375 # Motors Off value

# Create the lists for IPs and OPs
AxisIPs = [0.0, 0.0, 0.0, 0.0] #Setup the array for the 4 axis IPs - from JS
AxisOPs = [FC, 0, RC, Off, 0,0,0,0,0,0,0,0] #Setup the array for the OPs - to Servos and LEDs

# Initialize the joysticks
pygame.joystick.init()
joystick = pygame.joystick.Joystick(0)
joystick.init()

print('start')

# Set frequency to 60hz, good for servos
pwm.set_pwm_freq(60)

for i in range( NumOP ): 
 pwm.set_pwm( i, 0, AxisOPs [i] ) # Centre all axis and turn off the LEDs

# Inputs from JS
# Axis 0 = Left stick left/right
# Axis 1 = Left stick up/down - normally speed
# Axis 2 = Right stick left/right - normally steering
# Axis 3 = Right stick up/down
#
# Outputs to Servos
# Channel 0 = Front steering
# Channel 1 = not used
# Channel 2 = Rear steering
# Channel 3 = motor speed
# Channels 4..11 LED digit 
# -------- Main Program Loop -----------
while done == False:
 # EVENT PROCESSING STEP
 for event in pygame.event.get(): # User did something
 if event.type == pygame.JOYBUTTONDOWN: # If a JS button was pressed
 if joystick.get_button(0) == 1: # If user clicked SELECT button
 done = True # Exit this loop

elif joystick.get_button(4) == 1: # Use UP ARROW button to inc. mode
 mode = mode +1
 elif joystick.get_button(6) == 1: # Use DOWN ARROW button to dec. mode
 mode = mode -1 
 if mode < 0: # limit modes to 0..8
 mode = 0
 if mode > 8:
 mode = 8
 
 for i in range( NumAxis ):
 axis = joystick.get_axis( i ) 
 AxisIPs [i] = axis

# Mode selection from here - max of 8 modes...
# 0 = all centred
# 1 = front steer normal & rear steer locked
# 2 = front steer normal & rear steer same as front
# 3 = front steer normal & rear steer oposite to front 
# 4 = all inputs direct to ouputs
# 5 = not used
# 6 = not used
# 7 = not used
# 8 = setting and saving of limit values

# Calc for JS to O/Ps
# value from JS = -1..0..+1
# Add 1 to make +ve 0..2
# span = hi value - lo value / 2
# Req O/P = value from JS * span + lo vlaue
# O/P converted from Float to Int
 
 if mode == 0: # All axis to centre pos.
 AxisOPs = [FC, 0, RC, Off,4000,4000,4000,4000,4000,4000,0,0]

elif mode == 1: #4WD with front steer
 AxisOPs = [0,0,0,0,0,4000,4000,0,0,0,0,4000] #LEDs to 1
 # Calc for front steering
 span = (FL - FR) / 2
 AxisOffset = 2 - (AxisIPs [2] + 1) # "2 -" to reverse the JS direction
 OPcalc = (AxisOffset * span ) + FR
 AxisOPs [0] = int(OPcalc)
 # Calc for rear steering
 AxisOPs [2] = RC # Rear centred
 # Calc for motors
 span = (Fwd - Rev) / 2
 AxisOffset = AxisIPs [1] + 1
 OPcalc = (AxisOffset * span ) + Rev
 AxisOPs [3] = int(OPcalc)

elif mode == 2: # 4WD with crab steer
 AxisOPs = [0,0,0,0,4000,4000,0,4000,4000,0,4000,4000]
 # Calc for front steering
 span = (FL - FR) / 2
 AxisOffset = 2 - (AxisIPs [2] + 1) # "2 -" to reverse the JS direction
 OPcalc = (AxisOffset * span ) + FR
 AxisOPs [0] = int(OPcalc)
 # Calc for rear steering
 span = (RR - RL) / 2 # Same direction as front
 AxisOffset = 2 - (AxisIPs [2] + 1) # "2 -" to reverse the JS direction
 OPcalc = (AxisOffset * span ) + RL
 AxisOPs [2] = int(OPcalc)
 # Calc for motors
 span = (Fwd - Rev) / 2
 AxisOffset = AxisIPs [1] + 1
 OPcalc = (AxisOffset * span ) + Rev
 AxisOPs [3] = int(OPcalc)

elif mode == 3: # 4WD with oposite steer
 AxisOPs = [0,0,0,0,4000,4000,4000,4000,0,0,4000,4000]
 # Calc for front steering
 span = (FL - FR) / 2
 AxisOffset = 2 - (AxisIPs [2] + 1) # "2 -" to reverse the JS direction
 OPcalc = (AxisOffset * span ) + FR
 AxisOPs [0] = int(OPcalc)
 # Calc for rear steering
 span = (RR - RL) / 2 # Oposite direction as front
 AxisOffset = AxisIPs [2] + 1
 OPcalc = (AxisOffset * span ) + RL
 AxisOPs [2] = int(OPcalc)
 # Calc for motors
 span = (Fwd - Rev) / 2
 AxisOffset = AxisIPs [1] + 1
 OPcalc = (AxisOffset * span ) + Rev
 AxisOPs [3] = int(OPcalc)

elif mode == 4: # All axis seperate control
 AxisOPs = [0,0,0,0,0,4000,4000,0,0,4000,4000,4000]
 # Calc for front steering
 span = (FL - FR) / 2
 AxisOffset = 2 - (AxisIPs [2] + 1) # "2 -" to reverse the JS direction
 OPcalc = (AxisOffset * span ) + FR
 AxisOPs [0] = int(OPcalc)
 # Calc for rear steering
 span = (RR - RL) / 2 # Free direction from left JS
 AxisOffset = 2 - (AxisIPs [0] + 1) # "2 -" to reverse the JS direction
 OPcalc = (AxisOffset * span ) + RL
 AxisOPs [2] = int(OPcalc)
 # Calc for motors
 span = (Fwd - Rev) / 2
 AxisOffset = AxisIPs [1] + 1
 OPcalc = (AxisOffset * span ) + Rev
 AxisOPs [3] = int(OPcalc)

elif mode == 5: # Steering test - no drive
 AxisOPs = [FC, 0, RC, Off,4000,0,4000,4000,0,4000,4000,4000]
 # Calc for front steering
 span = (FL - FR) / 2
 AxisOffset = 2 - (AxisIPs [2] + 1) # "2 -" to reverse the JS direction
 OPcalc = (AxisOffset * span ) + FR
 AxisOPs [0] = int(OPcalc)
 # Calc for rear steering
 span = (RR - RL) / 2 # Free direction from left JS
 AxisOffset = 2 - (AxisIPs [0] + 1) # "2 -" to reverse the JS direction
 OPcalc = (AxisOffset * span ) + RL
 AxisOPs [2] = int(OPcalc)
 # Calc for motors - motors off
 AxisOPs [3] = Off

elif mode == 6: # Not used - all to centre pos.
 AxisOPs = [FC, 0, RC, Off,4000,0,4000,4000,4000,4000,4000,0]
 
 elif mode == 7: # Not used - all to centre pos.
 AxisOPs = [FC, 0, RC, Off,4000,4000,4000,0,0,0,0,0]
 
 elif mode == 8: # setting limit values
 AxisOPs = [FC, 0, RC, Off,4000,4000,4000,4000,4000,4000,4000,0]
 
 for i in range( NumOP ):
 pwm.set_pwm(i, 0, AxisOPs [i]) # Then use the calc values as the position for servos and LEDs
 
 #Limit to 10 loops per second
 clock.tick(10)


#End of program actions:
AxisOPs = [FC, 0, RC, Off,0,0,0,0,0,0,0,0]
for i in range( NumOP ): 
 pwm.set_pwm( i, 0, AxisOPs [i] ) # Centre all axis and turn off the LEDspwm.set_pwm(4, 0, 0)

pygame.quit ()
print ('stop')