Configure a DMC4000 motor

This model supports stepper motors controlled by DMC-40x0 series motion controllers.

Whereas a basic low-level stepper driver supported by the gpiostepper model sends power to a stepper motor based on PWM signals from GPIO pins, the DMC40x0 motion controller has many motion control features. When using it, you do not need to configure a board component because it handles computation and signal creation on the motion controller itself.

The DMC-40x0 controller can drive a variety of motor types, but the built-in Viam implementation supports only stepper motors at this time. You can drive other types of motors with Viam and the DMC-40x0 controller by creating a custom motor model.

Navigate to the Config tab of your robot’s page in the Viam app. Click on the Components subtab and click Create component. Select the motor type, then select the DMC4000 model. Enter a name for your motor and click Create.

A DMC4000 motor config with the attributes configured per the Raw JSON on the next tab in this doc.

Edit and fill in the attributes as applicable.

{
  "components": [
    {
      "name": "<your-motor-name>",
      "type": "motor",
      "model": "DMC4000",
      "attributes": {
        "amplifier_gain": <int>,
        "low_current": <int>,
        "ticks_per_rotation": <int>,
        "serial_path": <string>,
        "controller_axis": "<your-motion-controller-axis-label>",
        "home_rpm": <int>,
        "max_rpm": <float>,
        "max_acceleration_rpm_per_sec": <float>
      },
      "depends_on": []
    }
  ]
}

Example configuration for a stepper motor controlled by a DMC-40x0 motion controller:

{
  "components": [
    {
      "name": "my-dmc-motor",
      "type": "motor",
      "model": "DMC4000",
      "attributes": {
        "amplifier_gain": 3,
        "low_current": 1,
        "ticks_per_rotation": 200,
        "serial_path": "/dev/serial/by-path/<device_ID>",
        "controller_axis": "A",
        "home_rpm": 70,
        "max_rpm": 300
      },
      "depends_on": []
    }
  ]
}

The following attributes are available for DMC4000 motors:

NameTypeInclusionDescription
amplifier_gainintRequiredSet the per phase current (when using stepper amp).
low_currentintRequiredReduce the hold current.
ticks_per_rotationintRequiredNumber of full steps in a rotation. 200 (equivalent to 1.8 degrees per step) is very common. If your data sheet specifies this in terms of degrees per step, divide 360 by that number to get ticks per rotation.
serial_pathstringRequiredThe full filesystem path to the serial device, starting with /dev/. With your serial device connected, you can run sudo dmesg | grep tty to show relevant device connection log messages, and then match the returned device name, such as ttyS0, to its device file, such as /dev/ttyS0. If you omit this attribute, Viam will attempt to automatically detect the path.
controller_axisstringRequiredPhysical port label (A-H); select which “axis” the motor is wired to on the controller.
home_rpmintRequiredSet speed in revolutions per minute (RPM) that the motor will turn when executing a Home() command (using DoCommand()).
dir_flipboolOptionalFlip the direction of the signal sent if there is a DIR pin.
max_rpmnumberOptionalSet a limit on maximum revolutions per minute that the motor can be run at.
max_acceleration_rpm_per_secnumberOptionalSet the maximum revolutions per minute (RPM) per second acceleration limit.

Refer to your motor and motor driver data sheets for specifics.

Extended API

The DMC4000 model supports additional methods that are not part of the standard Viam motor API:

Home

Run the DMC homing routine.

Parameters:

  • None

Raises:

  • (error): An error, if one occurred.

For more information on do_command, see the Python SDK Docs.

myMotor = Motor.from_robot(robot=robot, name='my_motor')

# Home the motor
home_dict = {
  "command": "home"
}
await myMotor.do_command(home_dict)

Parameters:

  • ctx (Context): A Context carries a deadline, a cancellation signal, and other values across API boundaries.

Returns:

  • (error): An error, if one occurred.

For more information, see the Go SDK docs on Home and on DoCommand.

myMotor, err := motor.FromRobot(robot, "motor1")

// Home the motor
resp, err := myMotor.DoCommand(ctx, map[string]interface{}{"command": "home"})

Jog

Move the motor indefinitely at the specified RPM.

Parameters:

  • rpm (float64): The revolutions per minute at which the motor will turn indefinitely.

Raises:

  • (error): An error, if one occurred.

For more information on do_command, see the Python SDK Docs.

myMotor = Motor.from_robot(robot=robot, name='my_motor')

# Run the motor indefinitely at 70 rpm
jog_dict = {
  "command": "jog",
  "rpm": 70
}
await myMotor.do_command(jog_dict)

Parameters:

  • ctx (Context): A Context carries a deadline, a cancellation signal, and other values across API boundaries.
  • rpm (float64): The revolutions per minute at which the motor will turn indefinitely.

Returns:

  • (error): An error, if one occurred.

For more information, see the Go SDK Docs on Jog and on DoCommand.

myMotor, err := motor.FromRobot(robot, "motor1")

// Run the motor indefinitely at 70 rpm
resp, err := myMotor.DoCommand(ctx, map[string]interface{}{"command": "jog", "rpm": 70})

Raw

Send raw string commands to the controller.

Parameters:

  • raw_input (String): The raw string to send to the controller.

Raises:

  • (error): An error, if one occurred.

For more information on do_command, see the Python SDK Docs.

myMotor = Motor.from_robot(robot=robot, name='my_motor')

raw_dict = {
  "command": "raw",
  "raw_input": "home"
}
await myMotor.do_command(raw_dict)

Parameters:

  • ctx (Context): A Context carries a deadline, a cancellation signal, and other values across API boundaries.
  • raw_input (String): The raw string to send to the controller.

Returns:

  • (error): An error, if one occurred.

For more information, see the Go SDK Docs on Raw and on DoCommand.

myMotor, err := motor.FromRobot(robot, "motor1")

resp, err := myMotor.DoCommand(ctx, map[string]interface{}{"command": "jog", "raw_input": "home"})

Test the motor

Once your motor is configured and connected, go to the Control tab and click on the motor’s drop-down panel. Use the buttons to try turning your motor forwards or backwards at different power levels and check whether it moves as expected.

Motor control panel.

If the motor does not appear on the Control tab, or if you notice unexpected behavior, check your robot’s Logs tab for errors, and review the configuration.



Have questions, or want to meet other people working on robots? Join our Community Discord.