Board v2 · Firmware in developmentDraft
Configuration and limits
Machine limits (HardConfig) and working limits (SoftConfig), base units, homing, limit switches and how the configuration is stored.
UPAN keeps two layers of configuration on the motion MCU. HardConfig describes the machine: mechanics, motor current, absolute travel and speed limits, limit switches and homing. SoftConfig holds the working limits for the current job and must stay inside HardConfig. Every motion command and every program step is checked against these limits on the device itself, whoever sent it — an app, a script or an AI agent. This page describes both layers, the units they use, homing and limit switch settings, and how the configuration is stored.
Note: This page follows board revision A and firmware that is still in development. Field names come from the protocol schema; see
HardConfigandSoftConfigin the API reference.
Base units
The protocol uses only metric integers, called base units. The axis type (HardConfig.axis_kind) decides which ones apply.
| Quantity | Linear axis (AXIS_LINEAR) |
Rotary axis (AXIS_ROTARY) |
|---|---|---|
| Position, distance | µm | millidegree (m°) |
| Velocity | µm/s | m°/s |
| Acceleration | µm/s² | m°/s² |
| Time | ms | ms |
There are no inches in the protocol. Host tools convert exactly (1 in = 25 400 µm) before sending. upan-cli accepts um, mm, cm, m, in on a linear axis and mdeg, deg, rev on a rotary axis; a plain number means millimetres or degrees. SoftConfig.display_units stores whether a user interface should show metric or imperial values; it has no effect on motion.
In motion commands, a velocity or acceleration of 0 means "use the default from SoftConfig".
Two layers
| HardConfig | SoftConfig | |
|---|---|---|
| Describes | the machine | the current job |
| Typical content | steps per revolution, travel per revolution, absolute travel, maximum speed and acceleration, motor current, limit switches, homing, encoder | working travel, speed and acceleration limits, defaults, jog timeout |
| Who may change it | only over USB, inside the physical presence window | any connected host: app, script, agent, network API |
| Set with | HardConfigSet |
SoftConfigSet |
| Read with | HardConfigGet |
SoftConfigGet |
A command outside the soft limits is refused with ERROR_LIMIT_EXCEEDED. The response carries a LimitViolation: which limit (LIMIT_TRAVEL_MIN, LIMIT_TRAVEL_MAX, LIMIT_VELOCITY, LIMIT_ACCELERATION, LIMIT_JOG_TIMEOUT), the requested value and the nearest allowed value, so a host or an agent can correct the request without guessing.
Changing HardConfig: USB and physical presence
HardConfigSet is accepted only when both conditions hold:
- The request arrives over USB. Over the network module it is refused with
ERROR_TRANSPORT_NOT_ALLOWED; the network API does not offer it at all. - The presence window is open. A short press (under 2 s) of the light-button on the device opens a 30 s window and the device sends
EVENT_PRESENCE_WINDOW_OPEN. Without it the request is refused withERROR_PRESENCE_REQUIRED.
upan-cli -p COM5 config set --hard home_method=limit_min limit_max_absent=yes
Press the light-button briefly, then run the command within 30 s.
After a successful HardConfigSet:
- SoftConfig is clamped into the new machine limits;
- the axis is no longer homed, because the mechanics may have changed;
- the driver is reconfigured (direction, current, microstepping).
Warning: HardConfig is the last line of protection for your machine. Set travel, speed and current to what the mechanics can really take. No app, agent or network client can raise these values.
Changing SoftConfig
Any host can change SoftConfig, as long as the new values lie inside HardConfig:
upan-cli -p COM5 config set travel_max=80mm velocity_default=5mm/s
upan-cli -p COM5 config show soft
The device checks the new SoftConfig and refuses it with ERROR_LIMIT_EXCEEDED (with the allowed value) or ERROR_INVALID_VALUE if it does not fit.
Both SoftConfigSet and HardConfigSet are accepted only while the axis is not moving (state idle, fault or e-stop); otherwise the answer is ERROR_BUSY.
HardConfig fields
| Field | Unit | Meaning |
|---|---|---|
axis_kind |
— | AXIS_LINEAR or AXIS_ROTARY; selects µm or m° |
full_steps_per_rev |
steps | full steps per motor revolution, usually 200 (up to 10 000) |
microsteps |
— | 1…256; with the built-in driver only powers of two |
travel_per_rev |
bu | travel per motor revolution: screw lead × reduction |
invert_direction |
— | reverse the motor direction |
travel_min, travel_max |
bu | absolute machine travel; travel_min must be less than travel_max |
velocity_max |
bu/s | machine speed limit |
acceleration_max |
bu/s² | machine acceleration limit |
run_current_ma |
mA | peak phase current, as printed on the motor nameplate (built-in driver only, up to 5 600 mA) |
hold_current_ma |
mA | current at standstill, not more than run_current_ma |
limit_min_active_low, limit_max_active_low |
— | polarity of the limit switch inputs |
limit_min_absent, limit_max_absent |
— | no switch fitted on that side; the input is ignored |
home_method |
— | see Homing |
home_velocity |
bu/s | homing speed, not more than velocity_max |
stallguard_threshold |
— | StallGuard sensitivity, −64…63; higher is less sensitive |
encoder_enabled |
— | use the encoder input |
encoder_counts_per_rev |
counts | encoder counts per motor revolution (quadrature, ×4) |
encoder_invert |
— | encoder counts in the opposite direction (A/B swapped) |
following_error_max |
bu | allowed difference between commanded and encoder position; more → fault |
driver_mode |
— | DRIVER_INTERNAL (built-in TMC2160) or DRIVER_EXTERNAL_STEP_DIR |
bus_node |
— | position in a module stack: 0 = UPAN Core, 1…7 = UPAN Axis |
The device validates the whole HardConfig before saving it:
- The step rate is limited to 500 000 steps/s. A
velocity_maxthat would need more is refused withLIMIT_VELOCITYand the highest allowed value. - Position in steps must fit the MCU counter; travel that is too long for the chosen resolution is refused with the allowed travel.
- Features the board variant does not have are refused with
ERROR_UNSUPPORTED:DRIVER_INTERNALand StallGuard homing on the Step/Dir variant (UPC-S), an encoder on hardware without the encoder capability.
Which features a board has is reported in Info.capabilities.
SoftConfig fields
| Field | Unit | Rule |
|---|---|---|
travel_min, travel_max |
bu | inside the HardConfig travel; travel_min < travel_max |
velocity_max |
bu/s | 1 … HardConfig velocity_max |
acceleration_max |
bu/s² | 1 … HardConfig acceleration_max |
velocity_default |
bu/s | 1 … velocity_max; used when a command gives velocity 0 |
acceleration_default |
bu/s² | 1 … acceleration_max; used when a command gives acceleration 0 |
jog_timeout_max_ms |
ms | upper bound for Jog.timeout_ms, up to 5 000 ms |
display_units |
— | DISPLAY_UNITS_METRIC or DISPLAY_UNITS_IMPERIAL, UI preference only |
Homing
Absolute moves and programs need a known position. The axis becomes homed by Home or by SetPosition (declare the current position without moving). Relative moves and jogging work without homing.
home_method |
What Home does |
|---|---|
HOME_NONE |
nothing: Home is refused with ERROR_INVALID_STATE; use SetPosition |
HOME_LIMIT_MIN |
moves toward the min switch at home_velocity, backs off slowly until the switch releases; position = HardConfig travel_min |
HOME_LIMIT_MAX |
same toward the max switch; position = HardConfig travel_max |
HOME_STALLGUARD_MIN |
moves toward min until the built-in driver detects a stall; no switch needed |
HOME_STALLGUARD_MAX |
same toward max |
If the switch or the stall is not found within the travel, the axis goes to fault with ERROR_HOMING_FAILED. When homing finishes, the device sends EVENT_HOME_DONE.
StallGuard homing is available only with the built-in driver (UPC-D). The right stallguard_threshold depends on the motor and the mechanics; 0 is a reasonable start. Tuning guidance is not final yet.
upan-cli -p COM5 home
upan-cli -p COM5 set-position 0
The axis loses its homed state after a fault, an e-stop, or a HardConfig change.
Limit switches
Board revision A expects normally closed (NC) limit switches. The inputs pass through an inverting Schmitt trigger, so a pressed switch or a broken wire reads as "triggered". The matching default is limit_min_active_low = false and limit_max_active_low = false.
If no switch is fitted on a side, the open input also reads as triggered, which is the safe state: the axis will not move toward that side. To run without a switch, set limit_min_absent or limit_max_absent to true in HardConfig. The fields say "absent" rather than "enabled" on purpose: a host that does not know them cannot switch protection off by accident.
Behaviour of the current firmware:
- A switch triggered in the direction of motion stops the axis immediately, puts it in fault with
ERROR_LIMIT_SWITCH, and clears the homed state. - A move toward an active switch is refused with
ERROR_LIMIT_SWITCH; a move away from it is allowed. FaultClearleaves the fault state once the cause is gone.
See Wiring for the switch connections and Safety for the stop input.
Where the configuration is stored
HardConfig and SoftConfig are stored together in the flash memory of the motion MCU, as a journal of records with a checksum. A new record is appended; the device loads the newest complete record at start-up.
- Power loss at any moment leaves the previous complete configuration in place.
- Configuration is saved only while the axis is still, because erasing flash pauses the step timing.
- If saving fails, the request is refused with
ERROR_STORAGEand the configuration in use does not change. A configuration that only changed in RAM and vanished after a reset would be worse than a refusal. - Reflashing the motion MCU firmware keeps the stored configuration.
- The record format is protobuf, so newer firmware can read configuration written by older firmware.
A factory reset (holding the light-button for 10 s at power-on) is planned to reset the network settings and SoftConfig, but not HardConfig. The procedure is not final yet.