Merge pull request #2426 from caternuson/servo_update

Update analog feedback servo
This commit is contained in:
Anne Barela 2023-03-04 12:50:15 -05:00 committed by GitHub
commit f354a53718
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 62 additions and 44 deletions

View file

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2019 Carter Nelson for Adafruit Industries
# SPDX-FileCopyrightText: 2023 Carter Nelson for Adafruit Industries
#
# SPDX-License-Identifier: MIT
@ -7,12 +7,12 @@
import time
import board
import pwmio
from adafruit_motor import servo
from analogio import AnalogIn
from adafruit_motor import servo
# Pin setup
SERVO_PIN = board.A1
FEEDBACK_PIN = board.A5
FEEDBACK_PIN = board.A3
# Calibration setup
ANGLE_MIN = 0
@ -27,20 +27,34 @@ servo.angle = None
feedback = AnalogIn(FEEDBACK_PIN)
print("Servo feedback calibration.")
# Helper function to average analog readings
def read_feedback(samples=10, delay=0.01):
reading = 0
for _ in range(samples):
reading += feedback.value
time.sleep(delay)
return int(reading/samples)
# Move to MIN angle
print("Moving to {}...".format(ANGLE_MIN), end="")
servo.angle = ANGLE_MIN
time.sleep(2)
print("Done.")
feedback_min = feedback.value
feedback_min = read_feedback()
# Move to MAX angle
print("Moving to {}...".format(ANGLE_MAX), end="")
servo.angle = ANGLE_MAX
time.sleep(2)
print("Done.")
feedback_max = feedback.value
feedback_max = read_feedback()
# Print results
print("="*20)
print("Feedback MIN = {}".format(feedback_min))
print("Feedback MAX = {}".format(feedback_max))
print("="*20)
# Deactivate servo
servo.angle = None

View file

@ -1,42 +1,37 @@
# SPDX-FileCopyrightText: 2019 Carter Nelson for Adafruit Industries
# SPDX-FileCopyrightText: 2023 Carter Nelson for Adafruit Industries
#
# SPDX-License-Identifier: MIT
# Example code for recording and playing back servo motion with a
# analog feedback servo
# pylint: disable=redefined-outer-name
import time
import board
import pwmio
import keypad
from simpleio import map_range
from adafruit_motor import servo
from analogio import AnalogIn
from digitalio import DigitalInOut, Direction, Pull
from digitalio import DigitalInOut, Direction
# Pin setup
RECORD_PIN = board.D10
PLAY_PIN = board.D9
LED_PIN = board.D13
SERVO_PIN = board.A1
FEEDBACK_PIN = board.A5
FEEDBACK_PIN = board.A3
# Record setup
CALIB_MIN = 2816
CALIB_MAX = 49632
CALIB_MIN = 15377
CALIB_MAX = 42890
ANGLE_MIN = 0
ANGLE_MAX = 180
SAMPLE_COUNT = 512
SAMPLE_DELAY = 0.025
# Setup record button
record_button = DigitalInOut(RECORD_PIN)
record_button.direction = Direction.INPUT
record_button.pull = Pull.UP
# Setup play button
play_button = DigitalInOut(PLAY_PIN)
play_button.direction = Direction.INPUT
play_button.pull = Pull.UP
# Setup buttons
buttons = keypad.Keys((RECORD_PIN, PLAY_PIN), value_when_pressed=False, pull=True)
# Setup LED
led = DigitalInOut(LED_PIN)
@ -59,8 +54,12 @@ print("Servo RecordPlay")
def play_servo():
print("Playing...", end="")
count = 0
while play_button.value:
while True:
print(".", end="")
event = buttons.events.get()
if event:
if event.pressed and event.key_number == 1:
break
angle = position[count]
if angle is None:
break
@ -80,8 +79,12 @@ def record_servo():
led.value = True
print("Recording...", end="")
count = 0
while record_button.value:
while True:
print(".", end='')
event = buttons.events.get()
if event:
if event.pressed and event.key_number == 0:
break
position[count] = map_range(feedback.value, CALIB_MIN, CALIB_MAX, ANGLE_MIN, ANGLE_MAX)
count += 1
if count >= SAMPLE_COUNT:
@ -92,20 +95,10 @@ def record_servo():
time.sleep(0.250)
while True:
if not record_button.value:
time.sleep(0.01)
# wait for released
while not record_button.value:
pass
time.sleep(0.02)
# OK released!
record_servo()
if not play_button.value:
time.sleep(0.01)
# wait for released
while not play_button.value:
pass
time.sleep(0.02)
# OK released!
play_servo()
event = buttons.events.get()
if event:
if event.pressed:
if event.key_number == 0:
record_servo()
elif event.key_number == 1:
play_servo()

23
Feedback_Servo_Record_and_Play/feedback_seek/code.py Normal file → Executable file
View file

@ -1,24 +1,25 @@
# SPDX-FileCopyrightText: 2019 Carter Nelson for Adafruit Industries
# SPDX-FileCopyrightText: 2023 Carter Nelson for Adafruit Industries
#
# SPDX-License-Identifier: MIT
# Example code for using analog feedback value to seek a position
import time
import board
import pwmio
from analogio import AnalogIn
from simpleio import map_range
from adafruit_motor import servo
from analogio import AnalogIn
# Demo angles
angles = [0, 180, 0, 45, 180]
# Pin setup
SERVO_PIN = board.A1
FEEDBACK_PIN = board.A5
FEEDBACK_PIN = board.A3
# Calibration setup
CALIB_MIN = 18112
CALIB_MAX = 49408
CALIB_MIN = 15377
CALIB_MAX = 42890
ANGLE_MIN = 0
ANGLE_MAX = 180
@ -31,9 +32,11 @@ servo.angle = None
feedback = AnalogIn(FEEDBACK_PIN)
def get_position():
'''Turns analog feedback raw ADC value into angle.'''
return map_range(feedback.value, CALIB_MIN, CALIB_MAX, ANGLE_MIN, ANGLE_MAX)
def seek_position(position, tolerance=2):
'''Move to specified angle and wait until move is complete.'''
servo.angle = position
while abs(get_position() - position) > tolerance:
@ -42,5 +45,13 @@ def seek_position(position, tolerance=2):
print("Servo feedback seek example.")
for angle in angles:
print("Moving to {}...".format(angle), end="")
start = time.monotonic()
seek_position(angle)
print("Done.")
end = time.monotonic()
print("Done. Move took {} seconds.".format(end-start))
print("Pausing for 1 second.")
time.sleep(1)
# Deactivate servo
print("Finished. Deactivating servo.")
servo.angle = None