-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmotor.py
106 lines (85 loc) · 3.22 KB
/
motor.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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import gpiozero as gz
from gpiozero.pins.mock import MockFactory
from time import sleep
import abc
# the time to wait between steps
STEP_TIME = .002
# gz.Device.pin_factory = MockFactory()
class Motor:
"""
Base class for both bipolar and unipolar stepper motors.
"""
def __init__(self, step_size):
self.step_size = step_size
def __str__(self):
return "Motor"
def degrees(self, deg, **kwargs):
steps = int(deg / self.step_size)
self.step(steps, STEP_TIME, **kwargs)
def coast(self):
"""
Lets the motor coast. Should be overridden by subclasses that support coasting.
"""
raise NotImplementedError
@abc.abstractmethod
def step(self, n=1):
raise NotImplementedError
class BipolarMotor(Motor):
"""
A bipolar motor, driven through a stepper motor driver
using a step pin and a direction pin.
"""
def __init__(self, step_pin, dir_pin, step_size):
super().__init__(step_size)
self.step_dev = gz.DigitalOutputDevice(step_pin)
self.dir_dev = gz.DigitalOutputDevice(dir_pin)
def __str__(self):
return "BipolarMotor({},{})".format(self.step_dev.pin, self.dir_dev.pin)
def step(self, n=1):
if n < 0:
n = -n
reverse = True
else:
reverse = False
print("stepping {} {}".format(n, "bwd" if reverse else "fwd"))
self.dir_dev.value = reverse
self.step_dev.blink(STEP_TIME, STEP_TIME, n, False)
# for i in range(n):
# self.step_dev.toggle()
# sleep(STEP_TIME)
def coast(self):
raise Exception("Coasting not supported for this bipolar motor.")
class UnipolarMotor(Motor):
def __init__(self, a0, a1, b0, b1, step_size, **kwargs):
super().__init__(step_size)
if "reverse" in kwargs and kwargs["reverse"]:
a0, a1, b0, b1 = b1, b0, a1, a0
self.a0 = gz.DigitalOutputDevice(a0)
self.a1 = gz.DigitalOutputDevice(a1)
self.b0 = gz.DigitalOutputDevice(b0)
self.b1 = gz.DigitalOutputDevice(b1)
self.phases = [[self.a0], [self.a1], [self.b0], [self.b1]]
self.phase_idx = 0
"""Can be freely chosen to simplify debugging."""
self.name = "UnipolarMotor({},{},{},{})".format(self.a0.pin, self.a1.pin, self.b0.pin, self.b1.pin)
def __str__(self):
return self.name
def step(self, n=1, step_time=STEP_TIME, **kwargs):
if 'halfstep' in kwargs and kwargs['halfstep']:
phases = [[self.a0], [self.a0, self.a1], [self.a1], [self.a1, self.b0], [self.b0], [self.b0, self.b1], [self.b1], [self.b1, self.a0]]
else:
phases = self.phases
if n < 0:
n = -n
reverse = True
else:
reverse = False
print("{} stepping {} {}".format(self, n, "bwd" if reverse else "fwd"))
phase_step = -1 if reverse else 1
for i in range(n):
[p.off() for p in phases[self.phase_idx]]
self.phase_idx = (self.phase_idx + phase_step) % len(phases)
[p.on() for p in phases[self.phase_idx]]
sleep(step_time)
def coast(self):
[p.off() for p in [self.a0, self.a1, self.b0, self.b1]]