-
Notifications
You must be signed in to change notification settings - Fork 8
Open
Description
Hello,
First of all, thank you for all of your incredible work on Circuitpython with Pimoroni! I really appreciate it!
I noticed that initializing multiple MMME encoders for gearmotors sometimes caused the program to hang. I tested the read_encoders example.
Using a single encoder instead of four worked flawlessly multiple times.
Next, I checked the rotaryio CircuitPython documentation.
Is it possible that the encoders need to be deinitialized each time?
Something like:
def get_position(self, motor):
if motor == "FL": # front left
with rotaryio.IncrementalEncoder(board.ENCODER_A_B, board.ENCODER_A_A, divisor=1) as encoder:
position = encoder.position + self.encoder_FL_prev_position
self.encoder_FL_prev_position = position
return position * 360 / self.counts_per_rev
elif motor == "BL": # back left
with rotaryio.IncrementalEncoder(board.ENCODER_B_B, board.ENCODER_B_A, divisor=1) as encoder:
position = encoder.position + self.encoder_BL_prev_position
self.encoder_BL_prev_position = position
return position * 360 / self.counts_per_rev
elif motor == "BR": # back right
with rotaryio.IncrementalEncoder(board.ENCODER_C_B, board.ENCODER_C_A, divisor=1) as encoder:
position = encoder.position + self.encoder_BR_prev_position
self.encoder_BR_prev_position = position
return position * 360 / self.counts_per_rev
elif motor == "FR": # front right
with rotaryio.IncrementalEncoder(board.ENCODER_D_B, board.ENCODER_D_A, divisor=1) as encoder:
position = encoder.position + self.encoder_FR_prev_position
self.encoder_FR_prev_position = position
return position * 360 / self.counts_per_rev
My entire code is below.
import board
import pwmio
import digitalio
from adafruit_motor import motor
import rotaryio
import neopixel
class ScuttleBot:
def __init__(self):
print("Initializing ScuttleBot...")
self.wheel_dia = 36 # wheel diameter in mm
self.gear_ratio = 50 # motor gear ratio (IN:OUT)
self.counts_per_rev = 12 * self.gear_ratio # encoder counts per wheel revolution
# Motor constants
self.FREQUENCY = 25000 # Choose a frequency above human hearing
self.DECAY_MODE = motor.SLOW_DECAY # The decay mode affects how the motor
# responds, with SLOW_DECAY having improved spin
# threshold and speed-to-throttle linearity
print("--> Setting up user switch")
# Create a digitalinout object for the user switch
self.user_sw = digitalio.DigitalInOut(board.USER_SW)
self.user_sw.direction = digitalio.Direction.INPUT
self.user_sw.pull = digitalio.Pull.UP
print("--> Setting up neopixel")
# Create the neopixel object
self.led = neopixel.NeoPixel(board.LED_DATA, board.NUM_LEDS)
self.led.brightness = 0.05 # 5% brightness
self.led = self.led[0]
print("--> Setting up PWM motor objects")
# Create the pwm objects
self.pwm_a_n = pwmio.PWMOut(board.MOTOR_A_N, frequency=self.FREQUENCY)
self.pwm_a_p = pwmio.PWMOut(board.MOTOR_A_P, frequency=self.FREQUENCY)
self.pwm_b_p = pwmio.PWMOut(board.MOTOR_B_P, frequency=self.FREQUENCY)
self.pwm_b_n = pwmio.PWMOut(board.MOTOR_B_N, frequency=self.FREQUENCY)
self.pwm_c_p = pwmio.PWMOut(board.MOTOR_C_P, frequency=self.FREQUENCY)
self.pwm_c_n = pwmio.PWMOut(board.MOTOR_C_N, frequency=self.FREQUENCY)
self.pwm_d_p = pwmio.PWMOut(board.MOTOR_D_P, frequency=self.FREQUENCY)
self.pwm_d_n = pwmio.PWMOut(board.MOTOR_D_N, frequency=self.FREQUENCY)
print("--> Setting up motors")
# Create the motor objects
self.motor_FL = motor.DCMotor(self.pwm_a_n, self.pwm_a_p) # Front left motor, connected to A
self.motor_BL = motor.DCMotor(self.pwm_b_n, self.pwm_b_p) # Back left motor, connected to B
self.motor_BR = motor.DCMotor(self.pwm_c_p, self.pwm_c_n) # Back right motor, connected to C
self.motor_FR = motor.DCMotor(self.pwm_d_p, self.pwm_d_n) # Front right motor, connected to D
# Set the motor decay modes (if unset the default will be FAST_DECAY)
self.motor_FL.decay_mode = self.DECAY_MODE
self.motor_BL.decay_mode = self.DECAY_MODE
self.motor_BR.decay_mode = self.DECAY_MODE
self.motor_FR.decay_mode = self.DECAY_MODE
# setup encoder previous position variables to be continuously updated
self.encoder_FL_prev_position = 0.0
self.encoder_BL_prev_position = 0.0
self.encoder_BR_prev_position = 0.0
self.encoder_FR_prev_position = 0.0
print("Scuttlebot Initialized!")
def set_led(self, colors):
self.led = colors
def get_position(self, motor):
if motor == "FL":
with rotaryio.IncrementalEncoder(board.ENCODER_A_B, board.ENCODER_A_A, divisor=1) as encoder:
position = encoder.position + self.encoder_FL_prev_position
self.encoder_FL_prev_position = position
return position * 360 / self.counts_per_rev
elif motor == "BL":
with rotaryio.IncrementalEncoder(board.ENCODER_B_B, board.ENCODER_B_A, divisor=1) as encoder:
position = encoder.position + self.encoder_BL_prev_position
self.encoder_BL_prev_position = position
return position * 360 / self.counts_per_rev
elif motor == "BR":
with rotaryio.IncrementalEncoder(board.ENCODER_C_B, board.ENCODER_C_A, divisor=1) as encoder:
position = encoder.position + self.encoder_BR_prev_position
self.encoder_BR_prev_position = position
return position * 360 / self.counts_per_rev
elif motor == "FR":
with rotaryio.IncrementalEncoder(board.ENCODER_D_B, board.ENCODER_D_A, divisor=1) as encoder:
position = encoder.position + self.encoder_FR_prev_position
self.encoder_FR_prev_position = position
return position * 360 / self.counts_per_rev
else:
print('Choose a motor') # TODO: setup errors to throw
def button_pressed(self):
return not self.user_sw.value
def stop(self):
self.motor_FL.throttle = 0
self.motor_BL.throttle = 0
self.motor_BR.throttle = 0
self.motor_FR.throttle = 0
def forward(self, speed=0.5, squares=1):
distance = squares * 500 # distance in mm to travel
self.motor_FL.throttle = speed
self.motor_BL.throttle = speed
self.motor_BR.throttle = speed
self.motor_FR.throttle = speed
def backward(self, speed=0.5, squares=1):
distance = squares * 500 # distance in mm to travel
self.motor_FL.throttle = -speed
self.motor_BL.throttle = -speed
self.motor_BR.throttle = -speed
self.motor_FR.throttle = -speed
def left(self, speed=0.5, squares=1):
distance = squares * 500 # distance in mm to travel
self.motor_FL.throttle = -speed
self.motor_BL.throttle = speed
self.motor_BR.throttle = -speed
self.motor_FR.throttle = speed
def right(self, speed=0.5, squares=1):
distance = squares * 500 # distance in mm to travel
self.motor_FL.throttle = speed
self.motor_BL.throttle = -speed
self.motor_BR.throttle = speed
self.motor_FR.throttle = -speed
Thank you so much!
Metadata
Metadata
Assignees
Labels
No labels