Hello everyone I've been trying to figure out how to make a joystick move a servo by using Arduino board, its software and Python with pygame module. But I can't just get the servo to move. I really wish someone can help me. This is actually part of my final year project. My lecturer told me that I could actually get a distinction for my project easily if I get this to work. It can actually help me get into a good university. That is why I had been reading day and night and trying to make it work.

I've used the codes from principallabs. Can anyone help me spot any mistakes? Also is it possible if someone teach me how to move the servos using the d-pad on my joystick rather than use the analog stick?

This is my python code that allows my joystick to control my Arduino board.

#!/usr/bin/env python

    ################################################################
    # Module:   multijoystick.py
    # Created:  2 April 2008
    # Author:   Brian D. Wendt
    #   http://principialabs.com/
    # Version:  0.2
    # License:  GPLv3
    #   http://www.fsf.org/licensing/
    '''
    Provides four-axis joystick servo control from a PC
    using the Arduino "MultipleServos" sketch
    and the Python "servo.py" serial abstraction module.

    Parts of this code were adapted from:
      http://svn.lee.org/swarm/trunk/mothernode/python/multijoy.py

    NOTE: This script requires the following Python modules:
      pyserial - http://pyserial.sourceforge.net/
      pygame   - http://www.pygame.org/
      servo    - http://principialabs.com/
    Win32 users may also need:
      pywin32  - http://sourceforge.net/projects/pywin32/
    '''
    ################################################################

    import servo
    import pygame

    # allow multiple joysticks
    joy = []

    # handle joystick event
    def handleJoyEvent(e):
        if e.type == pygame.JOYAXISMOTION:
            axis = "unknown"
            if (e.dict['axis'] == 0):
                axis = "X"

            if (e.dict['axis'] == 1):
                axis = "Y"

            if (e.dict['axis'] == 2):
                axis = "Throttle"

            if (e.dict['axis'] == 3):
                axis = "Z"

            if (axis != "unknown"):
                str = "Axis: %s; Value: %f" % (axis, e.dict['value'])
                # uncomment to debug
                #output(str, e.dict['joy'])

                # Arduino joystick-servo hack
                if (axis == "X"):
                    pos = e.dict['value']
                    # convert joystick position to servo increment, 0-180
                    move = round(pos * 90, 0)
                    serv = int(90 + move)
                    # and send to Arduino over serial connection
                    servo.move(1, serv)

                # Arduino joystick-servo hack
                if (axis == "Y"):
                    pos = e.dict['value']
                    # convert joystick position to servo increment, 0-180
                    move = round(pos * 90, 0)
                    serv = int(90 + move)
                    # and send to Arduino over serial connection
                    servo.move(2, serv)

                # Arduino joystick-servo hack
                if (axis == "Z"):
                    pos = e.dict['value']
                    # convert joystick position to servo increment, 0-180
                    move = round(pos * 90, 0)
                    serv = int(90 + move)
                    # and send to Arduino over serial connection
                    servo.move(3, serv)

                # Arduino joystick-servo hack
                if (axis == "Throttle"):
                    pos = e.dict['value']
                    # convert joystick position to servo increment, 0-180
                    move = round(pos * 90, 0)
                    serv = int(90 + move)
                    # and send to Arduino over serial connection
                    servo.move(4, serv)

        elif e.type == pygame.JOYBUTTONDOWN:
            str = "Button: %d" % (e.dict['button'])
            # uncomment to debug
            #output(str, e.dict['joy'])
            # Button 0 (trigger) to quit
            if (e.dict['button'] == 0):
                print ("Bye!\n")
                quit()
        else:
            pass

    # print the joystick position
    def output(line, stick):
        print ("Joystick: %d; %s" % (stick, line))

    # wait for joystick input
    def joystickControl():
        while True:
            e = pygame.event.wait()
            if (e.type == pygame.JOYAXISMOTION or e.type == pygame.JOYBUTTONDOWN):
                handleJoyEvent(e)

    # main method
    def main():
        # initialize pygame
        pygame.joystick.init()
        pygame.display.init()
        if not pygame.joystick.get_count():
            print ("\nPlease connect a joystick and run again.\n")
            quit()
        print ("\n%d joystick(s) detected." % pygame.joystick.get_count())
        for i in range(pygame.joystick.get_count()):
            myjoy = pygame.joystick.Joystick(i)
            myjoy.init()
            joy.append(myjoy)
            print ("Joystick %d: " % (i) + joy[i].get_name())
        print ("Depress trigger (button 0) to quit.\n")

        # run joystick listener loop
        joystickControl()

    # allow use as a module or standalone script
    if __name__ == "__main__":
        main()

this is my servo.py code. prerequisite for the above code to work.

#!/usr/bin/env python

    ################################################
    # Module:   servo.py
    # Created:  2 April 2008
    # Author:   Brian D. Wendt
    #   http://principialabs.com/
    # Version:  0.2
    # License:  GPLv3
    #   http://www.fsf.org/licensing/
    '''
    Provides a serial connection abstraction layer
    for use with Arduino "MultipleServos" sketch.
    '''
    ################################################

    import serial

    usbport = 'COM7'
    ser = serial.Serial(usbport, 9600, timeout=1)
    #print ser

    def move(servo, angle):
        '''Moves the specified servo to the supplied angle.

        Arguments:
            servo
              the servo number to command, an integer from 1-4
            angle
              the desired servo angle, an integer from 0 to 180

        (e.g.) >>> servo.move(2, 90)
               ... # "move servo #2 to 90 degrees"'''

        if (0 <= angle <= 180):
            ser.write(chr(255).encode())
            ser.write(chr(servo).encode())
            ser.write(chr(angle).encode())
        else:
            print ("Servo angle must be an integer between 0 and 180.\n")

and lastly this is my Arduino code.

/*
* ------------------------------
* MultipleSerialServoControl
* ------------------------------
*
* Uses the Arduino Serial library
* (http://arduino.cc/en/Reference/Serial)
* and the Arduino Servo library
* (http://arduino.cc/en/Reference/Servo)
* to control multiple servos from a PC using a USB cable.
*
* Dependencies:
* Arduino 0017 or higher
* (http://www.arduino.cc/en/Main/Software)
* Python servo.py module
* (http://principialabs.com/arduino-python ... o-control/)
*
* Created: 23 December 2009
* Author: Brian D. Wendt
* (http://principialabs.com/)
* Version: 1.0
* License: GPLv3
* (http://www.fsf.org/licensing/)
*
*/

// Import the Arduino Servo library
#include <Servo.h>

// Create a Servo object for each servo
Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
// TO ADD SERVOS:
// Servo servo5;
// etc...

// Common servo setup values
int minPulse = 900; // minimum servo position, us (microseconds)
int maxPulse = 2400; // maximum servo position, us

// User input for servo and position
int userInput[3]; // raw input from serial buffer, 3 bytes
int startbyte; // start byte, begin reading input
int servo; // which servo to pulse?
int pos; // servo angle 0-180
int i; // iterator

void setup()
{
// Attach each Servo object to a digital pin
servo1.attach(2, minPulse, maxPulse);
servo2.attach(3, minPulse, maxPulse);
servo3.attach(4, minPulse, maxPulse);
servo4.attach(5, minPulse, maxPulse);
// TO ADD SERVOS:
// servo5.attach(YOUR_PIN, minPulse, maxPulse);
// etc...

// Open the serial connection, 9600 baud
Serial.begin(9600);
}

void loop()
{
// Wait for serial input (min 3 bytes in buffer)
if (Serial.available() > 2) {
// Read the first byte
startbyte = Serial.read();
// If it's really the startbyte (255) ...
if (startbyte == 255) {
// ... then get the next two bytes
for (i=0;i<2;i++) {
userInput[i] = Serial.read();
}
// First byte = servo to move?
servo = userInput[0];
// Second byte = which position?
pos = userInput[1];
// Packet error checking and recovery
if (pos == 255) { servo = 255; }

// Assign new position to appropriate servo
switch (servo) {
case 1:
servo1.write(pos); // move servo1 to 'pos'
break;
case 2:
servo2.write(pos);
break;
case 3:
servo3.write(pos);
break;
case 4:
servo4.write(pos);
break;
// TO ADD SERVOS:
// case 5:
// servo5.write(pos);
// break;
// etc...
}
}
}


}

i hope i can get help. Anyways I'm using Arduino 0022 and Python 3.1. I'm using a Logitech Attack 3 joystick. My Arduino board is connected to COM7. the thing is that everytime i move my joystick, the RX light on my Arduino lights up. but my servo doesnt move.

Edited 5 Years Ago by amanmazleigh: n/a

And where do you get the servo module from??
self written?

its all from principallabs. even though i modified the code so that there will be no errors.

have u got the arduino working?
im using Win7, i had to install python2.6 to get pygame and py serial to start working. and u need to compile the servo.py file.
if u get Python, pygame, and pyserial to work then u get the principialabs sketch working.
look at youtube. lots of tutorials on python.
think if u write "import pygame" in python shell and u get no errors then its all good =P

This article has been dead for over six months. Start a new discussion instead.