A robot arm that draws its landscape.
Part of the Cybernetic Garden — a machine-creature that perceives the territory around it (device pings, signal landscape, eventually a depth camera) and renders what it senses as drawings on paper. Sibling of gen3d (ceramic) and gen2d (plotter).
Three motors, two struts, direct drive, horizontal table, paper taped down. No wrist, no pen lift, no elegance. Assembled and moving first; fancy joints, belts, and perception later.
rotate pivot pivot
[base] --- [shoulder] --- [elbow] --- pen
NEMA17 NEMA23 NEMA17
|mast 30cm 2020 30cm 2020
Pi 3B+ (host) Arduino Uno + CNC shield Arm
-------------- ------------------------ ---
perception (later) USB 3x TMC2209 (assumed - verify!)
path planning ------> coordinated stepping 3x stepper
inverse kinematics serial homing, limits 2x 30cm strut
host/arm_host.py E-STOP pen
host/arm_ik.py firmware/genarm_firmware
The host does all thinking (IK, path planning, perception). The Arduino is a dumb, reliable motion executor: it receives joint angles and steps to them. Same pattern as the gen3d ceramic extruder rig.
- L1 = L2 = 300 mm pivot-to-pivot (2020 aluminium extrusion)
- Shoulder pivot height H ~ 200 mm above table (19 cm mast + base bearing stack; measure after assembly). Taller = better pen angle + less torque, bigger central dead zone.
- Workspace: annulus roughly 50-588 mm radius (see visualizer)
| Piece | Job |
|---|---|
| 39 cm x2 | upper arm + forearm: pivot inset 9 cm from one end = 30 cm working strut + 9 cm counterweight tail through the pivot |
| 39 cm x2 | base H-frame rails (clamp to table) |
| 24 cm x2 | base H-frame cross-pieces |
| 19 cm | mast |
| 19 cm | spare / pen boom / endstop mounts |
Counterweight = washer stack or chunky bolt in the tail slot; slide along the slot until the arm floats, lock the T-nut.
- IK is closed-form: base aims at the target bearing, shoulder+elbow are a 2-link planar solve (law of cosines), elbow-up only
Open visualizer/index.html in any browser — click the table to move the
pen, run test patterns, drag the shoulder-height slider.
Worst case = arm straight out horizontal.
| Joint | Load moment | Motor (from stock) | Plan |
|---|---|---|---|
| Shoulder | ~25 kg-cm | 57HD4016 NEMA23 (short stack, ~5-9) | counterweight MANDATORY |
| Elbow | ~5 kg-cm | 42-40 Creality NEMA17 (~4) | small counterweight stub |
| Base | ~0 (gravity-neutral) | 42BYGH610P2-X NEMA17 (long stack) | fine |
Spares: 2x 42-40, 42SHDC3025-24B, 42-34 (future pen-lift axis). The 57HD4016 is a short NEMA23 - if a taller one turns up, swap it in.
Counterweight = run the strut past the pivot and hang washers until the arm nearly balances. Costs nothing, halves the problem.
Known v1 limitation: direct drive at 16 microsteps is ~1 mm of pen motion per microstep at full reach. It will draw; fine lines will be coarse. Upgrade #1 is a 3-5:1 GT2 belt reduction on shoulder + base.
| Command | Meaning |
|---|---|
G <base> <sh> <el> |
coordinated move to joint angles (degrees) |
H |
home all axes |
E / D |
enable / disable steppers |
U / L |
pen up / down (future - servo lift) |
P |
report status + current angles |
! |
E-STOP: halt + disable immediately |
Firmware replies ok when a move completes (host flow control), err ...
on rejects. Physical E-STOP button also wired (pin A0 to GND).
visualizer/index.html standalone IK simulator (no deps, just open it)
host/arm_ik.py inverse kinematics (stdlib only; python arm_ik.py --test)
host/arm_host.py Pi/laptop-side controller: streams angles over serial
firmware/genarm_firmware/ Arduino sketch (UNTESTED - written ahead of hardware)
sudo apt install python3-serial # or: pip install pyserial
python3 host/arm_ik.py --test
python3 host/arm_host.py --port /dev/ttyUSB0 --demo squareArduino appears as /dev/ttyUSB0 (CH340 clone) or /dev/ttyACM0 (genuine).
Add user to dialout: sudo usermod -a -G dialout $USER, re-login.
- IK + visualizer + self-test
- Verify CNC shield drivers actually are TMC2209 (look for "2209" on the driver boards)
- Firmware bring-up: motors on bench, no arm attached
- Cut list, assembly, counterweights, homing switches
- First drawing: square + circle on paper
- Pen-lift servo; belt reduction on shoulder + base 6.5 [ ] Leadscrew elbow (linear actuator across the joint, excavator-style): motor mass moves to the shoulder end, self-locking (holds pose unpowered), huge reduction. Angle<->screw-length is a triangle solve added to arm_ik.py.
- Wrist roll + pen pivot (4th/5th DOF)
- Perception: device pings / signal landscape / depth cam -> drawing
- Canvas change mechanism (or whiteboard + wipe)
2026-07-26: IK solved, tested (5000-point roundtrip, worst error 7e-13 mm), visualizer working. Firmware written but never flashed. No metal cut yet.