Merge pull request #2426 from caternuson/servo_update
Update analog feedback servo
This commit is contained in:
commit
f354a53718
5 changed files with 62 additions and 44 deletions
Binary file not shown.
Binary file not shown.
24
Feedback_Servo_Record_and_Play/feedback_calibrate/code.py
Normal file → Executable file
24
Feedback_Servo_Record_and_Play/feedback_calibrate/code.py
Normal file → Executable 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
|
||||
|
|
|
|||
59
Feedback_Servo_Record_and_Play/feedback_record_play/code.py
Normal file → Executable file
59
Feedback_Servo_Record_and_Play/feedback_record_play/code.py
Normal file → Executable 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
23
Feedback_Servo_Record_and_Play/feedback_seek/code.py
Normal file → Executable 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
|
||||
|
|
|
|||
Loading…
Reference in a new issue