Fab Academy Rwanda · Printable pen plotter

XIAO RP2040 wiring and control

We selected a standard Seeed Studio XIAO RP2040 with grblHAL. Two external step/direction drivers move X and Y; a micro servo lifts the pen. We prepare drawings in our image-to-G-code tool and send the downloaded file over USB with a grblHAL-compatible sender. The standard XIAO RP2040 has no built-in Wi-Fi.

Controller and power

  • Standard XIAO RP2040 and a USB data cable.
  • Two external drivers with PUL/STEP and DIR inputs, matched to the actual bipolar NEMA 17 motors. The driver model determines the input circuit, current limits, pulse timing and motor supply voltage.
  • SG90-class servo, its supplied horn and screw, and a regulated 5 V supply sized for its peak current. Power the servo from that supply, not the XIAO's 3.3 V rail.
  • Two X/Y home switches. Optional hold/reset buttons have reserved pins and are disabled in our default build.
  • Motor supply, DC switch, fuse, connectors and cable sizes chosen for the actual drivers and motors.

The servo supply negative and servo signal ground connect to XIAO GND. Keep an external 5 V rail disconnected from the XIAO 5 V/USB pin unless its power-sharing circuit has been designed for that connection. Never put motor-supply voltage or 5 V on a GPIO.

Pin map

Use the printed D labels when locating a header pin and the GPIO number in firmware. These assignments are specific to our board map, not a generic Pico image.

SignalXIAO labelRP2040 GPIOConnection
X PUL/STEPD60X driver input interface
X DIRD82X driver input interface
Y PUL/STEPD71Y driver input interface
Y DIRD103Y driver input interface
Shared driver enableD94Optional; confirm enable polarity and input load
Pen servo signalD57Servo PWM output 0; 3.3 V signal or appropriate buffer
X homeD026Switch input referenced to GND
Y homeD127Switch input referenced to GND
Optional feed holdD228Disabled until a suitable button is fitted
Optional reset/haltD329Disabled until a suitable button is fitted
SpareD46Unassigned

Native USB uses separate USB pins. We do not enable a UART sender on D6/D7 because these pins drive step signals. The build moves the unclaimed hardware UART to internal LED pins 16/17; do not enable UART accessories with this profile. grblHAL has a minimum of three logical axes: the unused Z step/direction outputs are GPIO18/19, which are not exposed on the standard XIAO. We omit a Z limit input and home only X and Y. Pen lifting uses M280, with no Z move.

PUL/DIR driver interface

We must identify the driver model before choosing the terminal wiring. A driver with labelled PUL+/PUL− and DIR+/DIR− may use optocouplers that need more voltage or current than a 3.3 V GPIO can provide. Do not assume these terminals can be wired directly.

  • If the manual explicitly accepts 3.3 V logic and its input current is within the RP2040 rating, use its specified logic connection and reference ground.
  • For opto-isolated inputs requiring a 5 V current loop, use a suitable transistor, buffer or line-driver interface. Select its supply, resistors and signal polarity from the driver manual.
  • Two enable inputs share one GPIO only through an interface rated for their combined load. Enable can remain unwired only if the driver manual specifies a suitable default state.
  • Set step pulse width, direction setup time, microstepping and motor current from the actual driver requirements. We have not assigned an unverified universal Vref or terminal polarity.

Build the controller firmware

Our profile enables USB and the grblHAL PWM servo plugin, disables spindle/coolant outputs, and sets X/Y-only homing cycles. Homing, hard limits, soft limits and optional buttons start disabled until the physical inputs and motion have been checked. The software still needs measured steps/mm and verified direction/enable polarity.

The configuration script targets a pinned upstream revision. It adds our board map, corrects MCU selection for the XIAO board, permits an absent Z limit input, and starts the servo at a 90° command with a 1–2 ms pulse range at 50 Hz. Remove the servo horn before the first power-up; the command angle does not establish the actual linkage position.

Install Git, Python 3, CMake and an ARM bare-metal GCC toolchain. In a separate build directory, obtain the upstream source and Pico SDK:

git clone https://github.com/grblHAL/RP2040.git grblhal-rp2040
cd grblhal-rp2040
git checkout 2f5bc4a06ecea3b1f78c1644623810f9b6416376
git submodule update --init --recursive
cd ..
git clone --depth 1 --branch 2.2.0 https://github.com/raspberrypi/pico-sdk.git pico-sdk
git -C pico-sdk submodule update --init lib/tinyusb
python /path/to/pen-plotter/controller/configure_grblhal.py grblhal-rp2040
cmake -S grblhal-rp2040 -B build-xiao -DPICO_BOARD=seeed_xiao_rp2040 -DPICO_SDK_PATH=/absolute/path/to/pico-sdk -DCMAKE_BUILD_TYPE=Release
cmake --build build-xiao --parallel 4

Build output: build-xiao/grblHAL.uf2. Hold the XIAO BOOT button while connecting USB to enter its bootloader, then copy the UF2 to the mounted boot drive. No firmware is flashed by the configuration script. Preserve the upstream licence notices; grblHAL is GPL-licensed. Our package contains the configuration source, not a pre-flashed or physically tested controller.

We compiled this profile successfully for the XIAO board and checked that the servo plugin was linked. See the software build record. This verifies compilation; it does not verify flashing, GPIO waveforms or physical motion.

Pen lift and G-code

The PWM servo plugin supplies a real 50 Hz servo signal. Its upstream documentation marks the feature experimental. Confirm the plugin appears in the controller's $I information and the servo pin is assigned as expected in $pins.

M280 P0 S90
G4 P0.25

This requests servo 0 at 90° and allows 0.25 seconds to settle. Our tool starts with 90° up and 60° down; fit the horn and adjust these values to the actual mechanism with X/Y stationary. Use a light contact on the paper and a small clear lift. We have not physically verified these angles.

The drawing tool scales an uploaded image to fit the page, converts dark regions to horizontal strokes, and previews the result. Export uses millimetres, absolute X/Y coordinates, G54, M280 and servo waits. It raises the pen before travel and between strokes, and finishes with the pen raised. It sends no machine commands and inserts no automatic homing or origin change. A picture is hatched into strokes; it is not automatically converted into vector outlines.

Coordinates and calibration

Set G54 X0 Y0 at the lower-left corner of the verified 200 × 150 mm drawing area. The tool produces X0…200 and Y0…150 coordinates within the chosen page margin. Positive drawing Y requires the moving paper bed to travel in the opposite physical direction; establish this with short labelled jogs.

For the selected cord/capstan drive, use the actual cord-centre winding diameter, not a timing-belt tooth count:

starting steps/mm = full steps per revolution × microsteps / (π × effective capstan diameter)
corrected steps/mm = current steps/mm × commanded distance / measured distance

The supplied profile starts at 49.6873969 steps/mm, calculated for a 200-step motor, 1/16 microstepping and a 20.5 mm effective cord-centre diameter. Set the actual driver microstep switches accordingly, then correct $100 and $101 from measured travel. A firmware default is not a calibrated value.

With motor power off, check every axis by hand. Then verify driver current/polarity and test 1–5 mm jogs with the pen removed. Check both home inputs and their inversion using controller status before enabling homing or hard limits. Normally closed switches to GND are a practical option with pull-ups and matching input polarity. Optional hold/reset inputs require the corresponding CONTROL_ENABLE flags and correct switch wiring; software hold/reset is not a motor-power isolator. Check the actual travel envelope before enabling soft limits. Finally fit the pen and measure a small square and longer lines to adjust travel scaling.

Primary references