Pages: [1]   Go Down
Author Topic: help with Python with USB joystick controlling servo and dc motor with PWM?  (Read 3136 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 11
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Alright to summarise about the project I intend to build on with my Arduino. I'm planning to build an unmanned ground vehicle that will be controlled wireless using the Xbee modules, a computer, a Logitech Attack 3 and lastly, the ever important Python. I had figured out some codes but right now, I have trouble figuring out how to make sure my servo moves as long as I press down the button on the joystick. Its frustrating that I have to keep pressing and (un)pressing the joystick buttons to move the servo. Can anyone help me figure out how to make sure the servo can move as long as I keep the buttons down? And also can anyone guide me about how I can use the analog stick to control motors with PWM? For example, when I move the joystick forwards, two motors will rotate clockwise and when i move the joystick to the left or right, one motor will move forwards and another backwards. And as a bonus if I move the joystick diagonally, one motor will maintain speed/increase speed and the other lower speed/maintain speed? Thanks guys!

Here are my codes.
Python code for joystick event control.
Code:
#!/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)

    if e.type == pygame.JOYBUTTONDOWN:
        str = "Button: %d" % (e.dict['button'])
        # uncomment to debug
        # uncomment to debug
        output(str, e.dict['joy'])
        # Button 8 to quit
        
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#=========================Rifle control section========================
#-------------------------Axis Y---------------------------------------
        if (e.dict['button'] == 1):
                #serv = 1
                # 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, 0)
        if (e.dict['button'] == 2):
                #serv = 1
                # 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, 1)
#----------------------------------------------------------------------
#-------------------------Axis X---------------------------------------
        if (e.dict['button'] == 3):
                #serv = 1
                # 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, 3)
        if (e.dict['button'] == 4):
                #serv = 1
                # 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, 4)      
#======================================================================
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#========================Rifle cocking section=========================
        for serv in range(0, 180, 1):
            if (e.dict['button'] == 5):
                #serv = serv + 1
                # 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(12, serv)
#======================================================================
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#========================Program Exit==================================
        if (e.dict['button'] == 7):
            print "Mission End"
            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 Button 8 to quit.\n"

    # run joystick listener loop
    joystickControl()

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

and here is the servo.py that communicates with the serial port to Arduino.
Code:
#!/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)
#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))
        ser.write(chr(servo))
        ser.write(chr(angle))
    else:
        print "Servo angle must be an integer between 0 and 180.\n"

Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 11
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

***continued because of character limits.


and finally! the Arduino code!
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-4-axis-servo-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;
Servo servo12;
// TO ADD SERVOS:
//   Servo servo5;
//   etc...

// Common servo setup values
int minPulse = 600;   // minimum servo position, us (microseconds)
int maxPulse = 2370;// maximum servo position, us
int minPulse1 = 800;
int maxPulse1 = 3000;
// 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
int fpos1 = 90;
int fpos2 = 90;
int change = 5;

void setup()
{
  // Attach each Servo object to a digital pin
  servo1.attach(2, minPulse1, maxPulse1);//camera up and down
  servo2.attach(3, minPulse, maxPulse);
  servo3.attach(4, minPulse1, maxPulse1);//camera left and right
  servo4.attach(5, minPulse, maxPulse);
  servo12.attach(13, minPulse, maxPulse); //gun cocking servo
  // 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) {
      //----Axis Y----------------------
        case 1:
        if(userInput[1]==1)//if arduino detects 1 coming from python, goes into following loop
        {
          fpos1 = fpos1 + change;
        }
        if(userInput[1]==0)//if arduino detects 0 coming from python, goes into following loop
        {
          fpos1 = fpos1 - change;
        }
        fpos1 = constrain(fpos1, 50, 150); // limit value of angle
        servo1.write(fpos1);
        delay(10);
        break;
      //--------------------------------
        case 2:
          servo2.write(pos);
          break;
      //----Axis X----------------------  
        case 3:
        if(userInput[1]==3)//if arduino detects 3 coming from python, goes into following loop
        {
          fpos2 = fpos2 + change;
        }
        if(userInput[1]==4)//if arduino detects 4 coming from python, goes into following loop
        {
          fpos2 = fpos2 - change;
        }
        fpos2 = constrain(fpos2, 50, 150); // limit value of angle
        servo3.write(fpos2);
        delay(10);
        break;
      //-------------------------------
        case 4:
          servo4.write(pos);
          break;
        case 12:
          servo12.write(pos);
          break;
   // TO ADD SERVOS:
   //     case 5:
   //       servo5.write(pos);
   //       break;
   // etc...
      }
    }
  }

}

i really appreciate all the help i can get guys! sincerely!
Logged

Pages: [1]   Go Up
Jump to: