Claw machine controller on an Arduino Uno
Move a two-motor gantry with the joystick, then press Drop to lower, grab, lift and release with a winch motor and servo. The whole build, an Arduino Uno and 8 more parts, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.
AdvancedRuns in your browser. Free, and no account needed.
The code
The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.
// Claw machine controller: the working control electronics inside the cabinet.
//
// Drag the joystick to move the X and Y gantry motors. Press the blue arcade
// button, or press the joystick itself, to run one complete grab cycle:
// lower the winch, close the claw, lift, then release. The three motor shafts
// and the servo horn show the machine responding while Serial names each state.
const int DROP_BUTTON = 2;
const int X_ENABLE = 3;
const int X_A = 4;
const int X_B = 5;
const int Y_ENABLE = 6;
const int Y_A = 7;
const int Y_B = 8;
const int Z_ENABLE = 9;
const int Z_A = 10;
const int Z_B = 11;
const int CLAW_SERVO = 12;
const int JOYSTICK_X = A0;
const int JOYSTICK_Y = A1;
const int DEAD_ZONE = 140;
enum GrabState { READY, LOWERING, CLOSING, LIFTING, RELEASING };
GrabState state = READY;
unsigned long stateStarted = 0;
unsigned long lastServoFrame = 0;
int clawAngle = 35;
void motor(int enable, int a, int b, int speed) {
if (speed > 0) {
digitalWrite(a, HIGH);
digitalWrite(b, LOW);
analogWrite(enable, speed);
} else if (speed < 0) {
digitalWrite(a, LOW);
digitalWrite(b, HIGH);
analogWrite(enable, -speed);
} else {
analogWrite(enable, 0);
digitalWrite(a, LOW);
digitalWrite(b, LOW);
}
}
int axisSpeed(int reading) {
int offset = reading - 512;
if (offset > -DEAD_ZONE && offset < DEAD_ZONE) return 0;
int magnitude = offset < 0 ? -offset : offset;
int speed = map(magnitude, DEAD_ZONE, 512, 90, 255);
if (speed > 255) speed = 255;
return offset < 0 ? -speed : speed;
}
void servoFrame() {
unsigned long now = micros();
if (now - lastServoFrame < 20000) return;
lastServoFrame = now;
int pulse = map(clawAngle, 0, 180, 1000, 2000);
digitalWrite(CLAW_SERVO, HIGH);
delayMicroseconds(pulse);
digitalWrite(CLAW_SERVO, LOW);
}
void enter(GrabState next, const char *message) {
state = next;
stateStarted = millis();
Serial.println(message);
}
void setup() {
pinMode(DROP_BUTTON, INPUT_PULLUP);
for (int pin = X_ENABLE; pin <= CLAW_SERVO; pin++) pinMode(pin, OUTPUT);
motor(X_ENABLE, X_A, X_B, 0);
motor(Y_ENABLE, Y_A, Y_B, 0);
motor(Z_ENABLE, Z_A, Z_B, 0);
Serial.begin(115200);
Serial.println("Claw ready: move the stick, then press Drop");
}
void loop() {
servoFrame();
unsigned long elapsed = millis() - stateStarted;
if (state == READY) {
motor(X_ENABLE, X_A, X_B, axisSpeed(analogRead(JOYSTICK_X)));
motor(Y_ENABLE, Y_A, Y_B, axisSpeed(analogRead(JOYSTICK_Y)));
motor(Z_ENABLE, Z_A, Z_B, 0);
clawAngle = 35;
if (digitalRead(DROP_BUTTON) == LOW) {
motor(X_ENABLE, X_A, X_B, 0);
motor(Y_ENABLE, Y_A, Y_B, 0);
enter(LOWERING, "1/4 lowering claw");
}
} else if (state == LOWERING) {
motor(Z_ENABLE, Z_A, Z_B, 210);
if (elapsed >= 1400) {
motor(Z_ENABLE, Z_A, Z_B, 0);
clawAngle = 135;
enter(CLOSING, "2/4 claw closed");
}
} else if (state == CLOSING) {
if (elapsed >= 700) enter(LIFTING, "3/4 lifting prize");
} else if (state == LIFTING) {
motor(Z_ENABLE, Z_A, Z_B, -210);
if (elapsed >= 1400) {
motor(Z_ENABLE, Z_A, Z_B, 0);
clawAngle = 35;
enter(RELEASING, "4/4 prize released");
}
} else if (elapsed >= 800 && digitalRead(DROP_BUTTON) == HIGH) {
enter(READY, "Claw ready");
}
}
Parts list
10 parts, plus the jumper wires. Every one is in the editor's parts bin.
- 1 × Arduino Uno R3
- 1 × Full-size breadboard
- 2 × Motor driver, L293D
- 1 × Arcade button
- 3 × DC motor
- 1 × Thumb stick
- 1 × Hobby servo
How it is wired
21 connections, pin by pin, read from the circuit itself. Each line is one set of pins joined together, by a jumper wire or a breadboard strip.
- Arduino Uno R3 pin 12; Hobby servo pin PWM
- Arduino Uno R3 pin 11; Motor driver, L293D (2) pin IN2
- Arduino Uno R3 pin 10; Motor driver, L293D (2) pin IN1
- Arduino Uno R3 pin 9; Motor driver, L293D (2) pin EN12
- Arduino Uno R3 pin 8; Motor driver, L293D (1) pin IN4
- Arduino Uno R3 pin 7; Motor driver, L293D (1) pin IN3
- Arduino Uno R3 pin 6; Motor driver, L293D (1) pin EN34
- Arduino Uno R3 pin 5; Motor driver, L293D (1) pin IN2
- Arduino Uno R3 pin 4; Motor driver, L293D (1) pin IN1
- Arduino Uno R3 pin 3; Motor driver, L293D (1) pin EN12
- Arduino Uno R3 pin 2; Arcade button pin 2; Thumb stick pin SW
- Arduino Uno R3 pin 5V; Motor driver, L293D (1) pin VS; Motor driver, L293D (1) pin VSS; Motor driver, L293D (2) pin VS; Motor driver, L293D (2) pin VSS; Thumb stick pin VCC; Hobby servo pin VCC
- Ground: Arduino Uno R3 pin GND; Motor driver, L293D (1) pin GND1; Motor driver, L293D (2) pin GND1; Arcade button pin 1; Thumb stick pin GND; Hobby servo pin GND
- Arduino Uno R3 pin A0; Thumb stick pin VRX
- Arduino Uno R3 pin A1; Thumb stick pin VRY
- Motor driver, L293D (1) pin OUT1; DC motor (1) pin 1
- Motor driver, L293D (1) pin OUT2; DC motor (1) pin 2
- Motor driver, L293D (1) pin OUT3; DC motor (2) pin 1
- Motor driver, L293D (1) pin OUT4; DC motor (2) pin 2
- Motor driver, L293D (2) pin OUT1; DC motor (3) pin 1
- Motor driver, L293D (2) pin OUT2; DC motor (3) pin 2
Change it and keep it
Open it in the editor, change the circuit or the code, and keep your version in a free account.