I designed and built a six-axis arm: custom mechanics, stepper control, numerical kinematics and a teach-in interface.
Hardware
Six stepper-driven revolute joints and a gripper, inspired by the ABB IRB 1100. Custom 3D-printed links and transmissions support joint-space and Cartesian motion.
Electronics
- Low-level processor: Arduino Mega 2560.
- Actuation: step/direction drivers with per-axis transmission ratios and 1/16 microstepping in the six-axis sketch.
- Feedback: AS5600 magnetic encoders through a TCA9548A I2C multiplexer.
- Serial interface: joint targets, velocity and acceleration limits at 1 Mbaud in the desktop-control path.
Kinematics
A URDF models joint axes and link transforms. MATLAB/DH derivations document the earlier analytical work.
T0,6(q) = T0,1(q1) · … · T5,6(q6)
q: six joint angles; T: homogeneous rigid-body transforms.
The offset wrist motivated numerical IK rather than spherical-wrist decoupling. IKPY uses bounded nonlinear least-squares to minimize Cartesian position error and weighted rotation-matrix residuals within the URDF joint limits. It solves position and orientation, seeded by the previous solution; forward kinematics checks the position residual. Pose targets use the URDF's right-handed base frame, with proper rotations and explicit millimetre-to-metre conversion. Host regressions check rotation validity and a reachable FK–IK–FK pose round-trip; these checks do not measure physical tool accuracy.
Ttarget = [ Rtarget ptarget; 0 1 ]
ep = ‖pFK(q) − ptarget‖2
R: orientation; p: position. Model residual, not physical tool accuracy.
Motion control
AccelStepper converts joint targets to steps and scales speed/acceleration by relative axis travel. FlexyStepper is the earlier trapezoidal-profile implementation. Encoder feedback supports teaching and control development; a continuous six-axis encoder-error servo is not demonstrated by the published sketch.
ni = si Gi μi qi / Δθmotor
G: transmission ratio; μ: microstep factor; s: axis sign. q and motor step angle use the same angular units.
State estimation
Encoder counts are unwrapped and corrected for zero offsets/gearing. Low-pass filters smooth position and finite-difference velocity; a single-axis sketch supports tuning.
q̂k = λpqk + (1 − λp)q̂k−1
q̇̂k = λv Δq̂k/Δt
+ (1 − λv)q̇̂k−1
First-order smoothing; coefficients trade noise rejection against measurement lag.
Simulation and operator interface
PyQt5 provides joint sliders, Cartesian pose targets and a live 3D URDF view. Kinematic visualisation only, not dynamics/collision simulation. The original host was a Raspberry Pi.
Teach-in and hardware demonstrations
Motors disabled: hand-guide the arm and record encoder motion. The GUI replays stored samples at a controlled speed. Clips demonstrate replay and task-space operation, not quantified repeatability.
ROS 2
Keyboard jogging publishes sensor_msgs/JointState targets on /joint_commands, with configurable increments and limits. Joint positions are converted from GUI/keyboard degrees to ROS radians at publication. The published serial firmware is separate: a consuming micro-ROS bridge is not included in the current public source. The historical integration milestone does not establish a reproducible ROS-to-hardware path. ROS 1 teleop is legacy.
Development
SimpleFOC stepper testing is experimental. STM32H7 migration remains planned.
Build gallery and videos
Raghavan, M., & Roth, B. (1993). Inverse kinematics of the general 6R manipulator and related linkages. Journal of Mechanical Design, 115(3), 502–508. https://doi.org/10.1115/1.2919218











