The “Grab-it” 5-axis robot arm from JOY-IT is perfect for hobbyists, schoolchildren and students looking to take their first steps into the world of electronics, mechanics and programming. Since all standard single-board computers (SBCs) and microcontrollers are compatible, you are not restricted to a particular platform and can begin working quickly. In this example, we will focus on the Raspberry Pi Model 4 with a Moto Pi and the Arduino Uno with a Motorino. Thanks to the high-torque servo motors and powerful gripper, small loads can easily be grasped and moved from A to B.
Assembly and calibration of the motors
The Grab-it robot arm kit comes in a practical, multipurpose case containing:- Aluminium robot arm, serial number: Robot02
- Raspberry Pi Model 4 with 2 GB and power supply
- Moto Pi for controlling the servos
- 20 W power supply for the control board
- Memory card with NOOBS, tools and instructions
- 1.5 m HDMI cable (HDMI Micro > HDMI) for 4K playback
The robot arm is compatible with the following motors:
- Torque: 21.5 kg·cm at 7.4 V
- Voltage: 5–7.4 V DC
- 360° mechanical angle and 180° working range
- Metal gearbox
- Control via pulse width modulation (PWM)
Recommended additional accessories:
- Arduino UNO R3
- JOY-IT Motorino: motor control for Arduino
- HDMI cable
- Raspberry Pi USB-C to USB cable with switch
- Cable set for breadboards
The aluminium robot arm is moved by six motors that can be controlled separately and is mounted on a rotating turntable (360°). The 4.5 mm thick acrylic base plate is equipped with mounting holes for all common SBCs and microcontrollers. Spacers allow the base plate to be easily attached to surfaces such as workbenches or desks.

Safety instructions
- Stable, level surface required – screw base plate securely in place if necessary.
- Check correct mains voltage; no deviations!
- Disconnect power supply before maintenance or installation work.
- Protect device from moisture, rain and wet conditions.
- Do not block motors; keep hands and objects away from the working area.
- Never point at or reach for people or animals.
- Keep small parts (screws, nuts, etc.) in a safe place – risk of swallowing!
- Only operate when fully assembled.
- Pay attention during assembly and operation – always keep an eye on your fingers.
- Protective gloves and safety goggles are recommended (risk of injury from sharp edges).
- Do not reach into drives or open components.
- Do not place metal objects on open conductor tracks (risk of short circuit).
- Check screws and nuts regularly (vibrations can loosen them); use screw lock if necessary.
- Install emergency stop switches in an easily accessible location.
- Use a powerful power supply unit:
- Each motor up to 2 A, total requirement max. 12 A
- Mobile phone power supplies are unsuitable
- Overloading can lead to overheating or hardware damage
Step-by-step assembly and calibration of the motors
The following items are required for assembly:
- Assembly materials: Phillips screwdriver, flat-nose pliers, Allen key (included), tweezers (if necessary)
- laptop and Raspberry Pi with Moto Pi or Arduino with Motorino for calibrating the motors
- Assembly instructions from JOY-IT


Assembly instructions:
- Remove the film from the base plate.
- Attach one of the round servo levers to one of the round plates using four screws.
- Next, mount a servo motor onto the plate. Place the plate on the servo and secure it with four screws and nuts. Ensure that the servo gear is aligned exactly in the centre.
- In the fourth step, mount the bearing. Insert the four long screws through the first ring and place the bearing on top. Next, attach the second ring and secure it in place with the four long brass sleeves.
- Place the round plate from step 2 with the servo mount on top of the servo head from step 3, then fasten it in the centre with a screw.
- Finally, place the plate with the servo on the bearing mount and secure it with four nuts (see Figure 03).

- Attach a bearing to the first angle bracket.
- Screw the angle bracket to the round plate.
- Then screw this to the bearing.
- It can then be mounted on the base plate and secured on the underside with brass sleeves. Caution! Ensure that the thread does not protrude from the sleeves and that the nuts are attached to the threaded pins beforehand. These can then be tightened from above. The plastic spacers can now be attached to the underside (Figure 04).
- Finally, attach the servo levers to the remaining servos (Figure 05).


ATTENTION: The servo motors must be calibrated in their basic position before installation! (Instructions below.)
- Screw the two U-plates together using four screws and nuts each.
- Secure the servo with four screws and nuts, then connect the servo arm to the robot arm with four screws (Figure 06).

- Screw another U-plate to an angle bracket and attach it to a servo holder.
- Then attach a bearing to the familiar position.
- Insert a servo motor and fasten it in the usual way with four screws and nuts. Finally, attach the servo motor to the robot arm with four screws.
- Place two servo holders on top of each other and secure them together with screws and nuts.
- Install the bearing and servo motor as usual.
- Attach the last servo to the gripper as usual (Figure 07).

- The robot claw must be assembled. To do this, screw the four claw fingers alternately with the short brass spacers. Nuts are used on one side and screws on the other to secure them in place.
- Then, four brass spacers are attached to the servo. Ensure there is a washer under and above each spacer. Next, insert a screw through the sheet metal and secure it to the servo. Place two washers on the screw.
- Next, insert a bearing into the gripper.
- Attach the first claw to the servo using a washer and a nut.
- For the second claw, attach a servo lever using four screws.
- Attach the second claw and secure it in place with a screw.
- Attach a servo lever to the angle bracket and secure it to the gripper arm with a screw.
- Screw the claw to the angle bracket (see Figure 8).

Calibrating the motors
Before installing and using the servo motors, they must be calibrated in position. This ensures that the entire working range of the robot arm is utilised and that the correct starting position for the Grab-it is obtained. For optimal adjustment, set the motors to a value of 1500. Only the claw motor is programmed to a value of 1600. To calibrate, connect the respective motor to the control unit (e.g. MotoPi with Raspberry Pi or Motorino with Arduino).
- The Raspberry Pi with the MotoPi board attached should then be connected to its power supply (or, alternatively, the Arduino with Motorino).
- Then, connect the external 5V power supply for the servo motors to the MotoPi.
- The ‘calibration script’ is started as described below. (Note: indentations in Python.)
- Now the following steps must now be carried out for each servo motor to be installed:
- Connect the servo motor to its respective position on the MotoPi (see Figure 09).

The modified library is copied to the Raspberry Pi, after which the following commands are executed:
sudo apt-get install python3-pip
sudo apt install python3-smbus
In the terminal, navigate to the folder and install the library with the following command:
sudo python3 setup.py install
Create the new file with the following command:
sudo nano calibrate.py
Write the following code into the file:
from __future__ import division
import time
import Adafruit_PCA9685
# Initialisierung mit alternativer Adresse
pwm = Adafruit_PCA9685.PCA9685(address=0x41)
# Einstellen der Minimal- und Maximal-Pulslaengen
servo_min = 150 # Minimale Pulslaenge
servo_max = 600 # Maximale Pulslaenge
# Hilfsfunktion
def set_servo_pulse(channel, pulse):
pulse_length = 1000000
pulse_length /= 50
print('{0}us per period'.format(pulse_length))
pulse_length /= 4096
print('{0}us per bit'.format(pulse_length))
pulse *= 1000
print(pulse_length)
pulse /= pulse_length
print(pulse)
pulse = round(pulse)
print(pulse)
pulse = int(pulse)
print (pulse)
pwm.set_pwm(channel, 0, pulse)
# Frequenz auf 50Hz setzen
pwm.set_pwm_freq(50)
# Bewege Servo 0-4 auf Position 1500
# Bewege Servo 5 auf Position 1600
set_servo_pulse(0,1.5)
time.sleep(1.5)
set_servo_pulse(1,1.5)
time.sleep(1.5)
set_servo_pulse(2,1.5)
time.sleep(1.5)
set_servo_pulse(3,1.5)
time.sleep(1.5)
set_servo_pulse(4,1.5)
time.sleep(1.5)
set_servo_pulse(5,1.6)
time.sleep(1.5)
Save the file with Ctrl+O and exit the editor with Ctrl+X. Start the calibration with the following command:
sudo python3 calibrate.py

Notes on programming and loading the motors
- When programming, pay attention to the achievable positions; the motor must actually be able to move to the specified position.
- This applies in particular to the claw:
- If it is to close completely, there must be no object in the way. Otherwise, the motor will attempt to reach the position with maximum force and press the object firmly.
- Short-term holding (a few seconds) is harmless, e.g. when transporting an object.
- Avoid prolonged loading, as this can lead to:
- significant heating
- overloading of the gearbox
- possible motor damage
- When selecting accessories (motor control, power supplies, etc.), ensure that there are sufficient power reserves.
- Motor power:
- Operating voltage: 7.4 V DC
- Current consumption: up to 2 A per motor
- Total: 6 motors → up to 12 A total current consumption
Initial movements with the Raspberry Pi and Moto Pi
Installing the Raspberry Pi OS
- Installing the Raspberry Pi OS
- Installing the desired OS (e.g. OS Lite 64 bit)

- Copy the Wi-Fi name and password to the SD card. Copy the route file to the SD card. Insert the SD card into the Pi.
- Start the Pi and run the OS (it starts automatically).
- Copy the library to the Raspberry Pi.
- Create a file.
- Enter the calibration code (as described above).
Pulse width modulation (PWM)
PWM is a method of changing the width of an electrical pulse in order to digitally control analogue values, such as position, speed, or brightness. An Arduino can only output 0 V (LOW) or 5 V (HIGH), not actual intermediate values. With PWM, intermediate values are simulated by switching very quickly between HIGH and LOW.
Servo motors, such as those used in the Grab-it device, do not understand analogue signals; rather, they understand special PWM signals at 50 Hz (i.e. every 20 ms). This means that a control pulse is sent every 20 ms, the length of which indicates the position. The servo measures how long the pulse is high, not how often. There are several ways to generate a PWM signal. The RPi.GPIO and pigpio variants are suitable for Grab-it.
Option 1:
import RPi.GPIO as GPIO
import time
# Pin-Nummer (z. B. GPIO 17)
servo_pin = 17
GPIO.setmode(GPIO.BCM)
GPIO.setup(servo_pin, GPIO.OUT)
# PWM mit 50 Hz (für Servos)
pwm = GPIO.PWM(servo_pin, 50)
pwm.start(0)
def set_angle(angle):
# Umrechnen von Winkel (0–180) auf Duty-Cycle (2–12 %)
duty = 2 + (angle / 18)
GPIO.output(servo_pin, True)
pwm.ChangeDutyCycle(duty)
time.sleep(0.5)
GPIO.output(servo_pin, False)
pwm.ChangeDutyCycle(0)
# Beispielbewegung
try:
set_angle(0)
set_angle(90)
set_angle(180)
finally:
pwm.stop()
GPIO.cleanup()
Option 2:
import pigpio
import time
pi = pigpio.pi()
servo_pin = 17
# Servo auf 90° (1.5 ms)
pi.set_servo_pulsewidth(servo_pin, 1500)
time.sleep(1)
# Servo auf 0°
pi.set_servo_pulsewidth(servo_pin, 1000)
time.sleep(1)
# Servo auf 180°
pi.set_servo_pulsewidth(servo_pin, 2000)
time.sleep(1)
# Servo stoppen
pi.set_servo_pulsewidth(servo_pin, 0)
pi.stop()
Code example: simple movements, gripping, turning
Once the motors have been calibrated to the correct position, the robot arm assembled and all components connected, the arm can be moved for the first time. To do this, simply run the relevant code on the Raspberry Pi. The library should have been copied during calibration. The code for the initial movements can be downloaded here (Figure 12).

Executing this command moves the arm:
sudo python3 RoboterArm.py
An excerpt of the code can be seen below:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import division
import time
import RPi.GPIO as GPIO
import Adafruit_PCA9685
import spidev
import time
import sys
import signal
import logging
# Standardadresse: (0x40).
#pwm = Adafruit_PCA9685.PCA9685()
# Initalisierung mit alternativer Adresse
pwm = Adafruit_PCA9685.PCA9685(address=0x41)
# Einstellen der Minimal- und Maximal-Pulslängen
servo_min = 150 # Minimale Pulslänge
servo_max = 600 # Maximale Pulslänge
# Hilfsfunktion
def set_servo_pulse(channel, pulse):
pulse_length = 1000000
pulse_length /= 50
pulse_length /= 4096
pulse *= 1000
pulse /= pulse_length
pulse = round(pulse)
pulse = int(pulse)
pwm.set_pwm(channel, 0, pulse)
Alternative control with Arduino
Connection & cabling with the Motorino
The JOY-IT Motorino Shield is a plug-in board (‘shield’) for the Arduino Uno. It serves as an alternative to the Raspberry Pi and Moto Pi combination and includes:
- 6 servo connections for your robot arm
- an additional power supply for servos (up to 12 A)
- Button, LED and sensor connections
Procedure:
- Plug in the shield
- Connect the servos
- Connect the power supply
- Connect the Arduino to the PC
- Optional: Connect the LED and button connections
Sample code using the Servo.h library:
Mit folgendem Code können wir den Grab-it – ähnlich wie im Codebeispiel für den Pi – erste Bewegungen ausführen lassen.
#include <Servo.h> // Standardbibliothek zur Ansteuerung von Servomotoren
// === Servo-Objekte für die 6 Motoren des Grab-it Roboterarms ===
Servo baseServo; // Dreht den Arm (Basis)
Servo shoulderServo; // Schultergelenk
Servo elbowServo; // Ellbogengelenk
Servo wristServo; // Handgelenk
Servo clawServo; // Greifklaue
Servo wristRotateServo;// Drehung des Handgelenks
// === Pinbelegung (Motorino Shield oder direkt am Arduino) ===
// Passen Sie die Pins ggf. an Ihre Verkabelung an
const int BASE_PIN = 2;
const int SHOULDER_PIN = 3;
const int ELBOW_PIN = 4;
const int WRIST_PIN = 5;
const int CLAW_PIN = 6;
const int WRIST_ROT_PIN = 7;
// === Anfangspositionen (in Grad) ===
int basePos = 90;
int shoulderPos = 90;
int elbowPos = 90;
int wristPos = 90;
int clawPos = 90;
int wristRotatePos = 90;
// === Setup ===
void setup() {
// Servos mit Pins verbinden
baseServo.attach(BASE_PIN);
shoulderServo.attach(SHOULDER_PIN);
elbowServo.attach(ELBOW_PIN);
wristServo.attach(WRIST_PIN);
clawServo.attach(CLAW_PIN);
wristRotateServo.attach(WRIST_ROT_PIN);
// Servos auf Ausgangsposition fahren
baseServo.write(basePos);
shoulderServo.write(shoulderPos);
elbowServo.write(elbowPos);
wristServo.write(wristPos);
clawServo.write(clawPos);
wristRotateServo.write(wristRotatePos);
delay(1000); // kurze Pause zum Stabilisieren
}
// === Hauptprogramm ===
void loop() {
// Beispielbewegung 1: Objekt greifen und bewegen
moveClaw(60); // Klaue öffnen
delay(500);
moveBase(120); // Arm nach rechts drehen
delay(500);
moveShoulder(70); // Arm absenken
delay(500);
moveClaw(100); // Klaue schließen (Objekt greifen)
delay(1000);
moveShoulder(90); // Arm anheben
delay(500);
moveBase(60); // Arm nach links drehen
delay(500);
moveClaw(60); // Klaue öffnen (Objekt ablegen)
delay(1000);
}
// === Hilfsfunktionen ===
void moveBase(int pos) {
pos = constrain(pos, 0, 180);
baseServo.write(pos);
}
void moveShoulder(int pos) {
pos = constrain(pos, 0, 180);
shoulderServo.write(pos);
}
void moveElbow(int pos) {
pos = constrain(pos, 0, 180);
elbowServo.write(pos);
}
void moveWrist(int pos) {
pos = constrain(pos, 0, 180);
wristServo.write(pos);
}
void moveWristRotate(int pos) {
pos = constrain(pos, 0, 180);
wristRotateServo.write(pos);
}
void moveClaw(int pos) {
pos = constrain(pos, 50, 120); // Begrenzung, um Überlast zu vermeiden
clawServo.write(pos);
}
Potentiometersteuerung oder einfache Buttonsteuerung
Servo über Potentiometer steuern:
#include <Servo.h>
Servo servo1;
const int potPin = A0; // Potentiometer an analogem Pin A0
const int servoPin = 2; // Servo-Signal an D2
void setup() {
servo1.attach(servoPin);
}
void loop() {
int sensorValue = analogRead(potPin); // 0–1023 lesen
int angle = map(sensorValue, 0, 1023, 0, 180); // in 0–180° umrechnen
servo1.write(angle); // Servo auf Winkel setzen
delay(10);
}
Servos über 2 Buttons steuern:
#include <Servo.h>
Servo servo1;
const int buttonLeft = 7;
const int buttonRight = 8;
const int servoPin = 2;
int angle = 90; // Startposition
void setup() {
servo1.attach(servoPin);
servo1.write(angle);
pinMode(buttonLeft, INPUT_PULLUP);
pinMode(buttonRight, INPUT_PULLUP);
}
void loop() {
// Button gedrückt = LOW (wegen INPUT_PULLUP)
if (digitalRead(buttonLeft) == LOW) {
angle--; // Winkel verringern
angle = constrain(angle, 0, 180);
servo1.write(angle);
delay(100);
}
if (digitalRead(buttonRight) == LOW) {
angle++; // Winkel erhöhen
angle = constrain(angle, 0, 180);
servo1.write(angle);
delay(100);
}
}
Simple control via potentiometers or buttons
Potentiometers or buttons are a great way to control the robot arm easily and precisely:
Buttons
Each button triggers a single action:
- Move servo left/right
- Open/close gripper
- Save/recall position
- Start automatic routine
Potentiometers
A potentiometer provides an analogue value that is converted proportionally into a servo angle:
- Potentiometer left → small servo angle
- Potentiometer right → large servo angle
Potentiometers enable fine manual control of each axis.
To control with buttons, you need two to six buttons depending on the desired axis control, as well as pull-down resistors, cables and a breadboard to connect the buttons.
You can use simple rotary potentiometers for the potentiometers, for example one per servo axis. Since the Raspberry Pi cannot process analogue inputs, you must also use an ADC converter to convert the input signals.
An example of the code for simple button control is shown below:
import RPi.GPIO as GPIO
import time
from adafruit_pca9685 import PCA9685
import busio, board
# PCA9685 Setup
i2c = busio.I2C(board.SCL, board.SDA)
pca = PCA9685(i2c)
pca.frequency = 50
def set_servo(channel, angle):
pulse = int(150 + (angle / 180) * 450)
pca.channels[channel].duty_cycle = pulse
GPIO.setmode(GPIO.BCM)
BTN_LEFT = 17
BTN_RIGHT = 27
GPIO.setup(BTN_LEFT, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(BTN_RIGHT, GPIO.IN, pull_up_down=GPIO.PUD_UP)
angle = 90
while True:
if GPIO.input(BTN_LEFT) == 0:
angle = max(0, angle - 5)
set_servo(0, angle)
time.sleep(0.1)
if GPIO.input(BTN_RIGHT) == 0:
angle = min(180, angle + 5)
set_servo(0, angle)
time.sleep(0.1)
Differences from the Pi variant
- The Arduino works directly with PWM hardware, generating the servo control signals itself and reacting in real time — ideal for precise movements.
- In contrast, the Raspberry Pi is a fully-fledged computer that generates PWM signals via software or an external module, such as the PCA9685.
- The Arduino runs ‘stand-alone’ without an operating system, and the code starts immediately upon switching on.
- The Raspberry Pi allows more complex programmes to be run via Python, AI and camera control, but precise timing support is required.
- The Motorino Shield fits directly onto the Arduino, whereas the Pi is usually connected to the servos via I²C (PCA9685).
From construction to control: the next step
The Grab-it robot arm is ideal for implementing initial projects with the Raspberry Pi or Arduino. Controlling and operating the servo motors is a particularly exciting aspect of this project, which receives special attention. In the first part, we got the Grab-it to perform its first movements. The second part of this article presents exciting project ideas and shows how to program a web interface for controlling the robot arm via a PC or smartphone.
Images: reichelt elektronik, JOY-IT, Adobe Stock
To the second part of the article:
Examples & Extensions: Enter the world of robotics with Grab-it – Part 2












