Protocol

The mock implements the SOLO serial protocol from the Operation Manual (Rev. 1.09b, chapter 4) for a SOLO-50.

Commands

CmdBytes sentBehaviorReply
c / C1read current positionu32 position + CR
h1move to stored homeCR after the move
w1move to stored workCR after the move
H1 + u32store target as home, then move thereCR after the move
W1 + u32store target as work, then move thereCR after the move
x / X1 + u32move to targetCR after the move
v1 + u16accepted, no effect (the SOLO-50 has one speed)CR

There are no terminators. Every command finishes with a single CR (0x0D), sent when its action completes. Positions are in µsteps.

Byte order

Multi-byte integers are least-significant byte first. The manual is inconsistent on this; the mock follows LSB-first throughout.

ExchangeBytes (hex)
host sends c63
mock replies 10,667 µsteps (0x29AB)AB 29 00 00 0D
host sends x to 20,000 µsteps (0x4E20)78 20 4E 00 00
mock replies when the move ends0D

Timing

All moves are straight-line at 3000 µm/s. A move of d µm takes d / 3000 / timescale seconds of wall time, and its CR is sent at the end. timescale is set in MockSOLO.start(; timescale). It must be > 0, and Inf makes moves instant.

Behavior where the manual is silent

SituationMock behavior
Target > 533,334 µstepsclamped to 533,334; the move proceeds and CR is sent
Bytes sent during a movequeued, processed in order after the move's CR (a mid-move c is answered after the move)
Unknown command bytedropped with no reply (still in the traffic log)
Partial framewaits indefinitely for the remaining bytes
H / Wstore the target (clamped) as home / work, then move there
Serial move during a front-panel movetakes over from the current position and clears any pause

Device constants

ConstantValue
µsteps → µm0.09375
µm → µsteps10.66666666667, rounded to an integer
Range0 – 533,334 µsteps (0 – 50,000 µm)
Speed3000 µm/s for all moves
Startup position1000 µm = 10,667 µsteps
Default home / work10,667 µsteps each
Pulse step30 µsteps = 2.8125 µm (manual: nominal 2.85 µm)

Traffic log

traffic returns a vector of (t, dir, bytes) named tuples, where t is seconds since start. dir is :in for one chunk read from the host and :out for one reply. Unknown bytes appear as :in entries with no matching :out.