Configure a motor with an encoder

Use an encoder with a motor to create a closed feedback loop for better control of your robot. Instead of sending speed or position commands without a way to verify the motor’s behavior, the encoder lets the computer know how the motor is actually rotating in the real world, so adjustments can be made to achieve the desired motor movement.

Some motors come with encoders integrated with or attached to them. You can also add an encoder to a motor. See the encoder component documentation for more information on encoders.

Viam supports gpio model motors with encoders. To configure an encoded motor, you must configure the encoder per the encoder documentation and then configure a gpio motor with an encoder attribute in addition to the standard gpio model attributes.

Here’s an example configuration:

Screenshot of an encoded motor config in the Viam app UI.
{
  "components": [
    {
      "name": <board_name>,
      "type": "board",
      "model": <board_model>,
      "attributes": {},
      "depends_on": []
    },
    {
      "name": <encoder_name>,
      "type": "encoder",
      "model": "incremental",
      "attributes": {
        "board": <board_name>,
        "pins": {
          "a": <first_pin_number>,
          "b": <second_pin_number>
        }
      },
      "depends_on": []
    },
    {
      "name": <motor_name>,
      "type": "motor",
      "model": "gpio",
      "attributes": {
        "board": <board_name>,
        "pins": {
          <...>
        },
        <...other_board_attributes...>
      },
      "depends_on": []
    }
  ]
}
{
  "components": [
    {
      "name": "local",
      "type": "board",
      "model": "pi",
      "attributes": {},
      "depends_on": []
    },
    {
      "name": "myEncoder",
      "type": "encoder",
      "model": "incremental",
      "attributes": {
        "board": "local",
        "pins": {
          "a": "13",
          "b": "15"
        }
      },
      "depends_on": []
    },
    {
      "name": "myMotor1",
      "type": "motor",
      "model": "gpio",
      "attributes": {
        "board": "local",
        "pins": {
          "pwm": "16",
          "dir": "18"
        },
        "encoder": "myEncoder",
        "ticks_per_rotation": 9600
      },
      "depends_on": []
    }
  ]
}

Same example JSON as on the JSON example tab, with notes alongside it. See attribute table below for all the same information.

Required Attributes

In addition to the required attributes for a non-encoded motor, encoded DC motors require the following:

NameTypeDescription
encoderstringShould match name of the encoder you configure as an encoder component.
ticks_per_rotationstringNumber of ticks in a full rotation of the encoder (and motor shaft).

max_rpm does not apply to encoded gpio motors.

Optional Attributes

In addition to the optional attributes listed in the non-encoded DC motor section, encoded motors have the following additional options:

NameTypeDescription
ramp_ratefloatHow fast to ramp power to motor when using RPM control. 0.01 ramps very slowly; 1 ramps instantaneously. Range is (0, 1]. Default is 0.2.

Wiring Example

Here’s an example of an encoded DC motor wired with the MAX14870 Single Brushed DC Motor Driver Carrier. This wiring example corresponds to the example config above.

Example wiring diagram with a Raspberry Pi, brushed DC motor, 12V power supply, and Pololu MAX14870 motor driver. The DIR pin of the driver is wired to pin 18 on the Pi. PWM goes to pin 16. The motor&rsquo;s encoder signal wires (out a and out b) go to pins 11 and 13 on the Pi. The motor&rsquo;s main power wires are connected to the motor driver while its encoder logic power wires are connected to the Pi.