Skip to content

Gestures

Every gesture is the same two-machine dance: the X/Y arm drives the stylus to the bbox center, then a solenoid drops the tip onto the glass and lifts it. The Z axis is not a servo and there’s no depth to calibrate — the tip sits at a fixed height, and the only thing that varies is timing. What makes a tap a tap and a long-press a hold is how long the coil stays energized.

The stylus tip is pushed down by a solenoid wired to the GRBL spindle PWM pin, so it’s driven with spindle G-code: M3 S<duty> energizes the coil at a PWM duty on a 01000 scale, and M5 releases it. A return spring lifts the tip when the coil cuts. A solenoid burns its coil out if held at full current, so PhysiClaw uses a hit-and-keep profile: strike hard to pull the iron core in, then drop to a lower hold current to keep it seated.

ConstantValueWhat it is
HIT_S1000strike duty — pulls the core in (brief only)
HOLD_S750hold duty — safe to sustain (long-press, swipe slide)
SETTLE_MS80msdwell after the strike before dropping to the hold level
RELEASE_MS200msspring-rebound dwell after M5, before any XY move
DOUBLE_TAP_GAP_MS100msbrief lift between the two strikes of a double-tap

After every M5, PhysiClaw dwells RELEASE_MS so the spring can lift the tip clear before the next XY move starts — otherwise the tip would drag a line across the screen.

A momentary press: strike at HIT_S, hold for the tap duration (80ms), release. The press is short enough that the reduced hold current isn’t needed — S1000 for 80ms gives a crisp contact without cooking the coil.

G-code
G0 X.. Y.. ; arm moves to the bbox center
M3 S1000 ; strike (stylus down)
G4 P0.08 ; hold 80 ms
M5 ; release
G4 P0.2 ; spring-rebound dwell (tip clears the glass)

Two strikes separated only by a brief contact-breaking lift — not the full spring-clear dwell. The whole pair runs as one gesture so down-to-down stays well under the iOS ~300ms double-tap window; chaining two independent taps (each with its 200ms release) pushed it to ~280ms, and timing jitter then split the gesture into two single taps.

G-code
M3 S1000 ; strike 1
G4 P0.08 ; hold 80 ms
M5 ; lift briefly…
G4 P0.1 ; …100 ms, just enough to break contact
M3 S1000 ; strike 2
G4 P0.08 ; hold 80 ms
M5 ; release
G4 P0.2 ; spring-rebound dwell

Here the hit-and-keep profile earns its name: strike, settle, drop to the hold current, and keep the tip seated for the full long-press duration (1.2s) before lifting. iOS/Android register a long-press at ~500ms; 1.2s leaves comfortable margin.

G-code
G0 X.. Y.. ; arm moves to the bbox center
M3 S1000 ; strike
G4 P0.08 ; settle 80 ms
M3 S750 ; drop to hold current
G4 P1.2 ; hold 1.2 s
M5 ; release
G4 P0.2 ; spring-rebound dwell

A swipe presses, then moves under load. The tip is held down at HOLD_S for the whole slide while the arm runs a controlled G1 move (not a rapid G0) from the origin to the endpoint, then lifts. Stroke length comes from the size argument; the speed argument sets the G1 feed rate:

speedFeedFeel
slowF3000careful scroll / drag
mediumF6000normal swipe (~100 mm/s)
fastF10000fling, page switch
G-code
G0 X.. Y.. ; arm moves to the start
M3 S1000 ; strike
G4 P0.08 ; settle 80 ms
M3 S750 ; drop to hold current (tip stays down for the slide)
G1 X.. Y.. F6000 ; drag to the endpoint at the chosen feed
M5 ; release
G4 P0.2 ; spring-rebound dwell
GestureDownHoldMoveUp
TapS100080msM5 + 200ms dwell
Double-tapS1000 ×280ms each, 100ms gapM5 + 200ms dwell
Long-pressS1000S7501.2sM5 + 200ms dwell
SwipeS1000S750for the slideG1 at F3000/6000/10000M5 + 200ms dwell