Two dialects,
one wire.
The box speaks YSC JSON frames and the full MAKCU km.* text dialect — command-for-command compatible with the MAKCU ecosystem. Same command set on V1 and V2; only the physical transport differs (V1 UART · V2 USB-CDC, baud-independent).
Recoil Control
Deceleration coefficients shrink real mouse pull while firing. Duration window auto-scales to polling rate — identical behavior on 1K and 8K mice.
Macro Engine
Eight trigger-masked slots. Periodic wheel pulses with per-cycle random jitter on interval and duration — no metronome signature.
Mouse Curves
Segmented movement profiles reshape injected motion — smoothing segments, duration control and amplitude jitter for natural paths.
Jitter Trajectory
Fire-triggered micro-oscillation on independent X/Y axes with separate amplitude and frequency. Draw your own spray pattern.
Gamepad Mapping
Pad buttons map to mouse buttons with analog trigger thresholds; mouse motion converts to stick deflection with scaling and axis inversion.
Remote Control
Drive the box from a second machine over the network. Built-in self-test verifies the link end to end before you rely on it.
Framing &
responses.
YSC frames — a 7-byte START mark, 2-byte big-endian total length and a JSON payload,
closed by a 5-byte END mark. USART runs DMA on TX/RX with IDLE-line framing. Responses arrive as
{"code":200,"message":"…","data":"…"}; jitter and curve query results return asynchronously
via debug_response.
MAKCU dialect — plain-text km.* commands terminated by CRLF,
answers close with >>>.
A 9-byte binary baud frame (0xDE 0xAD 05 00 A5 + 4-byte LE rate) reconfigures the USART
directly — the recovery path when the current rate is unknown.
>>>
| Cmd | Name | Payload / Notes |
|---|---|---|
| 30 | MOUSE_MOVE | {"cmd":30,"x":100,"y":50,"c":1,"rx":1.0,"ry":1.0,"rc":0} — smooth move; c = step count; rx/ry physical-input deceleration, rc = window ms (rate-adaptive) |
| 31 | MOUSE_MOVE_TOW | Directional move, stacks with cmd 30 (deltas sum in the HID report). Same fields; its rc wins when both set |
| 32 | MOUSE_BUTTON | b mask (1=L, 2=R, 4=M), c = reports before auto-release |
| 33 | BUTTON_STATE | Direct set: s=1 press, 0 release — immediate, no report count |
| 34 | UPLOAD_STATUS | status>0 streams HID data (buttons + motion) back over serial |
| 35 | WHEEL_HOLD | w ±1, c = hold duration ms |
| 36 | MACRO_SET | Slot s 0–7, e enable, t trigger mask, p block mask, w wheel, i interval ms, d duty ms, ij/dj random jitter. Buttons: 1=L 2=R 4=M 8=S-back 16=S-fwd |
| 37 | MACRO_GET | s=-1 all slots, 0–7 single |
| 38 | MACRO_RESET | All slots back to firmware default (disabled) |
| 39 / 40 / 41 | JITTER SET/GET/RESET | e, t, ax, fx, py, fy — fire-triggered X/Y oscillation; results via async debug_response |
| 42 / 43 / 44 | CURVE SET/GET/RESET | e, p, n, d, j — profile, segments, duration ms, jitter amplitude |
| 50 | JUMP_TO_IAP | Replies entering_iap, then reboots into bootloader. V2 re-enumerates as serial number TOWMCUIAP — COM number may change |
| 132 (0x84) | GET_VERSION | Build date (__DATE__). V2: APP returns ysc-towmcu-L|R v1.0; IAP returns YSC-IAP |
| 133 (0x85) | SET_BAUDRATE | baud — no whitelist check in firmware; send only the 8 whitelisted rates (115200 … 3000000). Host must follow immediately |
| Command | Group | Notes |
|---|---|---|
| km.move(x,y[,seg]) | Motion | seg 1–512 (clipped) for stepped moves |
| km.left / right / middle / ms1 / ms2 (1/0) | Buttons | 1=press, 0=release, 2=silent release (skips push queue) |
| km.wheel(±1) | Motion | One notch; other values clipped to ±1 |
| km.lock_mx / lock_my (0/1) | Axis lock | Also lock_mx+ / lock_mx- for single direction; same for Y |
| km.lock_ml / mr / mm / ms1 / ms2 | Button lock | Physical button stops registering |
| km.invert_x / invert_y · km.swap_xy | Axis map | Invert or swap axes |
| km.catch_ml / mm / mr / ms1 / ms2 | Capture | 0=auto, 1=manual capture mode |
| km.scroll_side · km.scroll_lr | Wheel map | Side-button or L+R chord triggers wheel |
| km.buttons(mode,period) | Push | Physical button push reports; period 1–1000 ms |
| km.serial("…" / 0) | Identity | Set / reset device serial (max 32 B, C-style escapes); no arg = query |
| km.echo(0/1) | System | Command echo (default on) |
| km.baud([rate]) | System | rate ≥ 115200, no whitelist check; no arg = query |
| km.version() | System | Returns km.version(km.MAKCU) |
| km.reboot() | System | Soft reset after reply |
| State | Meaning | How to identify |
|---|---|---|
| APP | Normal operation — passthrough + command handling | cmd 132 returns the app version string (ysc-towmcu-L v1.0 / -R on V2, build date on V1) |
| IAP | Bootloader, awaiting firmware | cmd 132 returns YSC-IAP; V2 enumerates with serial number TOWMCUIAP |