Arms

Prerequisites

It is recommended that you read through the servo programming guide before reading this one; that guide explains conditionals and joystick buttons, which will be used in this guide.

Hardware Setup

For this guide, we will be programming a DC motor to control an arm-like mechanism, like on this Pushbot from the FIRST guides:

A DC Motor is used instead of a servo because servos typically do not have enough power to lift mechanisms that are this large.

If you are using Java, this is starting hardware configuration code you will need. Replace “MyOpNodeName” with your OpMode’s name:

import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
import com.qualcomm.robotcore.hardware.DcMotor;
@TeleOp(name="MyOpNodeName")
public class MyOpNodeName extends LinearOpMode {
    private DcMotor arm;

    @Override
    public void runOpMode() {
        // Put initialization blocks here.
        arm = hardwareMap.dcMotor.get("arm");
        waitForStart();
        // Put run blocks here.
        while(opModeIsActive()) {
            //Loop code will go here
        }
    }
}

Moving the Arm

Moving the arm will be very similar to how we moved our claw in the servo programming guide: by using joystick buttons and a conditional statement. 

For this guide, let’s say we want to move our arm up when we hold the X button on the gamepad and move our arm down when we hold the Y button on the gamepad. At first, it seems like we can code this the same way we coded the servo in the previous guide. Add this code to the loop section of your program, but DO NOT RUN IT; there is a fatal flaw in the code:

if (gamepad1.x) { arm.setPower(0.5); } else if (gamepad1.y) { arm.setPower(-0.5); }
If you are using Blocks, the block structure for the conditional (the “if do”) is under the Logic section of the toolbar.

(Note: I used 0.5 (50%) as my power values, but you can use any value you want. You may have to make it higher or lower depending on the weight of your robot’s arm)

In this code, if the driver presses X, then the arm will start moving forward. Else, if the driver presses Y, then the arm will start moving backwards. However, currently, our code contains no way to stop the arm! This is something you always have to keep in mind when controlling motors opposed to angular servos: angular servos will move to a position and stay there, but motors will continue moving until you tell them to stop.

To fix this issue, let’s add a final “else” portion to our conditional statement that stops the arm if neither the X button nor the Y button are being pressed:

if (gamepad1.x) { arm.setPower(0.5); } else if (gamepad1.y) { arm.setPower(-0.5); } else { arm.setPower(0); }
If you are using Blocks, to add an “else” portion to the conditional (the “if do”) click the gear icon on the conditional. This will bring up a small window with a menu on the left and with some blocks on the right. The blocks on the right represent the structure of your conditional. Grab the “else” block from the menu and place it under the “else if” block in the conditional structure. Click the gear again to close this window.

Now, the arm will stop if we don’t hold any buttons on the gamepad, so this code is safe to run.

The Full Code

import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
import com.qualcomm.robotcore.hardware.DcMotor;

@TeleOp(name="MyOpModeName")
public class MyOpModeName extends LinearOpMode {
  private DcMotor arm;

  @Override
  public void runOpMode() {
    arm = hardwareMap.dcMotor.get("arm");

    // Put initialization blocks here.
    waitForStart();
    if (opModeIsActive()) {
      // Put run blocks here.
      while (opModeIsActive()) {
        // Put loop blocks here.
        if (gamepad1.x) {
          arm.setPower(0.5);
        } else if (gamepad1.y) {
          arm.setPower(-0.5);
        } else {
          arm.setPower(0);
        }
        telemetry.update();
      }
    }
  }
}