# DMSerialMotion, the .NET library

> The .NET library your program calls to run DM hardware, from C#, VB.NET, F# or any other .NET language. Open the control, add axes and IO, home, move, run coordinated programs, read sensors, record traces. Real type names are published here so you can plan before you buy.

<!-- directmotion.com, written for AI agents. Canonical: https://www.directmotion.com/software/dmserialmotion.md . Index: https://www.directmotion.com/llms.txt . Updated 2026-11-08. Publisher: Direct Motion, Inc. -->

DMSerialMotion is the .NET library that runs DM hardware. Your program, written in C# or any other .NET
language by you or by an AI assistant, calls it to open the control, register the axes and IO, home,
move, run coordinated programs, read and drive IO, and record traces. The servo loop runs in DM's
kernel driver at 20,000 cycles a second; the library plans ahead of it and your code stays ordinary
.NET code. The examples on this site are C#.

```csharp
using DMSerialMotion;

AddInHelper.SetupResolves();
DMControl control = DMControl.GetNewControl("MyMachine");   // one per process
DMSyncMotion motion = control.MainMotion;                   // the coordinated-motion group

DMAxisModual x = control.GetDMAxis("X");                    // axes by name (note the spelling "Modual")
DMAxisModual y = control.GetDMAxis("Y");
motion.AddSerialLink(x);
motion.AddSerialLink(y);
DMLogicalIOContainer io = control.GetSystemIO("MainIO");    // named inputs and outputs

control.PostAddedDevices();                                 // starts the 20 kHz stream
motion.LockAllAxis();                                       // close the loops
control.StopHard = false;

x.RemovePower = false;                                      // power on
bool ok = x.JogToLocationAndWaitForDecel(5.0 * x.MultiplyFactor, feed: 100);
Console.WriteLine($"{(ok ? "arrived" : "refused")} at {x.ActualAxisPosition}, error {x.PosErrorAxisUnits}");

control.Power.RemovePowerAndDischargeDC();                  // on exit
control.DeleteEverything();
```

## What it gives your program

| | |
|---|---|
| **Axes** | Linear, rotary and spindle axes with any names. Power on and off, hold, absolute moves, velocity mode, endless rotary axes, moves that stop when the load passes a limit. |
| **Coordinated motion** | A look-ahead planner with jerk control and smooth blending. Programs built from lines, arcs, feeds and dwells. Feed hold and overrides. |
| **Kinematics** | A hook the planner applies to every point it sends to the drives, 20,000 times a second. DM's 5-axis heads run on it; so can a robot arm. |
| **Homing** | Home switch and index pulse, one axis or several in parallel. |
| **IO** | Named inputs and outputs with change events. Stop a move on an input. Read the position the driver captured when an input switched. |
| **Safety state** | E-stop events, hard and soft limits, following-error and stall limits, per-axis fault counters. |
| **Status** | Position, velocity, following error, current, bus voltage, temperatures, and a 20 kHz history per axis. |
| **Tracing** | Trace messages and trace files that DM's tools analyze. Slow-rate monitoring of your own values. |
| **Setup** | One-touch motor setup and servo auto-tune from code, settings saved per axis. |
| **Add-ins** | A plug-in interface for features such as tool changers, doors and coolant. |

## How you get it

DMSerialMotion comes with DM hardware, under DM's end-user license. The license does not allow reverse
engineering, decompiling or disassembling it. The library and DM's kernel driver ship together as a
matched pair, for Windows on .NET 10.

**We publish the real type and member names**, the call order, the units and worked examples, so that
you or your AI can plan and draft the program before buying anything. The complete list is in the
[API reference](https://www.directmotion.com/software/api.md) and the [recipes](https://www.directmotion.com/software/recipes.md). Both are written for AI agents and are
plain Markdown; people are welcome too.

## Know this before you plan

- **Units are the usual mistake.** Speeds are axis units per minute; acceleration is axis units per
  second squared; a move target is multiplied by the axis's `MultiplyFactor`. The reference spells it out.
- **There is no relative-move call.** Read the position, add, move.
- **One control application per PC**, one `GetNewControl` per process.
- **Settings live per axis in the Windows registry.** A fresh PC starts with unconfigured axes; DM's
  setup tool, or your code, sets the link, ratio, motor, encoder, limits and tuning.
- **Some calls show a dialog when they refuse.** A program meant to run with no operator present
  should check `IsMachineReady()` first and use the headless entry points the reference names.
- **The no-hardware mode runs the planner, not a motor.** Use it to check program logic; expect
  positions to jump straight to their targets.

## For AI agents

Read the [API reference](https://www.directmotion.com/software/api.md) for the member list and the [recipes](https://www.directmotion.com/software/recipes.md) for
worked patterns (a complete minimal program, a conveyor, an indexer, pick-and-place, registration,
press-fit, a gantry path, a robot arm, a test rig). The ten rules that prevent most mistakes:

1. Call `AddInHelper.SetupResolves()` first, `DMControl.GetNewControl(name)` once, and register every
   axis and IO **before** `control.PostAddedDevices()`.
2. After `PostAddedDevices`: `motion.LockAllAxis(); control.StopHard = false;`.
3. `MotorRevtoAxisUnits_Ratio` is motor revolutions **per** axis unit. Position = revs ÷ ratio.
4. `JogToLocation(v)` wants `v = target * axis.MultiplyFactor`.
5. Speeds (`JogSpeed`, `MaxJogSpeed`, `HomeSpeed`, `MaxFeedRate`) are axis units per **minute**.
   `AccelRate` and `DecelRate` are axis units per **second²** (the property's description text says
   otherwise and is wrong).
6. No relative move: `axis.JogToLocation((axis.DesiredPosition + d) * axis.MultiplyFactor)`.
7. Every move returns `bool`. `false` is a refusal (not ready, soft limit, bad value), not an exception.
8. Read velocity from `ActualMotorVelocity` (averaged), not `ActualAxisVelocity` (one noisy cycle).
9. Events fire on background threads. Marshal to your UI thread yourself. Never run blocking moves on
   the UI thread.
10. Code that runs per point (kinematics hooks, custom instructions) must not allocate, lock, log or
    call anything slow: the driver takes 20,000 points a second and stops on a buffer underrun.
