Skip to content

Commit f354a53

Browse files
authored
Merge pull request #2426 from caternuson/servo_update
Update analog feedback servo
2 parents 0c4256a + 829e027 commit f354a53

File tree

5 files changed

+62
-44
lines changed

5 files changed

+62
-44
lines changed
Binary file not shown.
Binary file not shown.

Feedback_Servo_Record_and_Play/feedback_calibrate/code.py

100644100755
Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# SPDX-FileCopyrightText: 2019 Carter Nelson for Adafruit Industries
1+
# SPDX-FileCopyrightText: 2023 Carter Nelson for Adafruit Industries
22
#
33
# SPDX-License-Identifier: MIT
44

@@ -7,12 +7,12 @@
77
import time
88
import board
99
import pwmio
10-
from adafruit_motor import servo
1110
from analogio import AnalogIn
11+
from adafruit_motor import servo
1212

1313
# Pin setup
1414
SERVO_PIN = board.A1
15-
FEEDBACK_PIN = board.A5
15+
FEEDBACK_PIN = board.A3
1616

1717
# Calibration setup
1818
ANGLE_MIN = 0
@@ -27,20 +27,34 @@
2727
feedback = AnalogIn(FEEDBACK_PIN)
2828

2929
print("Servo feedback calibration.")
30+
31+
# Helper function to average analog readings
32+
def read_feedback(samples=10, delay=0.01):
33+
reading = 0
34+
for _ in range(samples):
35+
reading += feedback.value
36+
time.sleep(delay)
37+
return int(reading/samples)
38+
3039
# Move to MIN angle
3140
print("Moving to {}...".format(ANGLE_MIN), end="")
3241
servo.angle = ANGLE_MIN
3342
time.sleep(2)
3443
print("Done.")
35-
feedback_min = feedback.value
44+
feedback_min = read_feedback()
45+
3646
# Move to MAX angle
3747
print("Moving to {}...".format(ANGLE_MAX), end="")
3848
servo.angle = ANGLE_MAX
3949
time.sleep(2)
4050
print("Done.")
41-
feedback_max = feedback.value
51+
feedback_max = read_feedback()
52+
4253
# Print results
54+
print("="*20)
4355
print("Feedback MIN = {}".format(feedback_min))
4456
print("Feedback MAX = {}".format(feedback_max))
57+
print("="*20)
58+
4559
# Deactivate servo
4660
servo.angle = None
Lines changed: 26 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,37 @@
1-
# SPDX-FileCopyrightText: 2019 Carter Nelson for Adafruit Industries
1+
# SPDX-FileCopyrightText: 2023 Carter Nelson for Adafruit Industries
22
#
33
# SPDX-License-Identifier: MIT
44

55
# Example code for recording and playing back servo motion with a
66
# analog feedback servo
7+
# pylint: disable=redefined-outer-name
78

89
import time
910
import board
1011
import pwmio
12+
import keypad
1113
from simpleio import map_range
1214
from adafruit_motor import servo
1315
from analogio import AnalogIn
14-
from digitalio import DigitalInOut, Direction, Pull
16+
from digitalio import DigitalInOut, Direction
1517

1618
# Pin setup
1719
RECORD_PIN = board.D10
1820
PLAY_PIN = board.D9
1921
LED_PIN = board.D13
2022
SERVO_PIN = board.A1
21-
FEEDBACK_PIN = board.A5
23+
FEEDBACK_PIN = board.A3
2224

2325
# Record setup
24-
CALIB_MIN = 2816
25-
CALIB_MAX = 49632
26+
CALIB_MIN = 15377
27+
CALIB_MAX = 42890
2628
ANGLE_MIN = 0
2729
ANGLE_MAX = 180
2830
SAMPLE_COUNT = 512
2931
SAMPLE_DELAY = 0.025
3032

31-
# Setup record button
32-
record_button = DigitalInOut(RECORD_PIN)
33-
record_button.direction = Direction.INPUT
34-
record_button.pull = Pull.UP
35-
36-
# Setup play button
37-
play_button = DigitalInOut(PLAY_PIN)
38-
play_button.direction = Direction.INPUT
39-
play_button.pull = Pull.UP
33+
# Setup buttons
34+
buttons = keypad.Keys((RECORD_PIN, PLAY_PIN), value_when_pressed=False, pull=True)
4035

4136
# Setup LED
4237
led = DigitalInOut(LED_PIN)
@@ -59,8 +54,12 @@
5954
def play_servo():
6055
print("Playing...", end="")
6156
count = 0
62-
while play_button.value:
57+
while True:
6358
print(".", end="")
59+
event = buttons.events.get()
60+
if event:
61+
if event.pressed and event.key_number == 1:
62+
break
6463
angle = position[count]
6564
if angle is None:
6665
break
@@ -80,8 +79,12 @@ def record_servo():
8079
led.value = True
8180
print("Recording...", end="")
8281
count = 0
83-
while record_button.value:
82+
while True:
8483
print(".", end='')
84+
event = buttons.events.get()
85+
if event:
86+
if event.pressed and event.key_number == 0:
87+
break
8588
position[count] = map_range(feedback.value, CALIB_MIN, CALIB_MAX, ANGLE_MIN, ANGLE_MAX)
8689
count += 1
8790
if count >= SAMPLE_COUNT:
@@ -92,20 +95,10 @@ def record_servo():
9295
time.sleep(0.250)
9396

9497
while True:
95-
if not record_button.value:
96-
time.sleep(0.01)
97-
# wait for released
98-
while not record_button.value:
99-
pass
100-
time.sleep(0.02)
101-
# OK released!
102-
record_servo()
103-
104-
if not play_button.value:
105-
time.sleep(0.01)
106-
# wait for released
107-
while not play_button.value:
108-
pass
109-
time.sleep(0.02)
110-
# OK released!
111-
play_servo()
98+
event = buttons.events.get()
99+
if event:
100+
if event.pressed:
101+
if event.key_number == 0:
102+
record_servo()
103+
elif event.key_number == 1:
104+
play_servo()

Feedback_Servo_Record_and_Play/feedback_seek/code.py

100644100755
Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
1-
# SPDX-FileCopyrightText: 2019 Carter Nelson for Adafruit Industries
1+
# SPDX-FileCopyrightText: 2023 Carter Nelson for Adafruit Industries
22
#
33
# SPDX-License-Identifier: MIT
44

55
# Example code for using analog feedback value to seek a position
6+
import time
67
import board
78
import pwmio
9+
from analogio import AnalogIn
810
from simpleio import map_range
911
from adafruit_motor import servo
10-
from analogio import AnalogIn
1112

1213
# Demo angles
1314
angles = [0, 180, 0, 45, 180]
1415

1516
# Pin setup
1617
SERVO_PIN = board.A1
17-
FEEDBACK_PIN = board.A5
18+
FEEDBACK_PIN = board.A3
1819

1920
# Calibration setup
20-
CALIB_MIN = 18112
21-
CALIB_MAX = 49408
21+
CALIB_MIN = 15377
22+
CALIB_MAX = 42890
2223
ANGLE_MIN = 0
2324
ANGLE_MAX = 180
2425

@@ -31,9 +32,11 @@
3132
feedback = AnalogIn(FEEDBACK_PIN)
3233

3334
def get_position():
35+
'''Turns analog feedback raw ADC value into angle.'''
3436
return map_range(feedback.value, CALIB_MIN, CALIB_MAX, ANGLE_MIN, ANGLE_MAX)
3537

3638
def seek_position(position, tolerance=2):
39+
'''Move to specified angle and wait until move is complete.'''
3740
servo.angle = position
3841

3942
while abs(get_position() - position) > tolerance:
@@ -42,5 +45,13 @@ def seek_position(position, tolerance=2):
4245
print("Servo feedback seek example.")
4346
for angle in angles:
4447
print("Moving to {}...".format(angle), end="")
48+
start = time.monotonic()
4549
seek_position(angle)
46-
print("Done.")
50+
end = time.monotonic()
51+
print("Done. Move took {} seconds.".format(end-start))
52+
print("Pausing for 1 second.")
53+
time.sleep(1)
54+
55+
# Deactivate servo
56+
print("Finished. Deactivating servo.")
57+
servo.angle = None

0 commit comments

Comments
 (0)