Configure a GPIO-Controlled Motor

The gpio model supports DC motors (both brushed and brushless).

To configure a DC motor as a component of your machine, first make sure the motor is wired to a suitable motor driver, which is in turn wired to a board. Connect the system to power if you want to test it while configuring. Configure the board to which the motor driver is wired. Then configure your motor:

Navigate to the CONFIGURE tab of your machine’s page in the Viam app. Click the + icon next to your machine part in the left-hand menu and select Component. Select the motor type, then select the gpio model. Enter a name or use the suggested name for your motor and click Create.

G P I O motor config in the builder UI with the In1 and In2 pins configured and the PWM pin field left blank.

Edit and fill in the attributes as applicable.

{
  "components": [
    {
      "name": "<your-board-name>",
      "model": "<your-board-model>",
      "type": "board",
      "namespace": "rdk",
      "attributes": {},
      "depends_on": [],
    },
    {
      "name": "<your-motor-name>",
      "model": "gpio",
      "type": "motor",
      "namespace": "rdk",
      "attributes": {
        "pins": {
          "dir": "<int>",
          "pwm": "<int>",
          "en_low": "<int>"
        },
        "board": "<your-board-name>",
        "max_rpm": <int>,
        "min_power_pct": <float>,
        "max_power_pct": <float>,
        "pwm_freq": <float>,
        "dir_flip": <float>
      },
      "depends_on": []
    }
  ]
}

An example configuration for a gpio motor:

{
  "components": [
    {
      "name": "local",
      "model": "pi",
      "type": "board",
      "namespace": "rdk",
      "attributes": {},
      "depends_on": []
    },
    {
      "name": "example-gpio",
      "model": "gpio",
      "type": "motor",
      "namespace": "rdk",
      "attributes": {
        "pins": {
          "dir": "36",
          "pwm": "32"
        },
        "board": "local",
        "max_rpm": 500
      },
      "depends_on": []
    }
  ]
}

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

The following attributes are available for gpio motors:

NameTypeRequired?Description
boardstringRequiredname of the board to which the motor driver is wired.
max_rpmintRequiredThis is an estimate of the maximum RPM the motor will run at with full power under no load. The GoFor method calculates how much power to send to the motor as a percentage of max_rpm. If unknown, you can set it to 100, which will mean that giving 40 as the rpm argument to GoFor or GoTo will set it to 40% speed. Not required or available for encoded gpio motors.
pinsobjectRequiredA structure that holds pin configuration information; see below.
min_power_pctfloatOptionalSets a limit on minimum power percentage sent to the motor.
Default: 0.0
max_power_pctfloatOptionalRange is 0.06 to 1.0; sets a limit on maximum power percentage sent to the motor.
Default: 1.0
pwm_freqintOptionalSets the PWM pulse frequency in Hz. Many motors operate optimally in the kHz range.
Default: 800
dir_flipboolOptionalFlips the direction of “forward” versus “backward” rotation. Default: false
encoderstringOptionalThe name of an encoder attached to this motor. See encoded motor.

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

pins

There are three common ways for your computer to communicate with a brushed DC motor driver chip. Your motor driver data sheet will specify which one to use.

  • PWM/DIR: Use this if one of your motor driver’s pins (labeled “PWM”) takes a pulse width modulation (PWM) signal to the driver to control speed while another pin labeled “DIR” takes a high or low signal to control the direction.
    • Configure pwm and dir.
  • In1/In2: Use this if your motor driver has pins labeled “IN1” and “IN2” or “A” and “B,” or similar. One digital signal set to a high voltage and another set to a low voltage turns the motor in one direction and vice versa. Speed is controlled with PWM through one or both pins.
    • Configure a and b.
  • In1/In2 and PWM: Use this if your motor driver uses three pins: In1 (A) and In2 (B) to control direction and a separate PWM pin to control speed.
    • Configure a, b, and pwm.

Inside the pins struct you need to configure two or three of the following, in addition to "en_high" or "en_low", depending on your motor driver:

NameTypeRequired?Description
astringRequired for some driversBoard pin number this motor driver’s “IN1” or “A” pin is wired to.
bstringRequired for some driversBoard pin number this motor driver’s “IN2” or “B” pin is wired to.
dirstringRequired for some driversBoard pin number this motor driver’s direction (“DIR”) pin is wired to.
pwmstringRequired for some driversBoard pin number this motor driver’s “PWM” pin is wired to.
en_high / en_lowstringOptionalSome drivers have optional enable pins that enable or disable the driver chip. If your chip requires a high signal to be enabled, add en_high with the pin number to this struct. If you need a low signal use en_low.

Wiring examples

Brushed DC motor

Taking a 12V brushed DC motor controlled by a DRV8256E Single Brushed DC Motor Driver Carrier wired to a Raspberry Pi as an example, the wiring diagram would look like this:

An example wiring diagram showing a Raspberry Pi, 12V power supply, DRV8256E motor driver, and 12V brushed DC motor. The logic side of the driver is connected to the Pi’s ground and 3.3V pins. The driver pin for PWM goes to pin 32 on the Pi and the direction pin goes to pin 36 on the Pi. The motor side of the motor driver is connected to the ground and 12V terminals of a power supply and the OUT1 and OUT2 pins go to the two terminals of the motor.

The signal wires in the diagram run from two GPIO pins on the Pi to the DIR and PWM pins on the motor driver. Refer to a Raspberry Pi pinout schematic to locate generic GPIO pins and determine their pin numbers for configuration.

Brushless DC motor

Brushless DC motor drivers work in much the same way as brushed DC motor drivers. They typically require a PWM/DIR input or an A/B (In1/In2) and PWM input to set the motor power and direction. The key difference between a brushed and brushless motor driver is on the motor output side. Brushless motors typically have three power connections (commonly referred to as A, B and C; or sometimes Phase 1, 2 and 3) and 3 sensor connections (commonly referred to as Hall A, Hall B, and Hall C) running between the motor and driver.

The configuration file of a BLDC motor with Viam is the same as that of a brushed motor. Only the output side of the driver board is different in that more wires connect the driver to the motor.

An example wiring diagram showing a Raspberry Pi, 12V power supply, RioRand 400W brushless DC motor controller, and 3 phase 12V brushless DC motor. The motor has three power wires (one for each phase) and five sensor wires (two to power the sensor and one for each of the three Hall effect sensors).

Test the motor

Once your motor is configured and connected, open the motor’s TEST panel on the CONFIGURE or CONTROL tabs. Use the buttons to try turning your motor forwards or backwards at different power levels and check whether it moves as expected.

Motor test panel.

If the motor does not appear on the TEST panel, or if you notice unexpected behavior, check your machine’s LOGS tab for errors, and review the configuration.

Troubleshooting

If your motor is not working as expected, follow these steps:

  1. Check your machine logs on the LOGS tab to check for errors.
  2. Review this motor model’s documentation to ensure you have configured all required attributes.
  3. Check that all wires are securely attached to the correct pins.
  4. Click on the TEST panel on the CONFIGURE or CONTROL tab and test if you can use the motor there.

If none of these steps work, reach out to us on the Community Discord and we will be happy to help.

Next steps

For more configuration and usage info, see: