Skip to the content
4 layers99 × 84 mmRobotic arm controller, the printed circuit board in 3D

Traditional servo controllers simply send PWM signals. This board goes further:

Size
99 × 84 mm
Copper layers
4
Thickness
1.6 mm
Parts
140
Nets
117
Pads
503
Tracks, vias
1,019, 515
Pours
26
Routed
Yes
KiCad
KiCad 9.0 (file 20241229)
Created
10 Apr 2026
Updated
11 Apr 2026

Overview

Robotic arm controller is an open-source printed circuit board by bejaouihamza, from the bejaouihamza/robotic_arm_controller repository on GitHub. It is a 4-layer board of 99 × 84 mm with 140 parts on 117 nets, routed with 1,019 tracks and 515 vias.

It is built around the RP2040, LM2596S-5.0 and W25Q16JVSSIQ, with the 74HC4051, AMS1117-3.3 and USBLC6-2SC6 among its other parts. Its parts include 38 resistors, 33 capacitors, 18 ICs, 11 connectors and 9 diodes. It belongs with the RP2040 boards of this library.

Main components

8

README

README.md

🦾 6-Axis Robotic Arm Controller — RP2040

A high-performance embedded controller for 6-axis robotic arms featuring PIO-based jitter-free PWM, per-channel current sensing, real-time torque estimation, and hardware-level collision detection — no external sensors required.

License MCU Axes PCB Lang


📸 PCB Renders

3D RenderPCB LayoutSchematic
3D RenderPCB LayoutSchematic

⚡ Key Specs

ParameterValue
MCURaspberry Pi RP2040 — Dual-core ARM Cortex-M0+ @ 133 MHz
Flash16MB W25Q16JV55 QSPI
Servo Channels6 independent, PIO-generated PWM
PWM Frequency50 Hz · 500–2500 µs pulse range
PWM Jitter< 1 µs (PIO hardware, zero CPU involvement)
Current SensePer-channel INA180 amplifier (×20 gain, 10 mΩ shunt)
Peak Current10A total across all 6 channels
Input Voltage6V – 24V VIN + USB-C 5V
PCB4-Layer, KiCad
FirmwareMicroPython · C++ Pico SDK
LicenseCERN Open Hardware License v2

🧠 Core Concept

Traditional servo controllers simply send PWM signals. This board goes further:

text
MEASURE  →  ANALYZE  →  REACT

Every servo channel has a dedicated current sense amplifier. The RP2040 reads all six channels through a 74HC4051 analog multiplexer, continuously estimating torque, detecting collisions, and triggering per-channel shutdowns — all in real time.


🔩 Hardware & Components

Processing Unit

  • RP2040 — Dual-core ARM Cortex-M0+ @ 133 MHz, 264KB SRAM, 8 PIO state machines
  • W25Q16JV55 — 16MB QSPI Flash for firmware and data logging
  • 12 MHz Crystal — Stable PLL reference for USB timing and precise PWM periods

Power Management

  • Integrated 5V Buck Converter — Logic supply and low-power servo rail
  • AMS1117-3.3 — Clean LDO for MCU and all analog circuitry
  • Auto power-path — Seamless switching between USB-C (5V) and external VIN (6–24V)

Servo Driver Block (×6 channels)

  • AO3401A P-MOSFET — High-side switch per channel. Enables software-controlled power sequencing and instant per-joint emergency stops
  • INA180A1 — Current sense amplifier, gain ×20. Amplifies shunt voltage for ADC reading
  • 10 mΩ Shunt Resistor — In-series with each servo rail for current measurement

Analog Signal Chain

  • 74HC4051 — 8:1 CMOS analog multiplexer. Funnels all 6 current sense signals into a single ADC pin using only 3 GPIO select lines
  • JP1–JP6 Jumpers — Per-channel voltage selection: position A = 5V buck, position B = direct VIN

User Interface

  • RV1, RV2 — 10kΩ potentiometers mapped to Joint 1 & 2 for manual testing
  • D3 — User-programmable LED
  • Reset button — Hardware reset
  • SWD header — ARM Serial Wire Debug (J-Link / DAPLink / OpenOCD)

🔌 GPIO Pin Mapping

GPIO 0–5 → Servo Enable (P-MOS high-side switches)
GPIO 6–11 → Servo PWM (PIO state machine outputs)

GPIONet NameTypeConnected ToDescription
GPIO 0servo1_ENGPIO OUTAO3401A Gate Ch1High-side MOSFET enable — active HIGH
GPIO 1servo2_ENGPIO OUTAO3401A Gate Ch2High-side MOSFET enable — active HIGH
GPIO 2servo3_ENGPIO OUTAO3401A Gate Ch3High-side MOSFET enable — active HIGH
GPIO 3servo4_ENGPIO OUTAO3401A Gate Ch4High-side MOSFET enable — active HIGH
GPIO 4servo5_ENGPIO OUTAO3401A Gate Ch5High-side MOSFET enable — active HIGH
GPIO 5servo6_ENGPIO OUTAO3401A Gate Ch6High-side MOSFET enable — active HIGH
GPIO 6servo1_PWMPIO OUTServo 1 signal wire50 Hz PIO PWM — sub-µs jitter
GPIO 7servo2_PWMPIO OUTServo 2 signal wire50 Hz PIO PWM
GPIO 8servo3_PWMPIO OUTServo 3 signal wire50 Hz PIO PWM
GPIO 9servo4_PWMPIO OUTServo 4 signal wire50 Hz PIO PWM
GPIO 10servo5_PWMPIO OUTServo 5 signal wire50 Hz PIO PWM
GPIO 11servo6_PWMPIO OUTServo 6 signal wire50 Hz PIO PWM
GPIO 12S0 (MUX)GPIO OUT74HC4051 Pin 11MUX address bit 0
GPIO 13S1 (MUX)GPIO OUT74HC4051 Pin 10MUX address bit 1
GPIO 14S2 (MUX)GPIO OUT74HC4051 Pin 9MUX address bit 2
GPIO 18POT_1ADC0 INRV1 wiperManual Joint 1 input (0–3.3V = 0°–180°)
GPIO 19POT_2ADC1 INRV2 wiperManual Joint 2 input
GPIO 26MUX_AGPIO OUT74HC4051 Pin 11MUX address line A
GPIO 27MUX_BGPIO OUT74HC4051 Pin 10MUX address line B
GPIO 28MUX_CGPIO OUT74HC4051 Pin 9MUX address line C
GPIO 29ISNS_ADCADC3 IN74HC4051 Common (Z)Reads selected channel current sense voltage
USB-CUSB_DP/DMUSB 1.1USB-C connectorUF2 bootloader + CDC serial debug
SWDSWCLK/SWDIODEBUGSWD header (JB)ARM Serial Wire Debug

🏗️ PCB — 4-Layer Stackup

LayerFunctionDetails
Layer 1 — TopSignal + ComponentsAll SMD placement, fine-pitch routing (MCU, INA180, MUX)
Layer 2 — GNDSolid ground planeLow-impedance return path, EMI shielding, heat spreading
Layer 3 — PowerSplit power planes3.3V (MCU/sensors) · 5V (buck) · VIN (servo rails)
Layer 4 — BottomHigh-current tracesServo power delivery, secondary signal routing

A 4-layer design is essential here — with 6 servo channels switching simultaneously and up to 10A peak current, a 2-layer board would suffer from unacceptable EMI coupling and resistive heating.


📐 Physics — How It Works

Motor Torque from Current

The fundamental relationship exploited by this board:

text
τ = Kₜ × I

A DC motor's torque is directly proportional to its armature current. Kₜ is the motor's torque constant (Nm/A). By measuring current through the INA180 shunt amplifiers, we measure torque — without any mechanical sensor.

Current Sensing Chain

text
I (servo current)
  → V_shunt = I × R_shunt          (Ohm's Law across 10mΩ shunt)
  → V_out = V_shunt × 20           (INA180 ×20 amplification)
  → ADC = (V_out / 3.3V) × 65535  (RP2040 12-bit ADC)
  → I = (ADC / 65535 × 3.3) / (20 × 0.01)

At 2.5A (overload threshold): V_shunt = 25mV → V_out = 500mV — well within ADC range.

Resolution: ~0.25 mA per LSB → ~0.02 mNm torque resolution per LSB.

Servo PWM Position Encoding

text
θ° = (t_pulse − 500µs) / 2000µs × 180°
Pulse WidthAngle
500 µs0°
1500 µs90° (centre)
2500 µs180°

The RP2040's PIO state machines generate these pulses in hardware — completely independent of the CPU clock, eliminating software-induced jitter that corrupts positional accuracy.

Why PIO Instead of Hardware PWM?

Hardware PWM slices share a clock divider. Reprogramming multiple channels simultaneously causes brief glitches. PIO state machines run from dedicated instruction memory, each executing its PWM loop independently — giving 6 perfectly phase-stable signals while freeing both CPU cores for inverse kinematics or vision tasks.

Collision Detection — Torque Spike

When the arm hits an obstacle, the motor stalls. A stalled motor draws its locked-rotor current — far above normal running current:

text
Normal:  I ≈ 0.3–0.8 A  →  τ ≈ 0.025–0.068 Nm
Stall:   I → 2–4 A      →  τ → 0.17–0.34 Nm  ← triggers shutdown

The ADC scans all 6 channels continuously. A torque spike is detected within one scan cycle (~1 ms). The P-MOSFET cuts power within a single GPIO toggle (~10 ns).


🛡️ Safety System

FeatureDescription
Torque Estimationτ = Kₜ × I, live on all 6 joints, ~0.02 mNm resolution
Collision DetectionConfigurable torque threshold (default 0.20 Nm) triggers per-joint shutdown
Overcurrent ProtectionSustained current > 2.5A sets latching fault, cuts P-MOSFET
Emergency StopAll 6 channels cut simultaneously via single function call
Smooth MotionInterpolated moves with per-step collision check
Power SequencingStaggered joint enable (100ms delay) prevents inrush brownout
Fault LatchFault persists until software reset — prevents repeated thermal stress

💻 Firmware

python
# robotic_arm_controller.py
# GPIO 0-5  → Servo ENABLE (P-MOS high-side switches)
# GPIO 6-11 → Servo PWM    (PIO state machines)
import rp2, machine, time

SERVO_EN_PINS  = [0, 1, 2, 3, 4, 5]
SERVO_PWM_PINS = [6, 7, 8, 9, 10, 11]
MUX_SEL_PINS   = [12, 13, 14]
ADC_ISNS_PIN   = 29
POT1_PIN, POT2_PIN = 18, 19

SERVO_MIN_US = 500
SERVO_MAX_US = 2500
ISNS_GAIN    = 20
SHUNT_R      = 0.010
OVERLOAD_A   = 2.5
KT_NM_PER_A  = 0.085
COLLISION_NM = 0.20

@rp2.asm_pio(sideset_init=rp2.PIO.OUT_LOW)
def servo_pwm_pio():
    pull(block)          .side(0)
    mov(x, osr)
    label("high_loop")

🚀 Getting Started

1. Power the board Connect VIN (6–24V) to the screw terminal. Set jumpers JP1–JP6:

  • Position A → 5V internal buck (standard hobby servos)
  • Position B → Direct VIN (high-torque servos above 7.4V)

2. Flash firmware Hold BOOT on the back, press RESET. A drive named RPI-RP2 appears. Drag your .uf2 file onto it. Board reboots and runs automatically.

3. Test with potentiometers RV1 and RV2 control Joint 1 and Joint 2 by default. Rotate to verify servo response before connecting the full arm.

4. Monitor over serial Open any terminal at 115200 baud on the USB-C port. arm.status() prints a live table of angle, current, torque, and fault state for all 6 joints.

5. Tune collision thresholds Run the arm freely and log status() output. Set COLLISION_NM to ~1.5–2× the maximum torque observed during normal free movement.

6. Extend with C++ for performance Run motion control on Core 0 and current sensing on Core 1 for fully parallel deterministic operation. Core 1 can achieve scan rates exceeding 10 kHz — enabling sub-millisecond collision response.


✅ Capabilities

  • 6 independent PIO-generated PWM channels — sub-microsecond jitter
  • Real-time torque estimation on every joint — no mechanical sensors
  • Per-channel collision detection with configurable threshold
  • Individual high-side MOSFET shutdown per channel
  • Emergency stop — all 6 channels cut within a single GPIO toggle
  • Smooth interpolated motion with mid-move collision check
  • Staggered power-up to prevent inrush brownout
  • Manual joint control via onboard potentiometers
  • USB-C UF2 flashing — no external programmer required
  • SWD debug header — J-Link / DAPLink / OpenOCD compatible
  • Dual-core execution: motion on Core 0, sensing on Core 1
  • MicroPython and C++ Pico SDK fully supported
  • Per-servo independent voltage selection via JP1–JP6
  • Live status table: angle, current, torque, fault per joint
  • Latching fault system with software reset
  • CERN Open Hardware License — free to modify and manufacture

📄 License

Released under the CERN Open Hardware Licence Version 2 — Strongly Reciprocal (CERN-OHL-S v2).
Free to study, modify, manufacture, and distribute — derivatives must remain open source.


Designed by B.H

Parts

140
QtyValueFootprintReferences
1310kResistor_SMD:R_0805_2012MetricR3, R5, R7, R9, R11, R13, R16, R18, R20, R22, R24, R28, R29
12220Resistor_SMD:R_0805_2012MetricR4, R8, R12, R17, R21, R27, R33, R34, R35, R36, R37, R38
7AO3401APackage_TO_SOT_SMD:SOT-23Q1, Q2, Q3, Q4, Q5, Q6, Q7
7LEDLED_SMD:LED_0805_2012MetricD3, D6, D7, D8, D9, D10, D11
60.1Resistor_SMD:R_2010_5025MetricR2, R6, R10, R14, R19, R23
60.1uCapacitor_SMD:C_0603_1608MetricC7, C8, C9, C10, C11, C12
6100uCapacitor_THT:C_Radial_D5.0mm_H7.0mm_P2.00mmC2, C18, C20, C22, C24, C26
6CCapacitor_SMD:C_1206_3216MetricC17, C19, C21, C23, C25, C27
6Conn_01x03_PinConnector_PinHeader_2.54mm:PinHeader_1x03_P2.54mm_VerticalJ1, J2, J3, J4, J6, J7
6INA180A1Package_TO_SOT_SMD:SOT-23-5U5, U8, U10, U13, U15, U17
6Jumper_3_OpenConnector_PinHeader_2.54mm:PinHeader_1x03_P2.54mm_VerticalJP1, JP2, JP3, JP4, JP5, JP6
6PC817Package_TO_SOT_SMD:Analog_KS-4U4, U7, U9, U12, U14, U16
6TestPointTestPoint:TestPoint_Keystone_5005-5009_CompactTP3, TP4, TP5, TP6, TP7, TP8
50.1uCapacitor_SMD:C_1206_3216MetricC6, C28, C29, C30, C37
4MountingHole_PadMountingHole:MountingHole_2.5mm_Pad_ViaH1, H2, H3, H4
2100nCapacitor_SMD:C_0603_1608MetricC15, C16
212pFCapacitor_SMD:C_0402_1005MetricC4, C33
21uCapacitor_SMD:C_0603_1608MetricC13, C14
227Resistor_SMD:R_0603_1608MetricR30, R31
25.1KResistor_SMD:R_0805_2012MetricR15, R25
2R_PotentiometerNew_Library:TRIM_PT01-B115D-B103RV1, RV2
2TestPointTestPoint:TestPoint_Pad_D2.0mmTP1, TP2
110uCapacitor_SMD:C_1206_3216MetricC36
110uCapacitor_SMD:C_Elec_10x10.2C35
112MHz(10ppm)Crystal:Crystal_SMD_2520-4Pin_2.5x2.0mmY2
11KResistor_SMD:R_0805_2012MetricR1
11N5822Diode_SMD:D_SMBD2
11kResistor_SMD:R_0402_1005MetricR26
11kResistor_SMD:R_0805_2012MetricR32
1220uCapacitor_SMD:C_Elec_10x10.2C34
133uInductor_SMD:L_Bourns_SRP1050WAL2
1680uCapacitor_SMD:C_Elec_10x10.2C32
174HC4051Package_SO:SOIC-16W_5.3x10.2mm_P1.27mmU6
1AMS1117-3.3Package_TO_SOT_SMD:SOT-223-3_TabPin2U19
1Conn_02x06_Odd_EvenConnector_PinHeader_2.54mm:PinHeader_2x06_P2.54mm_Vertical_SMDJ11
1Conn_ARM_SWD_TagConnect_TC2030Connector:Tag-Connect_TC2030-IDC-FP_2x03_P1.27mm_VerticalJ8
1FerriteBeadInductor_SMD:L_0805_2012MetricFB2
1LM2596S-5Package_TO_SOT_SMD:TO-263-5_TabPin3U3
1RP2040Package_DFN_QFN:QFN-56-1EP_7x7mm_P0.4mm_EP3.2x3.2mmU1
1SS34Diode_SMD:D_SMAD1
1SW_PushButton_Switch_THT:SW_PUSH_6mm_H5mmSW1
1Screw_Terminal_01x02TerminalBlock_Phoenix:TerminalBlock_Phoenix_MKDS-1,5-2-5.08_1x02_P5.08mm_HorizontalJ9
1Screw_Terminal_01x12TerminalBlock_Phoenix:TerminalBlock_Phoenix_MKDS-1,5-12-5.08_1x12_P5.08mm_HorizontalJ10
1USBLC6-2SC6Package_TO_SOT_SMD:SOT-23-6U11
1USB_C_Receptacle_USB2.0_14PConnector_USB:USB_C_Receptacle_HRO_TYPE-C-31-M-12J5
1W25Q16JVSSPackage_SO:SOIC-8_5.3x5.3mm_P1.27mmU2

Similar boards

  • 4 layers110 × 120 mmDUT Interface board v0.2, the printed circuit board in 3D

    DUT Interface board v0.2

    krishchan007/DUT_Interface_board_v0.2

    v0.2 of DUT interface board with significant changes in layout, architecture etc.

    271 parts1
  • 4 layers72 × 44 mmPicflash board, the printed circuit board in 3D

    Picflash board

    nthclrd/picflash

    Programmeur PIC open source en Rust : remplace MPLAB IPE/XC8 pour les PIC16, pilote les PICkit 4/5/Basic ou une carte RP2040 maison (KiCad)

    115 parts1MIT
  • 2 layers76.2 × 61.9 mmDigits pcb, the printed circuit board in 3D

    Digits pcb

    justinlindh/digits

    Encrypted retro phone network — private VoIP over vintage desk phones

    71 parts4AGPL-3.0
  • 4 layers240 × 180 mmOparroy ci, the printed circuit board in 3D

    Oparroy ci

    kristofferkoch/oparroy

    WS2812 inspired versatile serial protocol and hardware

    570 partsMIT
  • 2 layers185 × 83 mmMass Spring Damper SysID Lab, the printed circuit board in 3D

    Mass Spring Damper SysID Lab

    Scalable-Open-Source-Labs/Mass-Spring-Damper-SysID-Lab

    An open source Mass-Spring-Damper to assist with teaching System Identification

    135 parts1MIT
  • 4 layers86 × 47 mmSmd board, the printed circuit board in 3D

    Smd board

    hinatadayo/nixie-token-display

    115 parts
  • 4 layers43 × 32.5 mmOpen TraceV1, the printed circuit board in 3D

    Open TraceV1

    Shubhayu-Banerjee/Open-Trace

    Cheap open source Mechanical 3D Lidar

    34 parts
  • 2 layers101.6 × 88.9 mmAutomotive gateway, the printed circuit board in 3D

    Automotive gateway

    dexus1337/automotive-gateway

    An automotive-grade, multi-protocol vehicle network interface, Man-in-the-Middle (MitM) filter, and wireless telemetry gateway

    109 parts1

Questions

How big is the Robotic arm controller PCB?

It measures 99 × 84 mm and has 4 copper layers, 1.6 mm thick.

What parts does the Robotic arm controller use?

140 parts, built around the RP2040, LM2596S-5.0, W25Q16JVSSIQ and 74HC4051. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.

Where can I download the Robotic arm controller KiCad files?

From the bejaouihamza/robotic_arm_controller repository on GitHub, at the commit this page was made from: the board is robotic_arm_controller.kicad_pcb and its schematic robotic_arm_controller.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the Robotic arm controller design in my own project?

Its repository states no licence, so its author keeps all rights: ask bejaouihamza before reusing the design.