Go Down

Topic: help with Python with USB joystick controlling servo and dc motor with PWM? (Read 3791 times) previous topic - next topic

amanmazleifg

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: [Select]
#!/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: [Select]
#!/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"



amanmazleifg

***continued because of character limits.


and finally! the Arduino code!
Code: [Select]
/*
* ------------------------------
*   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!

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy