In the previous post here, I successfully connected DS4 controller to Raspberry Pi.
It is time for me to control something using this framework.
The easiest way for me is to control the servo using DS4 input events as I have the servo controller board and tilt & pan servos from Adafruit.My goal is to use joystick on the DS4 to control the pan & tilt of servo and see how it works.
I expect it would not be so great using joystick as it is a bit sensitive and may be difficult to control servo naturally or precisely.
Well, let's see how it goes...
Setup
As always, I am using Raspberry Pi 3 Model B (not Plus) for this setup.
The setup looks like this in my environment.
Connecting DS4 to Raspberry Pi can be referred to my previous work here.
Also, the using Adafruit servo controller shield board and pan & tilt servo kit can be referred to my previous work here as well.
Adafruit servo controller shield board requires the external power supply but you may be able to use Raspberry Pi 5V by connecting the power and ground pins to the shield board depending on the servo you use.
My approach:
My approach here is to obtain the variation from the default (center) position of the joystick data and convert the number to the servo control signal with a simple scale factor.
Something like this.
Servo value = (Joystick current value - Joystick center value) x scale factor
There are so many descriptions if you google it but what I did was to add the following line in the python.
print (gamepad.capabilities(verbose=True))
This will give you the default value and maximum and minimum value of the each event of the input device.
From this message, left joystick returns 127 as the center value and maximum 255 and minimum 0.
This means the maximum variation value that I get from joystick is 128 and minimum is -127.
Maximum variation value = 255 - 127 = 128
Miminum variation value = 0 - 127 = -127
I just want to move the servo around +/-90 degrees horizontally, and my servo range is as below.
+90: 570
0: 370
-90: 170
Based on the above, I decided the equation to be like this.
Servo value = (Joystick current value - 127) x 1/10
One thing that I cannot forget is that I am using evdev and it only returns the input event when there is a change in the value.
This means if I move the joystick to the all the way left or right, the joystick value does not change from the point which results in no servo movement.
Notes:
Before moving forward, I would recommend to double check the minimum and maximum rotations of your servo.
Joystick is sensitive and servo might go crazy if the tuning is not done properly.I would also recommend to place the servo securely with something.
In my case, I used cramp and place it on my desk tightly.
Python code for testing
Now the time to implement the code for both DS4 joystick and servo control.
As I mentioned above and same as my previous work, I used evdev and python for this quick example.
*** Depending on the python version, you may get different result and my python version is 2.7.13.
If you need the input event numbers of your controller, you can use the following commands to idendify the numbers.
Check input events:
$ ls /dev/input
Install input-utils:
If you do not know which event is mouse or keyboard, follow this.
If you do not know which event is mouse or keyboard, follow this.
$ sudo apt-get install input-utils$ lsinput
Video:
Here is the video of the quick test.
Example:
This is the python example code.
#!/usr/bin/pythonfrom Adafruit_PWM_Servo_Driver import PWM import time from evdev import InputDevice, categorize, ecodes, KeyEvent gamepad = InputDevice('/dev/input/event7') absMed = 128 pwm = PWM(0x40) servo0Min = 60 servo0Mid = 360 servo0Max = 660 pwm.setPWMFreq(60) pwm.setPWM(0, 0, servo0Mid) time.sleep(1) step0 = servo0Mid step0Var = 0 for event in gamepad.read_loop(): if event.type == ecodes.EV_ABS: if event.code == 0 and abs(event.value-absMed) > 20: step0Var = (event.value - absMed)/10 print ('step0Var:' + str(step0Var)) print ('step0 :' + str(step0)) step0 += step0Var if step0 > servo0Max: step0 = servo0Max elif step0 < servo0Min: step0 = servo0Min pwm.setPWM(0, 0, step0) step0Var = 0
Crate a python script file as below and copy&paste the above code.
nano ds4-servo-test.py
Run the python script.
python ds4-servo-test.py
Press any buttons on the DS4 and you will see the outputs in the terminal.
Done!