So our robot is going to have two motors working to produce differential steering. I.e. move one side faster to turn.
This means we need two hardware PWMs for continuous speed control and to have some way of controlling it remotely!
With the raspberry pi3 there is an opportunity to have no external hardware on the robot itself by using a PS4 DS4 controller which connects over bluetooth.
We’re working in python and there is handily a python based driver called ds4drv.
To get ds4drv on the pi running you can use the following commands:
sudo apt install python3-dev python3-pip sudo pip3 install ds4drv
Then in the file “/home/user/.bashrc” – where user is pi by default – add the following line to the file:
sudo ds4drv --daemon --led 000008 --emulate-xpad-wireless &
This ensures that the bluetooth driver is initialised every time you log in. Then to connect your ds4 controller hold the share button and the ps button until manic flashing begins and the light bar should turn blue when it’s all connected.
To test this was working I used a program called jstest. You can get this by running the commands:
sudo apt-get install joystick jstest /dev/input/js0
The js0 may be different on your pi if you have multiple joysticks attached.
When jstest is running you will get a readout of each change to the status of js0, i.e. every time you press a button or move a joystick you will get an update on the command line telling you what each button a joystick value is now.
Now to implement this in a python script!
For this it was important to make sure that python3, pygame and wiringpi were all installed. Then the following script gets a connected ds4 controller and maps the trigger values to two hardware pwms. In this example there is stuff for controlling the H-bridge we’ve got for powering the motors too.
"""Test script for using pygame to read in ds4 controller with ds4drv running as a daemon DS4 controller axis maps: Axis0: Left stick l-r (-1 left, 1 right) Axis1: Left stick u-d (-1 up, 1 down) Axis2: Left trigger (-1 unpressed, 1 completely pressed) Axis3: Right stick l-r (-1 left, 1 right) Axis4: Right stick u-d (-1 up, 1 down) Axis5: Right trigger (-1 unpressed, 1 completely pressed) """ import pygame import wiringpi from time import sleep import sys #initialise DS4 controller screen = pygame.display.set_mode([10,10]) #make a 10x10 window pygame.joystick.init() #find the joysticks joy = pygame.joystick.Joystick(0) joy.init() if(joy.get_name()=='Sony Entertainment Wireless Controller'): print("DS4 connected") else: print("Not a DS4") Motor1PWM = 1 # gpio pin 12 = wiringpi no. 1 (BCM 18) Motor1AIN1 = 4 # gpio pin 16 = wiringpi no. 4 (BCM 23) Motor1AIN2 = 5 # gpio pin 18 = wiringpi no. 5 (BCM 24) MotorStandby = 6 # gpio pin 22 = wiringpi no. 6 (BCM 25) Motor2PWM = 23 # gpio pin 33 = wiringpi no. 23 (BCM 13) Motor2BIN1 = 21 # gpio pin 29 = wiringpi no. 21 (BCM 5) Motor2BIN2 = 22 # gpio pin 31 = wiringpi no. 22 (BCM 6) # Initialize PWM output wiringpi.wiringPiSetup() wiringpi.pinMode(Motor1PWM, 2) # PWM mode wiringpi.pinMode(Motor1AIN1, 1) #Digital out mode wiringpi.pinMode(Motor1AIN2, 1) #Digital out mode wiringpi.pinMode(MotorStandby, 1) #Ditial out mode wiringpi.pinMode(Motor2PWM, 2) # PWM mode wiringpi.pinMode(Motor2BIN1, 1) #Digital out mode wiringpi.pinMode(Motor2BIN2, 1) #Digital out mode wiringpi.pwmWrite(Motor1PWM, 0) # OFF wiringpi.pwmWrite(Motor2PWM, 0) # OFF wiringpi.digitalWrite(Motor1AIN1, 1) #forward mode wiringpi.digitalWrite(Motor1AIN2, 0) #forward mode wiringpi.digitalWrite(Motor2BIN1, 1) wiringpi.digitalWrite(Motor2BIN2, 0) wiringpi.digitalWrite(MotorStandby, 1) #enabled # Set Motor Speed def motorspeed(speed1, speed2): wiringpi.pwmWrite(Motor1PWM, speed1) #motorspeed from 0 to 1024 wiringpi.pwmWrite(Motor2PWM, speed2) while True: pygame.event.get() rt = joy.get_axis(5) lt = joy.get_axis(2) print(rt) print(lt) speed1 = (rt+1)*512 speed2 = (lt+1)*512 motorspeed(int(speed1),int(speed2)) sleep(0.1) #limit the frequency to 10Hz
Success! This resulted in two hardware PWMs and associated digital signals being controlled in a simple way by the DS4 controller over bluetooth. Seems pretty reliable so far too. Videos to follow when then is wired up to SunnyBot himself!