Introduction: ITTT Robot Arm Arcade Game

This is an instructable for a installation I made for a school project. I wasn't able to completely finish this project and there were some minor issues with the final. I will describe them in the steps but I just want you to know that this is not a finished project.

The idea was to create a game featuring a robot arm that can be controlled by three rotating knobs. Around the robot is a dome with multiple LED lights that can be turned on independently. The goal of the game is to move the robot arm towards the LEDs that are turned on. I haven't got the time to finish the LEDs in the dome so I also haven't completed the gameplay yet.

This instructable will explain what parts I used to create this installation, the lasercut files, the arduino code and I'll explain the issues that will need to be fixed to complete this project.

Step 1: Parts

These are the parts I used for my current installation:

  • Arduino Yún
  • 2 micro servo motors
  • 1 5v stepper motor (28BYJ-48)
  • ULN2003 stepper motor driver
  • 3 Rotary encoders (24 step) with scrubber knobs
  • Breadboard & Jumper wires
  • Bolts and nuts M3 (3mm diameter), approximately these sizes:
    • 4x 20mm
    • 10x 12mm
  • 4mm plywood. I used 4 pieces of around 600x400 mm.
  • Wire for the dome, but I'll come back to this in a later step.

To complete the dome you would need 16 LED lights and possibly some chip to get more pins on your arduino.

Step 2: Lasercut

The first thing you will need to do is to lasercut all of the elements. These are the files to create the parts I used for my prototype. The robot is based on this robotarm. My version uses a stepper motor for the rotation of the top part. It is made in such a way that the robotarm head is always in a same distant from the dome and you will need to use all knobs to get to all parts of the dome. This is deliberately an impractical way to create a robotarm, but this will increases the gameplay.

These are my lasercut files:

Robotarm lasercut file (ai)

Ground plane lasercut file (ai)

Step 3: Robot Base

Attach the servo to the robot base with two bolts. Make sure the bolts are tight enough so the servo can't move, but not too tight or the part around the servo will break.

Next, use the longer bolts to connect the two base parts. You can adjust the nuts to level the platform.

Step 4: Robot Middle

First connect the servo to the side panel. Then screw the servo top to the square bottom piece. The robotarm I based my robot upon actually uses 3mm acryl so you will probably need to carve in the wood a bit to ensure the part will attach to the servo properly. Next attach the other parts to the base and fix them using bolts and nuts. There probably are multiple ways to attach the pieces together so I'm sure you will find an order that works!

Step 5: ​Robotarm

Bolt the first arm piece to the servo. Again you probably have to carve in the wood a bit. Attach the second arm piece to the opposite side of the base. I used a bolt that was long enough to reach the other arm piece. Without this bolt the arm sometimes fell of the servo.

Attach the stepper motor to the two pieces. Next slide the motor over the arms. I used a small screw through the arm without servo to fix this arm to the motor. Without this screw the arm was to loose and the arm was not moving along properly.

Step 6: ​Robot Top

The parts for the top piece were very loose so I glued them all together. The small square part is the bottom part that will fit over the servo motor. Add the sides and the small rectangular parts. Finally glue the circular part to the top of the arm but make sure the holes remain open.

The top arm should slide in the top an do not need to be glued. Bolt the two arms and the small rectangle together at the end of the arm. You can use part to get the arm as close as possible to the dome.

Add the top part to the robot arm and then slide the entire top through the hole and on top of the servo. These parts should stay in place without glue. (I'm sorry but I don't have any better pictures of this at the moment).

Step 7: Control Box

Bolt the first side to the front and backpanel of the box. Add the part for the rotary encoders and then bolt the other side in place. Attach the rotary encoders to the box and then place the top piece. Again you might have to carve in the piece for the rotary encoders to make them fit through the holes. A 3mm version would be much better but all my files are made for 4mm plywood right now. Finally add the scrubber knobs to the rotary encoders and the top part should be locked in place too.

Step 8: ​Dome

As I mentioned in the requirements list I used welding wire and soldered them together to make the dome. However this wire is very hard to solder and the weird angles of the dome aren't helping. Therefore I would probably try something else if I had to make this again. I'll just describe the way to construct the dome here.

You will need 35 'wires' with a length of 111 mm and 30 'wires' with a length of 98 mm. The best way to start is probably by creating the base ring. This is created by 10 wires of 111 mm all at the same angle (36 degree). Starting with this ring makes it easier to get a full dome in the end. Next create the top part using 5 longer pieces to create the ring and 5 smaller pieces going from every corner towards the center. The top should be approximately 2 cm higher than the ring.

The side of the dome can be seen as 5 more of the same pieces as the top piece. I created them by first creating the crosses with the longer pieces and then soldering them between the top and the base ring. After that I used the other smaller pieces to fill up the dome.

Step 9: ​Ground Plane

The ground plane consists of three parts. The top part was cut in half because it didn't fit in whole on my plane. This turned out to be helpfull as it became easier to run the wires through the holes in the top plane. The small parts are used to create the columns that support the dome. These are very unstable so you might want to glue them in place. In my case the whole thing became stronger under the weight of the dome but almost every time I removed the dome I had to replace some columns.

Step 10: Wiring

Without the LEDs you won't need any resistors for this installation so connecting everything to the arduino should be simple. I only used the breadboard to connect all ground and 5v wires.

Place the robot on top of the base servo and let all of the wires go through the hole in the bottom. Than place the robot in the middle of the ground plane.

In my code I used 1 interupt pin for every rorary encoder. These are pins 2, 3 and 7 for the arduino yun. It makes a difference which pin is connected to the interupt pin so if the knobs aren't working properly you might have to connect them the other way. The middle pin of each rotary encoder should be connected to the ground. Using this code the left encoder should be connected to pins 2 and 4, the middle one to pins 3 and 12 and the right one to pins 7 and 13.

The servo for the base should be connected to pin 6, and the one for the arm to pin 5. The other wires from the servo also go to the breadboard. Finally the stepper motor is connected to the driver chip. This chip is connected with a 5v and a ground wire to the breadboard. IN1 to IN4 is connected to pins 8 to 11. You might have to change the order in which the pins are placed if the motor doesn't move.

I was hoping that both the breadboard and arduino could fit within the box of the knobs but both of them don't fit. I was able to get the breadboard inside by putting it on its side. I just left the arduino next to the box.

Step 11: Arduino Code


Servo armServo; Servo baseServo;

//declare variables for the motor pins int motorPin1 = 8; // IN 1 int motorPin2 = 9; // IN 2 int motorPin3 = 10; // In 3 int motorPin4 = 11; // IN 4

int motorSpeed = 6000; //variable to set stepper speed // Experiment with this; too small will not work. int count = 0; // count of steps made int countsperrev = 68; // number of steps per revolution for this motor

int lookup[8] = {B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001};

int motorPos = 0; // Used to keep track of the motor

//declare variables for the rotary encoders int encPins[] = {2, 3, 7, 4, 12, 13};

volatile int lastEncoded[] = {0, 0, 0}; volatile long encoderValue[] = {90, 180, 0};

void setup() { baseServo.attach(6); armServo.attach(5); //declare the motor pins as outputs pinMode(motorPin1, OUTPUT); pinMode(motorPin2, OUTPUT); pinMode(motorPin3, OUTPUT); pinMode(motorPin4, OUTPUT); Serial.begin(9600);

//declaring rotary encoder pins for (int i=0; i < 6; i++){ pinMode(encPins[i], INPUT); digitalWrite(encPins[i], HIGH); //turn pullup resistor on };

//call updateEncoder() when any high/low changed seen //on interrupt 0 (pin 3), interrupt 1 (pin 2) or interupt 4 (pin 7) attachInterrupt(1, update1, CHANGE); attachInterrupt(0, update2, CHANGE); attachInterrupt(4, update3, CHANGE);


void loop() { //check first rotary encoder and update base servo. if(encoderValue[0] < 0) encoderValue[0] = 0; if(encoderValue[0] > 180) encoderValue[0] = 180; baseServo.write(encoderValue[0]);

//check second rotary encoder and update arm servo. if(encoderValue[1] < 90) encoderValue[1] = 90; if(encoderValue[1] > 270) encoderValue[1] = 270; armServo.write(int(encoderValue[1]/2));

//check last rotary encoder and adjust motor position if its lower than the rotary encoder position. This way it will only move one step each loop. if(motorPos < int(encoderValue[2]/4)){ motorPos++; clockwise(); } else if(motorPos > int(encoderValue[2]/4)){ motorPos--; anticlockwise(); } //Delay if the delay of the steppermotor is not used. else{ delay(15); }


///// //set pins to ULN2003 high in sequence from 1 to 4 //delay "motorSpeed" between each pin setting (to determine speed) ///// void anticlockwise() { for(int i = 0; i < 8; i++) { setOutput(i); delayMicroseconds(motorSpeed); } }

void clockwise() { for(int i = 7; i >= 0; i--) { setOutput(i); delayMicroseconds(motorSpeed); } }

void setOutput(int out) { digitalWrite(motorPin1, bitRead(lookup[out], 0)); digitalWrite(motorPin2, bitRead(lookup[out], 1)); digitalWrite(motorPin3, bitRead(lookup[out], 2)); digitalWrite(motorPin4, bitRead(lookup[out], 3)); }

///// //Rotary encoder interupt functions /////

void update1() { updateEncoder(0); }

void update2() { updateEncoder(1); }

void update3() { updateEncoder(2); }

void updateEncoder(int p){ int MSB = digitalRead(encPins[p]); //MSB = most significant bit int LSB = digitalRead(encPins[p+3]); //LSB = least significant bit

if(MSB == LSB){ encoderValue[p] ++; } else { encoderValue[p] --; }