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