Encoded Motors
Use an encoder with a motor to create a closed feedback loop for better control of your machine. 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.
Configure the board and the encoder.
{
"components": [
{
"name": "<your-board-name>",
"model": "<your-board-model>",
"api": "rdk:component:board",
"attributes": {},
"depends_on": []
},
{
"name": "<your-encoder-name>",
"model": "<your-encoder-model>",
"api": "rdk:component:encoder",
"attributes": {
... // insert encoder model specific attributes
},
"depends_on": []
},
{
"name": "<your-motor-name>",
"model": "gpio",
"api": "rdk:component:motor",
"attributes": {
"board": "<your-board-name>",
"pins": {
<...> // insert pins struct
},
"encoder": "<your-encoder-name>",
"ticks_per_rotation": <int>,
"control_parameters": {
"p": <int>,
"i": <int>,
"d": <int>
}
},
"depends_on": []
}
]
}
Here’s an example configuration:
{
"components": [
{
"name": "local",
"model": "pi",
"api": "rdk:component:board",
"attributes": {},
"depends_on": []
},
{
"name": "myEncoder",
"model": "incremental",
"api": "rdk:component:encoder",
"attributes": {
"board": "local",
"pins": {
"a": "13",
"b": "15"
}
},
"depends_on": []
},
{
"name": "myMotor1",
"model": "gpio",
"api": "rdk:component:motor",
"attributes": {
"board": "local",
"pins": {
"pwm": "16",
"dir": "18"
},
"encoder": "myEncoder",
"ticks_per_rotation": 9600,
"control_parameters": {
"p": 0.2,
"i": 0.5,
"d": 0.0
}
},
"depends_on": []
}
]
}
In addition to the attributes for a non-encoded motor, the following attributes are available for encoded DC motors:
| Name | Type | Required? | Description |
|---|---|---|---|
encoder | string | Required | name of the encoder. |
ticks_per_rotation | int | Required | Number of ticks in a full rotation of the encoder and motor shaft. |
ramp_rate | float | Optional | Rate to increase the motor’s input voltage (power supply) per second when increasing the speed the motor rotates (RPM). Range = ( 0.0, 1.0]Default: 0.05 |
control_parameters | object | Optional | A JSON object containing the coefficients for the proportional, integral, and derivative terms. If you want these values to be auto-tuned, you can set all values to 0: { "p": 0, "i": 0, "d": 0 }, and viam-server will auto-tune and log the calculated values. Tuning takes several seconds and spins the motors. Copy the values from the logs and add them to the configuration once tuned for the values to take effect. For more information see Control motor velocity with encoder feedback. |
Info
The attribute max_rpm is not required or available for encoded gpio motors.
Important
If encoder is model AM5-AS5048,ticks_per_rotation must be 1, as AM5-AS5048 is an absolute encoder which provides angular measurements directly.
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.

Control motor velocity with encoder feedback
If you want to control your motor by specifying the distance and velocity in terms of distance and distance/time, for example 2 rotations at 5 m/s, and you have an encoder, you can use the position of your encoder to adjust the distance and velocity.
You can do this in two ways:
The first just uses the encoder feedback to increase or decrease the power being set on the motors in increments of 10%.
The second requires setting the control_parameters attribute, which sets up a PID control loop to adjust the distance and velocity of the motor.
Setting the control_parameters will automatically set up the required PID loop for an encoded motor.
For more information on PID or to set up a more complex control loop, see the controls package
If you want these values to be auto-tuned, you can set all values to 0: { "p": 0, "i": 0, "d": 0 }, and viam-server will auto-tune and log the calculated values.
Tuning takes several seconds and spins the motor.
Copy the values from the logs and add them to the configuration once tuned for the values to take effect.
Was this page helpful?
Glad to hear it! If you have any other feedback please let us know:
We're sorry about that. To help us improve, please tell us what we can do better:
Thank you!