-
Notifications
You must be signed in to change notification settings - Fork 0
/
servo_control.py
72 lines (59 loc) · 2 KB
/
servo_control.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import board
import busio
import adafruit_pca9685
import time
class Servo:
def __init__(self):
i2c = busio.I2C(board.SCL, board.SDA)
self.hat = adafruit_pca9685.PCA9685(i2c, address=0x54)
self.hat.frequency = 50 #50 Hz
#in1 needs to be high, in2 needs to be low
self.a1=self.hat.channels[4]
self.a2=self.hat.channels[3]
self.b2=self.hat.channels[5]
self.b1=self.hat.channels[6]
self.servo1 = self.hat.channels[2]
self.servo2 = self.hat.channels[7]
#matlabs polyfit used to find coefficients of line to convert angle to pwm
self.m = 51.11
self.b = 6500
def turn_on(self):
self.a1.duty_cycle = 0x0000
self.b1.duty_cycle = 0x0000
self.a2.duty_cycle = 0xffff
self.b2.duty_cycle = 0xffff
def turn_off(self):
self.a1.duty_cycle = 0x0000
self.b1.duty_cycle = 0x0000
self.a2.duty_cycle = 0x0000
self.b2.duty_cycle = 0x0000
#1ms duty cycle = -90d -> 0x0ccc or 3276
#1.5ms duty cycle = 0d -> 0x1333
#2ms duty cycle = 90d -> 0x1999 or 6553
def test(self):
#testing shows range from ~4200 to ~8900
j=0
while(j<1):
for i in range(4000, 9500, 20):
print(i)
self.servo1.duty_cycle = i
time.sleep(0.5)
for i2 in range(4500, 9000, 200):
print(i2)
self.servo2.duty_cycle = i2
time.sleep(0.5)
j += 1
#input angle ranges from -45d to 45d
#servo datasheet says range is 180d but it is not
#also have no way of measuring angle of servos so this is rough estimate
def set_Xangle(self, theta):
pwm = round(self.m*theta + self.b)
self.servo1.duty_cycle = pwm
def set_Yangle(self, theta):
pwm = round(-self.m*theta + self.b)
self.servo2.duty_cycle = pwm
if __name__ == "__main__":
a = Servo()
a.turn_on()
a.test()
a.turn_off()