1
2
3
4
5
6
7 """
8 This code was written to work with the Pololu Qik 2s9v1 motor controller.
9 http://www.pololu.com/catalog/product/1110
10
11 by Carl J. Nobile
12
13 THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 SOFTWARE.
20 """
21 __docformat__ = "reStructuredText en"
22
23
24 from .qik import Qik
25
26 __version__ = '1.0.0'
27 __version_info__ = tuple([int(num) for num in __version__.split('.')])
28
29
31 """
32 Implementation of the Pololu motor controller interface for the Qik 2s9v1
33 board.
34 """
35 DEFAULT_DEVICE_ID = 0x09
36 DEFAULT_SERIAL_TIMEOUT = 0.262
37 _COMMAND = {
38 'get-fw-version': 0x01,
39 'get-error': 0x02,
40 'get-config': 0x03,
41 'set-config': 0x04,
42 'm0-coast': 0x06,
43 'm1-coast': 0x07,
44 'm0-forward-7bit': 0x08,
45 'm0-forward-8bit': 0x09,
46 'm0-reverse-7bit': 0x0A,
47 'm0-reverse-8bit': 0x0B,
48 'm1-forward-7bit': 0x0C,
49 'm1-forward-8bit': 0x0D,
50 'm1-reverse-7bit': 0x0E,
51 'm1-reverse-8bit': 0x0F,
52 }
53 _ERRORS = {
54 0: 'OK',
55 1: 'Bit 0 Unused',
56 2: 'Bit 1 Unused',
57 4: 'Bit 2 Unused',
58 8: 'Data Overrun Error',
59 16: 'Frame Error',
60 32: 'CRC Error',
61 64: 'Format Error',
62 128: 'Timeout Error',
63 }
64 DEVICE_ID = 0x00
65 PWM_PARAM = 0x01
66 MOTOR_ERR_SHUTDOWN = 0x02
67 SERIAL_TIMEOUT = 0x03
68 _CONFIG_NUM = {
69 DEVICE_ID: 'Device ID',
70 PWM_PARAM: 'PWM Parameter',
71 MOTOR_ERR_SHUTDOWN: 'Shutdown Motors on Error',
72 SERIAL_TIMEOUT: 'Serial Error',
73 }
74 _CONFIG_PWM = {
75 0: (31500, '7-Bit, PWM Frequency 31.5kHz'),
76 1: (15700, '8-Bit, PWM Frequency 15.7 kHz'),
77 2: (7800, '7-Bit, PWM Frequency 7.8 kHz'),
78 3: (3900, '8-Bit, PWM Frequency 3.9 kHz'),
79 }
80 _CONFIG_PWM_TO_VALUE = dict(((v[0], k) for k, v in _CONFIG_PWM.items()))
81
82 - def __init__(self, device, baud=38400, readTimeout=None, writeTimeout=None,
83 log=None):
87
93
95 """
96 Get the firmware version of the Qik 2s9v1 hardware.
97
98 :Keywords:
99 device : `int`
100 The device is the integer number of the hardware devices ID and
101 is only used with the Pololu Protocol. Defaults to the hardware's
102 default value.
103
104 :Returns:
105 An integer indicating the version number.
106 """
107 return self._getFirmwareVersion(device)
108
110 """
111 Get the error message or value stored in the Qik 2s9v1 hardware.
112
113 :Keywords:
114 device : `int`
115 The device is the integer number of the hardware devices ID and
116 is only used with the Pololu Protocol. Defaults to the hardware's
117 default value.
118 message : `bool`
119 If set to `True` a text message will be returned, if set to `False`
120 the integer stored in the Qik will be returned.
121
122 :Returns:
123 A list of text messages, integers, or and empty list. See the
124 `message` parameter above.
125 """
126 return self._getError(device, message)
127
129 """
130 Get the device ID.
131
132 :Keywords:
133 device : `int`
134 The device is the integer number of the hardware devices ID and
135 is only used with the Pololu Protocol. Defaults to the hardware's
136 default value.
137
138 :Returns:
139 An integer number of the hardware device ID.
140 """
141 return self._getDeviceID(device)
142
144 """
145 Get the motor shutdown on error status stored on the hardware device.
146
147 :Keywords:
148 device : `int`
149 The device is the integer number of the hardware devices ID and
150 is only used with the Pololu Protocol. Defaults to the hardware's
151 default value.
152 message : `bool`
153 If set to `True` a text message will be returned, if set to `False`
154 the integer stored in the Qik will be returned.
155
156 :Returns:
157 A text message or an int. See the `message` parameter above.
158 """
159 return self._getPWMFrequency(device, message)
160
162 """
163 Get the motor shutdown on error status stored on the hardware device.
164
165 :Keywords:
166 device : `int`
167 The device is the integer number of the hardware devices ID and
168 is only used with the Pololu Protocol. Defaults to the hardware's
169 default value.
170
171 :Returns:
172 Returns `True` when morot will shutdown on and error, else `False`.
173 """
174 return self._getMotorShutdown(device)
175
177 """
178 Get the serial timeout stored on the hardware device.
179
180 Caution, more that one value returned from the Qik can have the same
181 actual timeout value according the the formula below. I have verified
182 this as an idiosyncrasy of the Qik itself. There are only a total of
183 72 unique values that the Qik can logically use the remaining 56
184 values are repeats of the 72.
185
186 :Keywords:
187 device : `int`
188 The device is the integer number of the hardware devices ID and
189 is only used with the Pololu Protocol. Defaults to the hardware's
190 default value.
191
192 :Returns:
193 The timeout value in seconds.
194 """
195 return self._getSerialTimeout(device)
196
198 """
199 Set the hardware device number. This is only needed if more that one
200 device is on the same serial buss.
201
202 :Parameters:
203 value : `int`
204 The device ID to set in the range of 0 - 127.
205
206 :Keywords:
207 device : `int`
208 The device is the integer number of the hardware devices ID and
209 is only used with the Pololu Protocol. Defaults to the hardware's
210 default value.
211 message : `bool`
212 If set to `True` a text message will be returned, if set to `False`
213 the integer stored in the Qik will be returned.
214
215 :Returns:
216 A text message or an int. See the `message` parameter above. If
217 `value` and `device` are the same `OK` or `0` will be returned
218 depending on the value of `message`.
219
220 :Exceptions:
221 * `SerialException`
222 IO error indicating there was a problem reading from the serial
223 connection.
224 """
225 return self._setDeviceID(value, device, message)
226
228 """
229 Set the PWM frequency.
230
231 :Parameters:
232 pwm : `int`
233 The PWN frequency to set in hertz.
234
235 :Keywords:
236 device : `int`
237 The device is the integer number of the hardware devices ID and
238 is only used with the Pololu Protocol. Defaults to the hardware's
239 default value.
240 message : `bool`
241 If set to `True` a text message will be returned, if set to `False`
242 the integer stored in the Qik will be returned.
243
244 :Returns:
245 A text message or an int. See the `message` parameter above.
246
247 :Exceptions:
248 * `SerialException`
249 IO error indicating there was a problem reading from the serial
250 connection.
251 """
252 return self._setPWMFrequency(pwm, device, message)
253
255 """
256 Set the motor shutdown on error status stored on the hardware device.
257
258 :Parameters:
259 value : `int`
260 An integer indicating the effect on the motors when an error occurs.
261 A `1` will cause the cause the motors to stop on an error and a
262 `0` will ignore errors keeping the motors running.
263
264 :Keywords:
265 device : `int`
266 The device is the integer number of the hardware devices ID and
267 is only used with the Pololu Protocol. Defaults to the hardware's
268 default value.
269 message : `bool`
270 If set to `True` a text message will be returned, if set to `False`
271 the integer stored in the Qik will be returned.
272
273 :Returns:
274 Text message indicating the status of the shutdown error.
275 A text message or an int. See the `message` parameter above.
276
277 :Exceptions:
278 * `SerialException`
279 IO error indicating there was a problem reading from the serial
280 connection.
281 """
282 return self._setMotorShutdown(value, device, message)
283
285 """
286 Set the serial timeout on the hardware device.
287
288 Setting the serial timeout to anything other than zero will cause an
289 error if the serial line is inactive for the time set. This may not be
290 a good thing as leaving the Qik idle may be a required event. Why
291 would you want the Qik to report an error when none actually occurred
292 and your Qik was just idle? This happens with or without the motors
293 running.
294
295 This also explains why, when the Qik is set at a very low timeout that
296 the red LED will come on almost immediately. You will not even get a
297 chance to send it a command before the timeout. This would be like
298 temporarily bricking your Qik. Not a good thing, though it's easy to
299 fix by just setting the timeout to 0 again.
300
301 OK, so how do we actually use the serial timeout. Good question, the
302 best way I can think of is to send the Qik a keep alive signal. One
303 way of doing this is to execute the getError() method at a little less
304 than half the timeout period. So if the timeout was set to 200ms you
305 would get the error status every 90ms. The Qik will stay alive unless
306 the keep alive signal is not seen. This should solve the problem.
307 However, if the keep alive is sent in a different process or thread
308 you could get a format error if the keep alive command collides with
309 any other command.
310
311 :Parameters:
312 timeout : `float` or `int`
313 The timeout value between 0 - 503.04 seconds, however, any number
314 can be passed to the argument, the code will find the nearest
315 allowed value from the 72 that are available.
316
317 :Keywords:
318 device : `int`
319 The device is the integer number of the hardware devices ID and
320 is only used with the Pololu Protocol. Defaults to the hardware's
321 default value.
322 message : `bool`
323 If set to `True` a text message will be returned, if set to `False`
324 the integer stored in the Qik will be returned.
325
326 :Returns:
327 Text message indicating the status of the shutdown error.
328
329 :Exceptions:
330 * `SerialException`
331 IO error indicating there was a problem reading from the serial
332 connection.
333 """
334 return self._setSerialTimeout(timeout, device, message)
335
337 """
338 Set motor 0 to coast.
339
340 :Keywords:
341 device : `int`
342 The device is the integer number of the hardware devices ID and
343 is only used with the Pololu Protocol. Defaults to the hardware's
344 default value.
345
346 :Exceptions:
347 * `SerialTimeoutException`
348 If the low level serial package times out.
349 * `SerialException`
350 IO error when the port is not open.
351 """
352 cmd = self._COMMAND.get('m0-coast')
353 self._writeData(cmd, device)
354
356 """
357 Set motor 1 to coast.
358
359 :Keywords:
360 device : `int`
361 The device is the integer number of the hardware devices ID and
362 is only used with the Pololu Protocol. Defaults to the hardware's
363 default value.
364
365 :Exceptions:
366 * `SerialTimeoutException`
367 If the low level serial package times out.
368 * `SerialException`
369 IO error when the port is not open.
370 """
371 cmd = self._COMMAND.get('m1-coast')
372 self._writeData(cmd, device)
373
375 """
376 Set motor 0 speed.
377
378 :Parameters:
379 speed : `int`
380 Motor speed as an integer. Negative numbers indicate reverse
381 speeds.
382
383 :Keywords:
384 device : `int`
385 The device is the integer number of the hardware devices ID and
386 is only used with the Pololu Protocol. Defaults to the hardware's
387 default value.
388
389 :Exceptions:
390 * `SerialTimeoutException`
391 If the low level serial package times out.
392 * `SerialException`
393 IO error when the port is not open.
394 """
395 self._setM0Speed(speed, device)
396
398 """
399 Set motor 1 speed.
400
401 :Parameters:
402 speed : `int`
403 Motor speed as an integer. Negative numbers indicate reverse
404 speeds.
405
406 :Keywords:
407 device : `int`
408 The device is the integer number of the hardware devices ID and
409 is only used with the Pololu Protocol. Defaults to the hardware's
410 default value.
411
412 :Exceptions:
413 * `SerialTimeoutException`
414 If the low level serial package times out.
415 * `SerialException`
416 IO error when the port is not open.
417 """
418 self._setM1Speed(speed, device)
419