Skip to the content
PCBKitNew board
2 layers165 × 95.5 mmRobotArmPCB, the printed circuit board in 3D

Firmware for a custom 3D-printed 6-axis robotic arm (50 cm reach, 2 kg payload). This is the first-generation control board, built around an ESP32-S3 carrier PCB driving six TMC2209 stepper drivers, with a WiFi web UI…

Size
165 × 95.5 mm
Copper layers
2
Thickness
1.6 mm
Parts
43
Nets
83
Pads
240
Tracks, vias
371, 11
Pours
1
Routed
Yes
KiCad
KiCad 9.0 (file 20241229)
Created
24 Jun 2026
Updated
24 Jun 2026

Overview

RobotArmPCB is an open-source printed circuit board by JonasKi2005, from the JonasKi2005/StepperControllerPCB repository on GitHub. It is a 2-layer board of 165 × 95.5 mm with 43 parts on 83 nets, routed with 371 tracks and 11 vias.

It is built around the ESP32-S3-DEVKITC-1-N8R2. Its parts include 15 capacitors, 12 connectors, 9 resistors and 7 ICs. It belongs with the ESP32 boards of this library.

Main components

1

README

readme.md

6-Axis Robot Arm — Firmware (v1: ESP32-S3 + TMC2209)

Firmware for a custom 3D-printed 6-axis robotic arm (~50 cm reach, 2 kg payload). This is the first-generation control board, built around an ESP32-S3 carrier PCB driving six TMC2209 stepper drivers, with a WiFi web UI for manual control and bring-up.

Status: This is the original ESP32-S3 board and is retired. It served as the first working bring-up of the arm, but the fabricated PCB had a UART addressing limitation (the driver address-select pins were not broken out as intended, so the address-multiplexing scheme below could not be used as designed). Development has since moved to a custom STM32G484 + TMC5240 board. This repo is kept as a reference for the working step-generation and driver code.


Hardware

ComponentPart
MCUESP32-S3 (DevKitC-class carrier PCB)
Stepper drivers6× TMC2209 (BTT V1.2 modules, R_sense = 0.11 Ω)
Motors J1–J3NEMA 17 17HS19-2004S1 (2 A)
Motors J4–J6NEMA 17 17HS13-0404S (0.4 A, short body)
Power24 V supply → drivers; logic rails on-board

Driver bus layout

The six drivers are split across two UART buses, three drivers per bus, using the TMC2209's single-wire half-duplex UART with address multiplexing (each driver on a bus is assigned address 0, 1, or 2):

text
UART1 ──┬── J1 (addr 0)      UART2 ──┬── J4 (addr 0)
        ├── J2 (addr 1)              ├── J5 (addr 1)
        └── J3 (addr 2)              └── J6 (addr 2)

All six drivers share a single EN line. The arm boots disarmed (EN held HIGH, motors freewheeling) and only energizes after a POST to /arm.


Firmware architecture

Built on ESP-IDF (FreeRTOS). Four main translation units:

main.cpp — entry point

Boot sequence: NVS init → construct one TMC2209 per axis (UART + GPIO setup only) → optionally push register config to each driver → start the motion controller → bring up WiFi (the web server starts automatically once an IP is assigned). All pin assignments and per-joint parameters (current, microsteps) live here in one place.

TMC2209.cpp — driver class

Low-level UART register access with CRC, plus higher-level config:

  • write_reg / read_reg — 8-byte datagrams, CRC-checked, with echo handling for single-wire half-duplex.
  • init() — pushes GCONF/CHOPCONF/IHOLD_IRUN/PWMCONF and verifies writes landed by checking that IFCNT incremented by the expected count (your UART-wiring smoke test).
  • set_current() — computes IRUN/IHOLD from a requested RMS current, automatically selecting vsense for best resolution.
  • set_microsteps() — maps microstep count to the CHOPCONF MRES field.
  • print_drv_status() — decodes DRV_STATUS flags (overtemp, short, open-load, etc.).

MotorController.cpp — motion engine

The ESP32-S3 has only 4 hardware GPTimers, so one timer per axis is impossible. Instead a single shared timer fires at 20 kHz, and the ISR uses Bresenham-style step accumulation (the same pattern Marlin/Klipper use): each active axis accumulates its velocity_sps per tick and emits a step pulse when the accumulator crosses the tick rate. Supports per-axis jogging, absolute move_to targets, and clean stop/disarm. Commands flow through a FreeRTOS queue to a dedicated motion task pinned to core 1.

Server.cpp — WiFi + web UI

Connects as a WiFi station and serves a self-contained HTML control panel (no external assets). The UI polls /status for live position and arm state, and exposes jog, move-to, arming, current, and microstep controls.

HTTP API
MethodEndpointParamsPurpose
GET/—Web control UI
GET/status—JSON: arm state, per-axis step counts, moving flags
POST/arm—Energize drivers (EN low)
POST/disarm—De-energize drivers (EN high)
POST/stop_all—Stop all axes
POST/jogaxis, dir, vContinuous jog until stop
POST/stopaxisStop one axis
POST/move_toaxis, target, vMove one axis to a step target
POST/currentaxis, maSet RMS current (50–2000 mA)
POST/microstepsaxis, usSet microstepping (1…256)

Building & flashing

Requires the ESP-IDF toolchain. From the firmware directory:

bash
idf.py set-target esp32s3
idf.py build
idf.py -p <PORT> flash monitor

On macOS the ESP32-S3 enumerates via the Silicon Labs CP210x driver; <PORT> is typically /dev/cu.SLAB_USBtoUART or similar.

Set your WiFi credentials (WIFI_SSID / WIFI_PASS) before building. On boot the serial monitor prints the assigned IP address — open it in a browser to reach the UI.

Bring-up note: Driver init() is commented out in main.cpp by default so the board can boot and run the web UI without working UART to the drivers. Re-enable it once the UART wiring is verified — init() will report via IFCNT whether register writes are actually reaching each driver.


Known limitations of this board

  • UART addressing: the address-multiplexing scheme above depends on each driver's address-select pins being individually set. On the fabricated board this wasn't the case and has to be fixed in the kicad files.
  • No closed-loop feedback — purely open-loop step counting.
  • This is my first PCB so there probably will be some other errors, since the PCB wasn't tested so far.

A note on the code

The code in this repository is handwritten. AI was used only to polish and comment it — the architecture, logic, and implementation decisions are my own.

Parts

43
QtyValueFootprintReferences
9100µFCapacitor_THT:CP_Radial_D6.3mm_P2.50mmC1, C2, C4, C6, C8, C10, C12, C14, C15
6100nFCapacitor_THT:C_Disc_D5.0mm_W2.5mm_P2.50mmC3, C5, C7, C9, C11, C13
622kΩResistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P7.62mm_HorizontalR1, R3, R5, R9, R11, R16
21kΩResistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P7.62mm_HorizontalR7, R8
2Servo_1Connector_PinHeader_2.54mm:PinHeader_1x03_P2.54mm_VerticalJ15, J16
110kΩResistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P7.62mm_HorizontalR13
1Buck-Down-ConverterKiCad:YAAJ_DCDC_StepDown_LM2596J6
1DRIVER_1TMC2209_SILENTSTEPSTICK:MODULE_TMC2209_SILENTSTEPSTICKU2
1DRIVER_2TMC2209_SILENTSTEPSTICK:MODULE_TMC2209_SILENTSTEPSTICKU4
1DRIVER_3TMC2209_SILENTSTEPSTICK:MODULE_TMC2209_SILENTSTEPSTICKU6
1DRIVER_4TMC2209_SILENTSTEPSTICK:MODULE_TMC2209_SILENTSTEPSTICKU3
1DRIVER_5TMC2209_SILENTSTEPSTICK:MODULE_TMC2209_SILENTSTEPSTICKU5
1DRIVER_6TMC2209_SILENTSTEPSTICK:MODULE_TMC2209_SILENTSTEPSTICKU7
1ESP32-S3-DEVKITC-1-N8R2ESP32_S3_DEVKITC_1_N8R2:XCVR_ESP32-S3-DEVKITC-1-N8R2U1
1Fan_1Connector_PinHeader_2.54mm:PinHeader_1x02_P2.54mm_VerticalJ17
1Fan_2Connector_PinHeader_2.54mm:PinHeader_1x02_P2.54mm_VerticalJ18
1Motor_1Connector_JST:JST_XH_B4B-XH-A_1x04_P2.50mm_VerticalJ19
1Motor_2Connector_JST:JST_XH_B4B-XH-A_1x04_P2.50mm_VerticalJ3
1Motor_3Connector_JST:JST_XH_B4B-XH-A_1x04_P2.50mm_VerticalJ5
1Motor_4Connector_JST:JST_XH_B4B-XH-A_1x04_P2.50mm_VerticalJ2
1Motor_5Connector_JST:JST_XH_B4B-XH-A_1x04_P2.50mm_VerticalJ4
1Motor_6Connector_JST:JST_XH_B4B-XH-A_1x04_P2.50mm_VerticalJ7
1PSU_INPUT1935161:PHOENIX_1935161J1

Questions

How big is the RobotArmPCB PCB?

It measures 165 × 95.5 mm and has 2 copper layers, 1.6 mm thick.

What parts does the RobotArmPCB use?

43 parts, built around the ESP32-S3-DEVKITC-1-N8R2. 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 RobotArmPCB KiCad files?

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

Can I use the RobotArmPCB design in my own project?

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

Similar boards

  • 4 layers135 × 84 mmStepper with TMC2209 controller board V1, the printed circuit board in 3D

    Stepper with TMC2209 controller board V1

    JasonHEngineering/DIY-Robot-Arm-V3

    1) Along with using with TMC2209 motor drivers, I have removed R8, R15, R16, R17, R18, R19 because the R value was accidentally too high. I have shorted R8, R16, R17, and left open R15, R18, R19.

    95 parts2
  • 2 layers200 × 130 mmEsp32s3 wmlta, the printed circuit board in 3D

    Esp32s3 wmlta

    riezky-gitH/SIMPAS-BOILER

    > 📖 Guidebook proyek — tautan guidebook baru akan ditambahkan di sini.

    129 parts2MIT
  • 2 layers100 × 50 mmVga test, the printed circuit board in 3D

    Vga test

    cfrankb/ESP32-S3-VGA-ADAPTOR

    VGA ESP32-S3 Breakout board for WROOM1- DevKit

    38 parts1
  • 4 layers100 × 79 mmESP32 Interface, the printed circuit board in 3D

    ESP32 Interface

    dennowiggle/ESP32_Interface

    Facilitate learning the Z80 Retro! hardware and software.

    114 parts1LGPL-2.1
  • 2 layers85.4 × 100 mmMl robot, the printed circuit board in 3D

    Ml robot

    matthieu-sgi/machine_learning_robot

    A machine learning bot.

    16 parts1
  • 2 layers126.2 × 143.6 mmSciencepcb, the printed circuit board in 3D

    Sciencepcb

    Sidbit08/ABEX_PCB_v1

    A custom ESP32-S3-based PCB designed in KiCad for automated soil sample analysis, featuring drivers and interfaces for environmental sensors, peristaltic pumps, and auger drilling actuators.

    100 parts1
  • 2 layers102 × 45 mmHELPStat V2, the printed circuit board in 3D

    HELPStat V2

    stevfu/eis_capstone

    Utilization of Electrochemical Impedance Spectroscopy for the Detection of Drugs

    51 parts1MIT