forked from MakersTeam/Edison
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathServo.py
More file actions
258 lines (198 loc) · 7.87 KB
/
Servo.py
File metadata and controls
258 lines (198 loc) · 7.87 KB
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
#!/usr/bin/env python
"""
Servo.py - Servo library for Intel(R) Edison
This library is free software; you can redistribute it and/or
modify it.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
"""
"""
A servo is activated by creating an instance of the Servo class
passing the desired pin to the attach() method. The servos are
pulsed using the write() method.
NOTE: This library uses the MRAA library for use the PWM outputs.
The methods are:
Servo - Class for manipulating servo motors connected to
Arduino Expansion Board for Intel Edison.
attach() - Attaches a servo motor to an PWM pin.
writeMicroseconds() - Sets the servo pulse width in microseconds.
write() - Sets the servo angle in degrees.
readwriteMicroseconds() - Gets the last written servo pulse width in microseconds.
read() - Gets the last written servo pulse width as an angle between 0 and 180.
getName() - Gets the reference name of the servo motor.
getPin() - Gets the pin where the servo motor is attached.
getPulseWidth() - Gets the current limits for the servo pulse width.
getFrequency() - Gets the current frequency.
getPeriod() - Gets the current period.
setWidth() - Sets new values for the limits of the servo pulse width.
setFrequency() - Sets a new value for frequency.
setPeriod() - Sets a new value for the period.
"""
"""
Revision History
----------------------------------------------------------
Author Date Description
----------------------------------------------------------
Diego Villalobos 02-12-2015 Library created
Diego Villalobos 04-22-2015 Bug related with the period has been corrected
"""
import mraa
# Default constants
DEFAULT_FREQ = 50.0 # Default frequency in Hertz for PWM signal
MIN_PULSE_WIDTH = 550.0 # The shortest pulse
MAX_PULSE_WIDTH = 2500.0 # The longest pulse
NEUTRAL_PULSE_WIDTH = 1500.0 # Neutral pulse sent
def mapValue(value, in_min, in_max, out_min, out_max):
"""
Returns a new value mapped in a desired range.
Parameters:
value: value to be mapped
in_min - in_max: limits of the range where the value is
out_min - out_max: limits of the range where the value will be mapped
"""
return (value - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
###############
# Servo Class #
###############
class Servo:
def __init__(self, name = "myServo", minWidth = MIN_PULSE_WIDTH, maxWidth = MAX_PULSE_WIDTH, frequency = DEFAULT_FREQ):
"""
Initialize a new servo object.
Parameters:
name: servo name for future references.
minWidth: minimum limit for the servo pulse width. By default 550usec.
maxWidth: maximum limit for the servo pulse width. By default 2500usec.
frequency: frequency of PWM signal. By default 50Hz.
"""
self._name = name
self._pinAttached = None
self._pwm = None
self._minWidth = minWidth
self._maxWidth = maxWidth
self._frequency = frequency
self._period = round(1.0/frequency,4)
self._uSecs = mapValue(90, 0, 180, self._minWidth, self._maxWidth)
def __str__(self):
"""
Returns the current servo motor settings.
"""
return "Servo reference name: " + self.getName() + "\n" \
+ "Pin attached: " + str(self.getPin()) + "\n" \
+ "Range width (uSec): [" + str(self.getPulseWidth()[0]) + ", " + str(self.getPulseWidth()[1]) + "]" + "\n" \
+ "Frequency: " + str(self.getFrequency()) + "Hz" + "\n" \
+ "Period: " + str(self.getPeriod()) + "sec" + "\n" \
+ "Pulse width: " + str(self.readMicroseconds()) + "uSec" + "\n" \
+ "Angle set: " + str(self.read())
def attach(self, pin):
"""
Attaches a servo motor to a PWM pin.
Parameters:
pin: pin where the servo motor will be attached. Currently only pins 3, 5, 6, and 9 are supported.
"""
if pin in [3, 5, 6, 9]:
self._pinAttached = pin
else:
while True: # Keep asking for a valid pin.
print "The pin '" + str(pin) + "' is not a valid input. The valid pins are 3, 5, 6 or 9."
pin = raw_input("Select a valid pin: ")
if pin in ["3", "5", "6", "9"]:
pin = int(pin)
self._pinAttached = pin
break
# Configure the selected pin as PWM output.
if self._pinAttached != None:
self._pwm = mraa.Pwm(self._pinAttached)
self._pwm.period(self._period)
self._pwm.enable(True)
self._pwm.write((self._uSecs/1000000.0)/self._period)
def writeMicroseconds(self, uSecs):
"""
Sets the servo pulse width in microseconds.
Parameters:
uSecs: pulse width in microseconds.
"""
# Check if the input value is in the valid range.
if uSecs < self._minWidth:
uSecs = self._minWidth
if uSecs > self._maxWidth:
uSecs = self._maxWidth
self._uSecs = uSecs
if self._pwm != None:
self._pwm.write((self._uSecs/1000000.0)/self._period)
def write(self, angle):
"""
Sets the servo angle in degrees.
Parameters:
angle: position as an angle in degrees.
"""
# Check if the angle is between 0 and 180.
if angle < 0:
angle = 0
if angle > 180:
angle = 180
self.writeMicroseconds(mapValue(angle, 0, 180, self._minWidth, self._maxWidth))
def readMicroseconds(self):
"""
Returns the last written servo pulse width in microseconds.
"""
return self._uSecs
def read(self):
"""
Returns the last written servo pulse width as an angle between 0 and 180.
"""
return mapValue(self._uSecs, self._minWidth, self._maxWidth, 0, 180)
def getName(self):
"""
Returns the reference name of the servo motor.
"""
return self._name
def getPin(self):
"""
Returns the pin where the servo motor is attached.
"""
return self._pinAttached
def getPulseWidth(self):
"""
Returns the current limits for the servo pulse width.
"""
return [self._minWidth, self._maxWidth]
def getFrequency(self):
"""
Returns the current frequency.
"""
return self._frequency
def getPeriod(self):
"""
Returns the current period.
"""
return self._period
def setWidth(self, minWidth, maxWidth):
"""
Sets new values for the limits of the servo pulse width.
Parameters:
minWidth: new minimum limit for the servo pulse width.
maxWidth: new maximum limit for the servo pulse width.
"""
self._minWidth = minWidth
self._maxWidth = maxWidth
def setFrequency(self, frequency):
"""
Sets a new value for frequency.
Parameters:
frequency: new frequency of PWM signal.
"""
# Sets frequency and then period.
self._frequency = frequency
self._period = round(1.0/frequency,4)
self._pwm.period(self._period)
def setPeriod(self, period):
"""
Sets a new value for period.
Parameters:
period: new period of PWM signal.
"""
# Sets period and then frequency
self._period = period
self._pwm.period(self._period)
self._frequency = round(1/period,4)