Kit: Rubber Band Shooter Turret (Joystick controlled)

()

This is a easy-modifiable rubberband shooting turret, build to be controlled by a wireless Playstation 2 joystick.

The kit consist of:

  • Code for the turret controls and building pieces, easy to modify for your needs.
  • Laser Cutting PDF of the building pieces.
  • A simple guide to get started.


1. Materials and resources:

Arduino: http://www.arduino.cc/en/Main/Software
Processing: https://processing.org/

Download: Cutting PDF and Code files:

Materials:

  • 3mm HDF: w: 26cm. x 34cm.
  • Arduino Board.
  • USB stick.
  • Servo controller shield or prototyping shield (or other means to connect the servo).
  • About 200 micro farad capacitor.
  • Screws (fitted for the servo mounts).
  • 3x Servo mount.
  • 1x SM-S4303R Continuous servo.
  • 2x TOWER PRO SG-5010 servos.
  • 1x PS2 controller Wireless adapter.
  • 1x Wireless PS2 joystick.

Tools:

  • Laser cutter.
  • Gluegun.
  • Screwdriver
  • Pincers
  • Soldering iron.


2. Laser cutting:

RUC Fablab Guide for laser cutting:
http://fablab.ruc.dk/lasercutter-guide/

3. Assembly:

The following pictures describe how the turret are assembled.

Tips:
  • Don't put the servo mounts and servos together with screws, before you are certain the code works with the turret.
  • Use the pincers to cut of ends of the screws attached to servo mounts, so they do not interfere with the servo rotation.


Detailed photos


Wiring

Source: Bill Porter

The three servos should be connected to the following pins:

  • Base servo: 6
  • Gun servo : 7
  • Trigger servo: 8

The three servos should be connected in a similar fashion as the diagram below. It is advised to place a capacitor (at least/approximately 200 micro farad - exact value is not critical) between plus and minus (plus on the capacitor should be connected to plus/5V on the Arduino).

The PS2 controller Wireless adapter should be connected to the following pins:

  • Yellow: attention - pin 10
  • Orange: command - pin 11
  • Blue: clock - pin 12
  • Brown: data - pin 13
  • Red: power 3.3V - 5V
  • Black: ground - GND

Image Source: CuriousInventor


Detailed photos


4. Code

To get the code for the turret working, you need to copy "PS2X lib" folder to the Arduino library folder.

Afterwards "PS2X lib" should appear under "Examples" in Arduino.

Arduino Code:

    #include <PS2X_lib.h>  //for v1.6

    /******************************************************************
       set pins connected to PS2 controller:
         - 1e column: original
         - 2e colmun: Stef?
       replace pin numbers by the ones you use
     ******************************************************************/
    #define PS2_DAT        13  //14    
    #define PS2_CMD        11  //15
    #define PS2_SEL        10  //16
    #define PS2_CLK        12  //17

    /******************************************************************
       select modes of PS2 controller:
         - pressures = analog reading of push-butttons
         - rumble    = motor rumbling
       uncomment 1 of the lines for each mode selection
     ******************************************************************/
    //#define pressures   true
    #define pressures   false
    //#define rumble      true
    #define rumble      false

    PS2X ps2x; // create PS2 Controller Class

    //right now, the library does NOT support hot pluggable controllers, meaning
    //you must always either restart your Arduino after you connect the controller,
    //or call config_gamepad(pins) again after connecting the controller.

    int error = 0;
    byte type = 0;
    byte vibrate = 0;
    #include <Servo.h>

    Servo servoGun;  // create servo object to control a servo
    // twelve servo objects can be created on most boards
    Servo servoBase;
    Servo servoTrigger;

    // ----------------- BEGIN: Movement Control -----------------
    int basePosition; //Keeps track of where the base is
    int gunPosition;  //Keeps track of where the gun is

    int baseZero  = 128;  //Zero position of the X value of the right stick
    int gunZero   = 127;  //Zero position of the Y value of the left stick

    int baseIncrement = 2;
    int gunIncrement  = 2;
    int moveDelay     = 0;
    // ----------------- END: Movement Control -----------------

    void setup() {

      Serial.begin(57600); //Servo setup
      servoGun.attach(7);
      servoBase.attach(6);
      servoTrigger.attach(8);

      delay(300);  //added delay to give wireless ps2 module some time to startup, before configuring it

      //CHANGES for v1.6 HERE!!! **************PAY ATTENTION*************

      //setup pins and settings: GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error
      error = ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT, pressures, rumble);

      if (error == 0) {
        Serial.print("Found Controller, configured successful ");
        Serial.print("pressures = ");
        if (pressures)
          Serial.println("true ");
        else
          Serial.println("false");
        Serial.print("rumble = ");
        if (rumble)
          Serial.println("true)");
        else
          Serial.println("false");
        Serial.println("Try out all the buttons, X will vibrate the controller, faster as you press harder;");
        Serial.println("holding L1 or R1 will print out the analog stick values.");
        Serial.println("Note: Go to www.billporter.info for updates and to report bugs.");
      }
      else if (error == 1)
        Serial.println("No controller found, check wiring, see readme.txt to enable debug. visit www.billporter.info for troubleshooting tips");

      else if (error == 2)
        Serial.println("Controller found but not accepting commands. see readme.txt to enable debug. Visit www.billporter.info for troubleshooting tips");

      else if (error == 3)
        Serial.println("Controller refusing to enter Pressures mode, may not support it. ");

      error = 0;

      //  Serial.print(ps2x.Analog(1), HEX);

      type = ps2x.readType();
      switch (type) {
        case 0:
          Serial.print("Unknown Controller type found ");
          break;
        case 1:
          Serial.print("DualShock Controller found ");
          break;
        case 2:
          Serial.print("GuitarHero Controller found ");
          break;
        case 3:
          Serial.print("Wireless Sony DualShock Controller found ");
          break;
      }
    }

    void loop() {
      /* You must Read Gamepad to get new values and set vibration values
         ps2x.read_gamepad(small motor on/off, larger motor strenght from 0-255)
         if you don't enable the rumble, use ps2x.read_gamepad(); with no values
         You should call this at least once a second
      */
      if (error == 1) //skip loop if no controller found
        return;

      if (type == 2) { //Guitar Hero Controller
        ps2x.read_gamepad();          //read controller

        if (ps2x.ButtonPressed(GREEN_FRET))
          Serial.println("Green Fret Pressed");
        if (ps2x.ButtonPressed(RED_FRET))
          Serial.println("Red Fret Pressed");
        if (ps2x.ButtonPressed(YELLOW_FRET))
          Serial.println("Yellow Fret Pressed");
        if (ps2x.ButtonPressed(BLUE_FRET))
          Serial.println("Blue Fret Pressed");
        if (ps2x.ButtonPressed(ORANGE_FRET))
          Serial.println("Orange Fret Pressed");

        if (ps2x.ButtonPressed(STAR_POWER))
          Serial.println("Star Power Command");

        if (ps2x.Button(UP_STRUM))         //will be TRUE as long as button is pressed
          Serial.println("Up Strum");
        if (ps2x.Button(DOWN_STRUM))
          Serial.println("DOWN Strum");

        if (ps2x.Button(PSB_START))        //will be TRUE as long as button is pressed
          Serial.println("Start is being held");
        if (ps2x.Button(PSB_SELECT))
          Serial.println("Select is being held");

        if (ps2x.Button(ORANGE_FRET)) {    // print stick value IF TRUE
          Serial.print("Wammy Bar Position:");
          Serial.println(ps2x.Analog(WHAMMY_BAR), DEC);
        }
      }
      else { //DualShock Controller
        ps2x.read_gamepad(false, vibrate); //read controller and set large motor to spin at 'vibrate' speed

        if (ps2x.Button(PSB_START))        //will be TRUE as long as button is pressed
          Serial.println("Start is being held");
        if (ps2x.Button(PSB_SELECT))
          Serial.println("Select is being held");

        if (ps2x.Button(PSB_PAD_UP)) {     //will be TRUE as long as button is pressed
          Serial.print("Up held this hard: ");
          Serial.println(ps2x.Analog(PSAB_PAD_UP), DEC);
        }
        if (ps2x.Button(PSB_PAD_RIGHT)) {
          Serial.print("Right held this hard: ");
          Serial.println(ps2x.Analog(PSAB_PAD_RIGHT), DEC);
        }
        if (ps2x.Button(PSB_PAD_LEFT)) {
          Serial.print("LEFT held this hard: ");
          Serial.println(ps2x.Analog(PSAB_PAD_LEFT), DEC);
        }
        if (ps2x.Button(PSB_PAD_DOWN)) {
          Serial.print("DOWN held this hard: ");
          Serial.println(ps2x.Analog(PSAB_PAD_DOWN), DEC);
        }

    // ----------Begin: Trigger Control----------

        vibrate = ps2x.Analog(PSAB_CROSS);  //this will set the large motor vibrate speed based on how hard you press the blue (X) button
        if (ps2x.NewButtonState()) {        //will be TRUE if any button changes state (on to off, or off to on)
          if (ps2x.Button(PSB_L3))
            Serial.println("L3 pressed");
          if (ps2x.Button(PSB_R3))
            Serial.println("R3 pressed");
          if (ps2x.Button(PSB_L2))
            Serial.println("L2 pressed");
          if (ps2x.Button(PSB_R2))
            Serial.println("R2 pressed");
          if (ps2x.Button(PSB_TRIANGLE))
            Serial.println("Triangle pressed");
          int toServoTrigger = map(ps2x.Analog(PSB_L2), 0, 255, 0, 180); //This will set the trigger as (L2) button
          servoTrigger.write(toServoTrigger);
        }
        else
        {
          servoTrigger.write(90);
        }
    // -----------End: Trigger Control-----------

        if (ps2x.ButtonPressed(PSB_CIRCLE))              //will be TRUE if button was JUST pressed
          Serial.println("Circle just pressed");
        if (ps2x.NewButtonState(PSB_CROSS))              //will be TRUE if button was JUST pressed OR released
          Serial.println("X just changed");
        if (ps2x.ButtonReleased(PSB_SQUARE))             //will be TRUE if button was JUST released
          Serial.println("Square just released");

        int toServoGun = map(ps2x.Analog(PSS_LY), 0, 255, 0, 120); //This will set the gun to the Left sticks Y axis
        int toServoBase = map(ps2x.Analog(PSS_RX), 255, 0, 0, 180); //This will set the turret-base servo to the Right sticks X axis


    // ---------- BEGIN: Base Control ---------- 
        Serial.println("--------------------");
        Serial.print("Right X:");
        Serial.println(ps2x.Analog(PSS_RX));

        Serial.print("basePosition:");
        Serial.println(basePosition);



        if (ps2x.Analog(PSS_RX) < 128) {
          Serial.println("Right X < 128");
          if (basePosition > 255) {
            basePosition = 255;
          } else {
            basePosition = basePosition + baseIncrement;
            delay(moveDelay);
            servoBase.write(basePosition);
          }
        }

        if (ps2x.Analog(PSS_RX) > 128) {
          Serial.println("Right X > 128");
          if (basePosition < 0) {
            basePosition = 0;
          } else {
            basePosition = basePosition - baseIncrement;
            delay(moveDelay);
            servoBase.write(basePosition);
          }
        }

        // ---------- END: Base Control ---------- 

        // ---------- BEGIN: Gun Control ---------

         if (ps2x.Analog(PSS_LY) < 127) {
          Serial.println("Left Y < 128");
          if (gunPosition > 255) {
            gunPosition = 255;
          } else {
            gunPosition = gunPosition + gunIncrement;
            delay(moveDelay);
            servoGun.write(gunPosition);
          }
        }

        if (ps2x.Analog(PSS_LY) > 127) {
          Serial.println("Left Y > 128");
          if (gunPosition < 0) {
            gunPosition = 0;
          } else {
            gunPosition = gunPosition - gunIncrement;
            delay(moveDelay);
            servoGun.write(gunPosition);
          }
        }

          // ---------- END: Gun Control ---------

        if (ps2x.Button(PSB_L1) || ps2x.Button(PSB_R1)) { //print stick values if either is TRUE
          Serial.print("Stick Values:");
          Serial.print("Left Y: ");
          Serial.print(ps2x.Analog(PSS_LY), DEC); //Left stick, Y axis. Other options: LX, RY, RX
          Serial.print(",");
          Serial.print("Left X: ");
          Serial.print(ps2x.Analog(PSS_LX), DEC);
          Serial.print(",");
          Serial.print("Right Y: ");
          Serial.print(ps2x.Analog(PSS_RY), DEC);
          Serial.print(",");
          Serial.print("Right X: ");
          Serial.println(ps2x.Analog(PSS_RX), DEC);
        }

      }

      // ------------- END: Movement Control -------------
      delay(50);
    }
Processing code

Code for the original building pieces.

    /*
      Generic Fablab Mechano interface by Mads Høbye CC:NC-BY-SA

     Todo:
     - Cheatsheet
     - arduino box
     - gear moving parts around(maybe matching the holes)
     - bendable
     - strawbees
     - fingerBox
     - calculate size for objects.
     - update api: 
     -- turn tackylines into a draw module with types of lines.Linetype straight tacky inverted reversed
     -- Move generators into seperate spreadhseet.

     */

    import processing.pdf.*;

    // material thickness - the gridsystem is equal to the thickness of the material


    // the parant mfab class used as a neutral container or canvas. (materialthickness,inset,offset)
    mfab canvas = createCanvas(3.0f, 0.3f, 0.2f, 86, 111, "Rubberband Gun", "Mads Hobye");

    void setup() {
      size(800, 800, P2D );

      setupElements();
    }




    void setupElements()
    {
      setupMFab();
      canvas.x = 4;
      canvas.y = 4;
      mfab servoPiece = canvas.addRectPiece(0, 10, canvas.toGrid(60)+1, canvas.toGrid(30)+3, "Servo hole");
      servoPiece.addServoHole(3, 2);
      servoPiece.bottom.lType = LTTACKY;

      mfab servoPiece2 = canvas.addRectPiece(0, 26, canvas.toGrid(60)+1, canvas.toGrid(30), "Servo hole");
      servoPiece2.addServoMount(9, 7);
      servoPiece2.addMountHoleRow(1, 1, canvas.toGrid(60), 0);

      mfab servoGun = canvas.addRectPiece(66, 41, canvas.toGrid(60)+50, 10, "Servo gun");
      servoGun.rotation = 90;
      mfab servoHole = servoGun.addServoHole(25, 8.5);
      servoHole.rotation = 180;
      servoGun.addServoMount(4, 6);
      servoGun.right.lType = LTINVERSED;
      servoGun.right.rotation = 90+40;
      servoGun.right.length = 13;
      servoGun.bottom.length = 63;
      servoGun.bottom.rotation = 0;
      servoGun.bottom.x = 0;


      canvas.addServoMount(75,48);
      canvas.addPopCircle(75, 48, 7);
      canvas.addServoMount(75,57);
      canvas.addPopCircle(75, 57, 7);
      canvas.addServoMount(75,67);
      canvas.addPopCircle(75, 67, 10);
      canvas.addServoMount(75,78);
      canvas.addPopCircle(75, 78, 10);

      mfab rubberbandGear = canvas.addPolygon(75,27, 3,10,LTTACKY);
      mfab servoMount =  rubberbandGear.addServoMount(-1.5, 4.5);
      mfab servoTower = generateInsetBox(23,10,21,13,13,canvas);
      servoTower.left.x -= 20;
      servoTower.right.x -= 20;
      servoTower.top.addServoHole(4,3);
      servoTower.bottom.x =0;
      servoTower.bottom.y = 55;
      servoTower.bottom.remove(0);
      servoTower.bottom.remove(0);
      servoTower.bottom.remove(0);
      servoTower.bottom.remove(0);
      servoTower.bottom.child(0).rotation = 45;
      servoTower.bottom.child(0).x = 12;
      servoTower.bottom.child(0).y -= 5;
      servoTower.bottom.addRectPiece(-20,-20,50,40,"Base"); 
    }

    void draw() {
      drawMFab();
    }
Share on : Twitter, Facebook or Google+