├── README.md ├── commands_struct_PELCO.py └── libpelco.py /README.md: -------------------------------------------------------------------------------- 1 | Python PELCO-D implementation API 2 | 3 | Purpose: 4 | PELCO-D Motor Control over UDP or RS-485 5 | 6 | -------------------------------------------------------------------------------- /commands_struct_PELCO.py: -------------------------------------------------------------------------------- 1 | # Weqaar A. Janjua , 24 MAR 2014 2 | # 3 | # Structures for Frame and Command Definitions for PELCO-D 4 | 5 | class libpelco_structs(): 6 | 7 | # Frame format: |synch byte|address|command1|command2|data1|data2|checksum| 8 | # Bytes 2 - 6 are Payload Bytes 9 | _frame = { 10 | 'synch_byte':'\xFF', # Synch Byte, always FF - 1 byte 11 | 'address': '\x00', # Address - 1 byte 12 | 'command1': '\x00', # Command1 - 1 byte 13 | 'command2': '\x00', # Command2 - 1 byte 14 | 'data1': '\x00', # Data1 (PAN SPEED): - 1 byte 15 | 'data2': '\x00', # Data2 (TILT SPEED): - 1 byte 16 | 'checksum': '\x00' # Checksum: - 1 byte 17 | } 18 | 19 | 20 | # Format: Command Hex Code 21 | _function_code = { 22 | 'DOWN': '\x10', 23 | 'UP': '\x08', 24 | 'LEFT': '\x04', 25 | 'RIGHT': '\x02', 26 | 'UP-RIGHT': '\x0A', 27 | 'DOWN-RIGHT': '\x12', 28 | 'UP-LEFT': '\x0C', 29 | 'DOWN-LEFT': '\x14', 30 | 'STOP': '\x00' 31 | } 32 | 33 | # END 34 | -------------------------------------------------------------------------------- /libpelco.py: -------------------------------------------------------------------------------- 1 | import serial 2 | import sys 3 | from commands_struct_PELCO import * 4 | 5 | 6 | class PELCO_Functions(): 7 | 8 | def __init__(self): 9 | global commands_struct 10 | commands_struct = libpelco_structs() 11 | 12 | # Returns: tuple (command, length of command) 13 | # Input: Address (optional), command2, pan_speed, tilt_speed 14 | def _construct_cmd(self, _command2, _pan_speed, _tilt_speed, _address = '\x01', _command1 = '\x00'): 15 | 16 | # DEBUG 17 | print "DEBUG _construct_cmd: " + str(_command2) + " " + str(_pan_speed) + " " + str(_tilt_speed) + "\n" 18 | 19 | # Synch Byte 20 | commands_struct._frame['synch_byte'] = commands_struct._frame['synch_byte'] 21 | 22 | # Address 23 | commands_struct._frame['address'] = _address 24 | 25 | # Command1 26 | commands_struct._frame['command1'] = _command1 27 | 28 | # Command2 29 | if _command2 not in commands_struct._function_code: 30 | print str(_command2) + " not in commands_struct._function_code\n" 31 | return False 32 | else: 33 | commands_struct._frame['command2'] = commands_struct._function_code[_command2] 34 | print "_command2 is: " + commands_struct._frame['command2'].encode('hex') + "\n" 35 | 36 | # Data1: Pan Speed 37 | print "_pan_speed is: " + str(_pan_speed) + "\n" 38 | _hex_pan_speed = hex(_pan_speed)[2:] 39 | if len(_hex_pan_speed) is 1: 40 | _hex_byte_pan = '0' + _hex_pan_speed 41 | else: 42 | _hex_byte_pan = _hex_pan_speed 43 | commands_struct._frame['data1'] = _hex_byte_pan.decode('hex') 44 | 45 | # Data2: Tilt Speed 46 | _hex_tilt_speed = hex(_tilt_speed)[2:] 47 | if len(_hex_tilt_speed) is 1: 48 | _hex_byte_tilt = '0' + _hex_tilt_speed 49 | else: 50 | _hex_byte_tilt = _hex_tilt_speed 51 | commands_struct._frame['data2'] = _hex_byte_tilt.decode('hex') 52 | 53 | # Checksum 54 | _payload_bytes = commands_struct._frame['address'] + commands_struct._frame['command1'] + \ 55 | commands_struct._frame['command2'] + \ 56 | commands_struct._frame['data1'] + commands_struct._frame['data2'] 57 | 58 | #_checksum = hex(self.checksum256(_payload_bytes))[2:].decode('hex') 59 | _checksum = hex(self.checksum256(_payload_bytes))[2:] 60 | if len(_checksum) is 1: 61 | _corrected_checksum = '0' + _checksum 62 | else: 63 | _corrected_checksum = _checksum 64 | commands_struct._frame['checksum'] = _corrected_checksum.decode('hex') 65 | 66 | print "_checksum is: " + commands_struct._frame['checksum'] + "\n" 67 | 68 | # assemble command 69 | _cmd = commands_struct._frame['synch_byte'] + _payload_bytes + commands_struct._frame['checksum'] 70 | 71 | print "Final _cmd: \n" 72 | for i in commands_struct._frame: 73 | print i + " : " + commands_struct._frame[i].encode('hex') 74 | print "\n" 75 | 76 | return (_cmd, None) 77 | 78 | 79 | ############ Commands ################################################################# 80 | 81 | ### STOP ############################################# 82 | # 83 | def pantilt_stop(self): 84 | retval = self._construct_cmd('STOP', 0, 0) 85 | return retval 86 | 87 | 88 | ### UP ############################################### 89 | 90 | def pantilt_up_pressed(self, _pan_tilt_speed): 91 | retval = self._construct_cmd('UP', int(_pan_tilt_speed[0]), int(_pan_tilt_speed[1])) 92 | return retval 93 | 94 | def pantilt_up_released(self, _pan_tilt_speed): 95 | retval = self.pantilt_stop() 96 | return retval 97 | 98 | 99 | ### UP-RIGHT ######################################### 100 | 101 | def pantilt_up_right_pressed(self, _pan_tilt_speed): 102 | retval = self._construct_cmd('UP-RIGHT', int(_pan_tilt_speed[0]), int(_pan_tilt_speed[1])) 103 | return retval 104 | 105 | def pantilt_up_right_released(self, _pan_tilt_speed): 106 | retval = self.pantilt_stop() 107 | return retval 108 | 109 | ### UP-LEFT ######################################### 110 | 111 | def pantilt_up_left_pressed(self, _pan_tilt_speed): 112 | retval = self._construct_cmd('UP-LEFT', int(_pan_tilt_speed[0]), int(_pan_tilt_speed[1])) 113 | return retval 114 | 115 | def pantilt_up_left_released(self, _pan_tilt_speed): 116 | retval = self.pantilt_stop() 117 | return retval 118 | 119 | ### DOWN ######################################### 120 | 121 | def pantilt_down_pressed(self, _pan_tilt_speed): 122 | retval = self._construct_cmd('DOWN', int(_pan_tilt_speed[0]), int(_pan_tilt_speed[1])) 123 | return retval 124 | 125 | def pantilt_down_released(self, _pan_tilt_speed): 126 | retval = self.pantilt_stop() 127 | return retval 128 | 129 | ### DOWN-RIGHT ######################################### 130 | 131 | def pantilt_down_right_pressed(self, _pan_tilt_speed): 132 | retval = self._construct_cmd('DOWN-RIGHT', int(_pan_tilt_speed[0]), int(_pan_tilt_speed[1])) 133 | return retval 134 | 135 | def pantilt_down_right_released(self, _pan_tilt_speed): 136 | retval = self.pantilt_stop() 137 | return retval 138 | 139 | ### DOWN-LEFT ######################################### 140 | 141 | def pantilt_down_left_pressed(self, _pan_tilt_speed): 142 | retval = self._construct_cmd('DOWN-LEFT', int(_pan_tilt_speed[0]), int(_pan_tilt_speed[1])) 143 | return retval 144 | 145 | def pantilt_down_left_released(self, _pan_tilt_speed): 146 | retval = self.pantilt_stop() 147 | return retval 148 | 149 | ### LEFT ######################################### 150 | 151 | def pantilt_left_pressed(self, _pan_tilt_speed): 152 | retval = self._construct_cmd('LEFT', int(_pan_tilt_speed[0]), int(_pan_tilt_speed[1])) 153 | return retval 154 | 155 | def pantilt_left_released(self, _pan_tilt_speed): 156 | retval = self.pantilt_stop() 157 | return retval 158 | 159 | ### RIGHT ######################################### 160 | 161 | def pantilt_right_pressed(self, _pan_tilt_speed): 162 | retval = self._construct_cmd('RIGHT', int(_pan_tilt_speed[0]), int(_pan_tilt_speed[1])) 163 | return retval 164 | 165 | def pantilt_right_released(self, _pan_tilt_speed): 166 | retval = self.pantilt_stop() 167 | return retval 168 | 169 | 170 | ### PAUSE ######################################### 171 | 172 | def pantilt_pause_pressed(self, _pan_tilt_speed): 173 | retval = self._construct_cmd('PAUSE', int(_pan_tilt_speed[0]), int(_pan_tilt_speed[1])) 174 | return retval 175 | 176 | def pantilt_pause_released(self, _pan_tilt_speed): 177 | retval = self.pantilt_stop() 178 | return retval 179 | 180 | ############ Supporting Functions ############# 181 | 182 | def checksum256(self, _str): 183 | return reduce(lambda x,y:x+y, map(ord, _str)) % 256 184 | 185 | # EOF 186 | --------------------------------------------------------------------------------