Package motors :: Module qik2s9v1
[hide private]
[frames] | no frames]

Source Code for Module motors.qik2s9v1

  1  # 
  2  # motors/pololu/qik2s9v1.py 
  3  # 
  4  # Usual device on Linux: /dev/ttyUSB0 
  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   
30 -class Qik2s9v1(Qik):
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):
84 super(Qik2s9v1, self).__init__(device, baud, readTimeout, writeTimeout, 85 log) 86 self.findConnectedDevices()
87
88 - def _deviceCallback(self, device, config):
89 config['version'] = self._getFirmwareVersion(device) 90 config['pwm'] = self._getConfig(self.PWM_PARAM, device) 91 config['shutdown'] = self._getConfig(self.MOTOR_ERR_SHUTDOWN, device) 92 config['timeout'] = self._getSerialTimeout(device)
93
94 - def getFirmwareVersion(self, device=DEFAULT_DEVICE_ID):
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
109 - def getError(self, device=DEFAULT_DEVICE_ID, message=True):
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
128 - def getDeviceID(self, device=DEFAULT_DEVICE_ID):
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
143 - def getPWMFrequency(self, device=DEFAULT_DEVICE_ID, message=True):
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
161 - def getMotorShutdown(self, device=DEFAULT_DEVICE_ID):
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
176 - def getSerialTimeout(self, device=DEFAULT_DEVICE_ID):
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
197 - def setDeviceID(self, value, device=DEFAULT_DEVICE_ID, message=True):
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
227 - def setPWMFrequency(self, pwm, device=DEFAULT_DEVICE_ID, message=True):
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
254 - def setMotorShutdown(self, value, device=DEFAULT_DEVICE_ID, message=True):
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
284 - def setSerialTimeout(self, timeout, device=DEFAULT_DEVICE_ID, message=True):
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
336 - def setM0Coast(self, device=DEFAULT_DEVICE_ID):
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
355 - def setM1Coast(self, device=DEFAULT_DEVICE_ID):
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
374 - def setM0Speed(self, speed, device=DEFAULT_DEVICE_ID):
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
397 - def setM1Speed(self, speed, device=DEFAULT_DEVICE_ID):
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