The following CircuitPython code examples will sweep an attached motor's duty cycle from 0% to 100% in 2% increments in one direction. Each step of the duty cycle will hold for 1 second. The motor stops at the end of the code. During execution, the code prints the duty cycle as a throttle value for display in the REPL's Serial and Plotter windows.
The first portion of each example imports the needed libraries and instantiates the motor controller with a new PWM frequency. Change the frequency value to select the one that works best for the attached motor.
Each motor controller is implemented differently, so refer to the example's code description to change the controller's frequency. The examples describe the frequency setting techniques when using:
- Crickit FeatherWing and Crickit for Circuit Playground Express
- Motor FeatherWing and Motor Shield
- Breakout Boards and H-Bridge Chips
Upon initiation, the Crickit library sets the DC motor PWM frequency to 50Hz, useful for most brushed DC motors like the Yellow TT motor. It is possible to override the default if a custom PWM frequency is needed while still preserving the ability to use the Crickit library's motor statements such as motor.throttle
.
The Crickit library also initially sets the controller's decay mode to FAST_DECAY. We'll change the decay mode to SLOW_DECAY to take advantage of the resultant performance improvement.
The Crickit uses two internal GPIO pins for each of the two DC motor controllers. The internal pins reserved for the motor controllers are 18, 19, 22, and 23. This is the section of the example code that changes the PWM to a custom value:
PWM_FREQ = 25 # Custom PWM frequency; Crickit min/max 3Hz/720Hz, default is 50Hz DECAY_MODE = motor.SLOW_DECAY # Set controller to Slow Decay (braking) mode THROTTLE_HOLD = 1 # Hold the throttle (seconds) motor1 = crickit.dc_motor_1 motor2 = crickit.dc_motor_2 motor1.decay_mode = DECAY_MODE motor2.decay_mode = DECAY_MODE ss = crickit.seesaw # To access Seesaw motor pins ss.set_pwm_freq(22, PWM_FREQ) # Set motor1A pin to custom PWM frequency ss.set_pwm_freq(23, PWM_FREQ) # Set motor1B pin to custom PWM frequency ss.set_pwm_freq(19, PWM_FREQ) # Set motor2A pin to custom PWM frequency ss.set_pwm_freq(18, PWM_FREQ) # Set motor2B pin to custom PWM frequency
Line 1 defines the constant used for the custom PWM frequency value, followed by a constant that defines the controller's decay mode. A throttle holding constant (THROTTLE_HOLD
) of 1 second is used later in the example code. The next lines define names for the two Crickit motor controllers. Defining the names also instantiates the motor pin definitions that will be changed.
In lines 8 and 9, the decay mode is set for each motor instance using the decay mode constant defined earlier. Next we'll access each motor controller pin individually and reset the default PWM frequency. For example, the first pin of DC_Motor_1's controller is updated in line 12:
ss.set_pwm_freq(22, PWM_FREQ)
The PWM frequency of each pin is then set to the custom value stored in the PWM_FREQ
constant.
Example code for the Crickit FeatherWing and Circuit Playground Express Crickit:
# SPDX-FileCopyrightText: 2021 Jan Goolsbey for Adafruit Industries # SPDX-License-Identifier: MIT # Crickit PWM Frequency Example # for Adafruit Crickit FeatherWing (#3343) # and Circuit Playground Express Crickit(#3093) import time from adafruit_motor import motor from adafruit_crickit import crickit PWM_FREQ = 25 # Custom PWM frequency; Crickit min/max 3Hz/720Hz, default is 50Hz DECAY_MODE = motor.SLOW_DECAY # Set controller to Slow Decay (braking) mode THROTTLE_HOLD = 1 # Hold the throttle (seconds) motor1 = crickit.dc_motor_1 motor2 = crickit.dc_motor_2 motor1.decay_mode = DECAY_MODE motor2.decay_mode = DECAY_MODE ss = crickit.seesaw # To access Seesaw motor pins ss.set_pwm_freq(22, PWM_FREQ) # Set motor1A pin to custom PWM frequency ss.set_pwm_freq(23, PWM_FREQ) # Set motor1B pin to custom PWM frequency ss.set_pwm_freq(19, PWM_FREQ) # Set motor2A pin to custom PWM frequency ss.set_pwm_freq(18, PWM_FREQ) # Set motor2B pin to custom PWM frequency print("PWM frequency:", PWM_FREQ) # Display internal PWM frequency motor1.throttle = 0 # Stop motor1 motor2.throttle = 0 # Stop motor2 print((0,)) # Plot/print current throttle value time.sleep(THROTTLE_HOLD) # Hold at current throttle value # Sweep up through 50 duty cycle values for duty_cycle in range(0, 101, 2): throttle = duty_cycle / 100 # Convert to throttle value (0 to 1.0) motor1.throttle = throttle motor2.throttle = throttle print((throttle,)) # Plot/print current throttle value time.sleep(THROTTLE_HOLD) # Hold at current throttle value motor1.throttle = 0 # Stop motor1 motor2.throttle = 0 # Stop motor2 print((0,)) # Plot/print current throttle value time.sleep(THROTTLE_HOLD) # Hold at current throttle value
Upon instantiation, the adafruit_motorkit
MotorKit
class sets the DC motor PWM frequency to a default of 1600Hz and the controller's decay mode to FAST_DECAY. Changing the frequency and decay mode to a custom value is accomplished using a MotorKit
parameter after instantiation.
PWM_FREQ = 25 # Custom PWM frequency; MotorKit min/maz 24Hz/2100Hz, default is 1600Hz DECAY_MODE = motor.SLOW_DECAY # Set controller to Slow Decay (braking) mode THROTTLE_HOLD = 1 # Hold the throttle (seconds) # Instantiate motor controller wing motorwing = MotorKit(i2c=board.I2C(), address=0x60) motorwing.frequency = PWM_FREQ # Set custom PWM frequency print("PWM frequency:", motorwing.frequency) # Verify internal PWM frequency motor1 = motorwing.motor1 motor1.decay_mode = DECAY_MODE
The first line defines the constant used for the custom PWM frequency value. A constant value for the decay mode is defined as SLOW_DECAY, followed by a throttle holding constant (THROTTLE_HOLD
) that's used later in the example code. Line 6 is the typical statement used to instantiate the Motor FeatherWing or Shield. Line 7 updates the MotorKit
PWM frequency parameter with the custom value stored in the PWM_FREQ
constant.
After the motor is instantiated in line 9, the controller's decay mode is set to SLOW_DECAY.
Example code for Motor FeatherWing and MotorShield:
# SPDX-FileCopyrightText: 2021 Jan Goolsbey for Adafruit Industries # SPDX-License-Identifier: MIT # Motor FeatherWing PWM Frequency Example # for Adafruit Motor FeatherWing (#3243) and Motor Shield (#1438) import time import board from adafruit_motor import motor from adafruit_motorkit import MotorKit PWM_FREQ = 25 # Custom PWM frequency; MotorKit min/maz 24Hz/2100Hz, default is 1600Hz DECAY_MODE = motor.SLOW_DECAY # Set controller to Slow Decay (braking) mode THROTTLE_HOLD = 1 # Hold the throttle (seconds) # Instantiate motor controller wing motorwing = MotorKit(i2c=board.I2C(), address=0x60) motorwing.frequency = PWM_FREQ # Set custom PWM frequency print("PWM frequency:", motorwing.frequency) # Verify internal PWM frequency motor1 = motorwing.motor1 motor1.decay_mode = DECAY_MODE motor1.throttle = 0 # Stop motor1 print((0,)) # Plot/print current throttle value time.sleep(THROTTLE_HOLD) # Hold at current throttle value # Sweep up through 50 duty cycle values for duty_cycle in range(0, 101, 2): throttle = duty_cycle / 100 # Convert to throttle value (0 to 1.0) motor1.throttle = throttle print((throttle,)) # Plot/print current throttle value time.sleep(THROTTLE_HOLD) # Hold at current throttle value motor1.throttle = 0 # Stop motor1 print((0,)) # Plot/print current throttle value time.sleep(THROTTLE_HOLD) # Hold at current throttle value
The adafruit_motor
library's DCMotor
class is the one to use with Adafruit motor controller breakout boards and H-bridge integrated circuits. Upon instantiation, the library works with the pwmio.PWMOut
class to define which GPIO pins to use to drive the motor, set the 500Hz default PWM frequency and FAST_DECAY controller mode. We'll change the default frequency when the GPIO pins are defined and will change the controller's decay mode to SLOW_DECAY.
Refer to your selected breakout board's or H-bridge chip's learning guide for how to properly connect it to a microcontroller.
PWM_FREQ = 25 # Custom PWM frequency in Hz; PWMOut min/max 1Hz/50kHz, default is 500Hz DECAY_MODE = motor.SLOW_DECAY # Set controller to Slow Decay (braking) mode THROTTLE_HOLD = 1 # Hold the throttle (seconds) # DC motor setup; Set pins to custom PWM frequency pwm_a = pwmio.PWMOut(PWM_PIN_A, frequency=PWM_FREQ) pwm_b = pwmio.PWMOut(PWM_PIN_B, frequency=PWM_FREQ) motor1 = motor.DCMotor(pwm_a, pwm_b) motor1.decay_mode = DECAY_MODE
The first line defines the constant used for the custom PWM frequency value. Next, a constant value for the controller's mode is defined as SLOW_DECAY, followed by a throttle holding constant (THROTTLE_HOLD
) that's used later in the example code. The two GPIO pins needed for the motor controller are defined next. Choose two pins that have their own unused PWM channel.
Lines 6 and 7 use pwmio.PWMOut
to establish the pins and set the custom PWM frequency. After the motor is instantiated as motor1
in line 8, the controller's decay mode is set to SLOW_DECAY.
Example code for breakout motor controller boards:
# SPDX-FileCopyrightText: 2021 Jan Goolsbey for Adafruit Industries # SPDX-License-Identifier: MIT # Breakout PWM Frequency Example # for Adafruit motor controller breakout boards and H-bridge drivers # TB6612 (#2448), DRV8833 (#3297), DRV8871 (#3190), L9110 (#4489), L293D (#807) import time import board import pwmio from adafruit_motor import motor PWM_PIN_A = board.D5 # Pick two PWM pins on their own channels PWM_PIN_B = board.D6 PWM_FREQ = 25 # Custom PWM frequency in Hz; PWMOut min/max 1Hz/50kHz, default is 500Hz DECAY_MODE = motor.SLOW_DECAY # Set controller to Slow Decay (braking) mode THROTTLE_HOLD = 1 # Hold the throttle (seconds) # DC motor setup; Set pins to custom PWM frequency pwm_a = pwmio.PWMOut(PWM_PIN_A, frequency=PWM_FREQ) pwm_b = pwmio.PWMOut(PWM_PIN_B, frequency=PWM_FREQ) motor1 = motor.DCMotor(pwm_a, pwm_b) motor1.decay_mode = DECAY_MODE motor1.throttle = 0 # Stop motor1 print((0,)) # Plot/print current throttle value # Sweep up through 50 duty cycle values for duty_cycle in range(0, 101, 2): throttle = duty_cycle / 100 # Convert to throttle value (0 to 1.0) motor1.throttle = throttle print((throttle,)) # Plot/print current throttle value time.sleep(1) # Hold at current throttle value motor1.throttle = 0 # Stop motor1 print((0,)) # Plot/print current throttle value
Text editor powered by tinymce.