ftservo-python-sdk 2.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,70 @@
1
+ Metadata-Version: 2.4
2
+ Name: ftservo-python-sdk
3
+ Version: 2.0.0
4
+ Summary: This is source code from official feetech repository
5
+ Home-page: https://github.com/ftservo/FTServo_Python
6
+ Author: ftservo
7
+ Author-email: 117692731@qq.com
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Topic :: System :: Hardware :: Universal Serial Bus (USB) :: Communications Device Class (CDC)
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: pyserial
15
+ Dynamic: author
16
+ Dynamic: author-email
17
+ Dynamic: classifier
18
+ Dynamic: description
19
+ Dynamic: description-content-type
20
+ Dynamic: home-page
21
+ Dynamic: license-file
22
+ Dynamic: requires-dist
23
+ Dynamic: summary
24
+
25
+ This is source code from [official feetech repository](https://github.com/ftservo/FTServo_Python).
26
+
27
+ ## Structure
28
+
29
+ ```
30
+ root dirrectory
31
+ |---scservo_sdk
32
+ |---sms_sts
33
+ |---scscl
34
+ ```
35
+ The 'scscl' and 'sms_sts' directories contain examples of using the library.
36
+
37
+ The source code of the library is located in the `scservo_sdk` directory.
38
+
39
+ The 'scsservo_sdk' directory contains the original archive with the source code of the library from the developer.
40
+
41
+ ## Usage
42
+
43
+ Tested on Linux Raspbian GNU/Linux 9.13 (stretch).
44
+ Python version Python 3.5.3
45
+
46
+ ### Method 1. Clone repositry
47
+
48
+ ```
49
+ $ cd /usr/src/
50
+ $ sudo git clone https://github.com/ftservo/FTServo_Python.git
51
+ $ sudo chown -R pi FTServo_Python
52
+ $ cd FTServo_Python/sms_sts
53
+ $ python3 ping.py
54
+ Succeeded to open the port
55
+ Succeeded to change the baudrate
56
+ [ID:001] ping Succeeded. SCServo model number : 1540
57
+ ```
58
+
59
+ ### Method 2. Install pip package
60
+
61
+ Copy the sample file to any location convenient for you. In the example I use '/home/pi/FeetechTestFiles'
62
+
63
+ ```
64
+ $ pip install ftservo-python-sdk
65
+ $ cd /home/pi/FeetechTestFiles/sms_sts
66
+ $ python3 ping.py
67
+ Succeeded to open the port
68
+ Succeeded to change the baudrate
69
+ [ID:001] ping Succeeded. SCServo model number : 1540
70
+ ```
@@ -0,0 +1,13 @@
1
+ ftservo_python_sdk-2.0.0.dist-info/licenses/LICENSE,sha256=7kzXw-DouYF2VTN5ykG5z9eOxoSn1I9ITJ0NFVsFvy8,1083
2
+ scservo_sdk/__init__.py,sha256=GP8TUZ1FsNWwr9fmn-UNr-yvAt_GlBjzwkWJAk2S2BY,205
3
+ scservo_sdk/group_sync_read.py,sha256=RaZs3Z__O1qsKaX-_kmwbInuF5wxOcznWdtiMEVetCI,5350
4
+ scservo_sdk/group_sync_write.py,sha256=Epps3ImNuvkRVTI-PePE0sTR8LmRtpJe_JiFLuOqB1E,1982
5
+ scservo_sdk/port_handler.py,sha256=sK1SZAYZWaAlxukAGfvC8tpSuWgpvkXJnuEEupVkGGU,3185
6
+ scservo_sdk/protocol_packet_handler.py,sha256=YKEQvAoZj6_NH9MAe-hcCtCUfyoCL4vMGFfxSQLYFHU,18287
7
+ scservo_sdk/scscl.py,sha256=N3vioVecwBZ3k4mI5KFKBxkUjFFIeylQxYa8sfzigGw,3887
8
+ scservo_sdk/scservo_def.py,sha256=PnKCh4I_12okAAHTA8pbmzpQZlogXetf5PfIDiGgSbE,734
9
+ scservo_sdk/sms_sts.py,sha256=YUq9QuMx9RDp0EhukL2vXs4FPiJ_YOGfYY5wK2W0gQE,4062
10
+ ftservo_python_sdk-2.0.0.dist-info/METADATA,sha256=SZAw-ea2RuN_Nf09_5nDBG3c3a517iFB8gHk4s-KVpA,2043
11
+ ftservo_python_sdk-2.0.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
12
+ ftservo_python_sdk-2.0.0.dist-info/top_level.txt,sha256=aH94_9kpy8x3zbQCNQNK8uAeJ_PtMM2r3S2tmEShADE,12
13
+ ftservo_python_sdk-2.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (78.1.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 ftservo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ scservo_sdk
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env python
2
+
3
+ from .port_handler import *
4
+ from .protocol_packet_handler import *
5
+ from .group_sync_write import *
6
+ from .group_sync_read import *
7
+ from .sms_sts import *
8
+ from .scscl import *
@@ -0,0 +1,151 @@
1
+ #!/usr/bin/env python
2
+
3
+ from .scservo_def import *
4
+
5
+ class GroupSyncRead:
6
+ def __init__(self, ph, start_address, data_length):
7
+ self.ph = ph
8
+ self.start_address = start_address
9
+ self.data_length = data_length
10
+
11
+ self.last_result = False
12
+ self.is_param_changed = False
13
+ self.param = []
14
+ self.data_dict = {}
15
+
16
+ self.clearParam()
17
+
18
+ def makeParam(self):
19
+ if not self.data_dict: # len(self.data_dict.keys()) == 0:
20
+ return
21
+
22
+ self.param = []
23
+
24
+ for scs_id in self.data_dict:
25
+ self.param.append(scs_id)
26
+
27
+ def addParam(self, scs_id):
28
+ if scs_id in self.data_dict: # scs_id already exist
29
+ return False
30
+
31
+ self.data_dict[scs_id] = [] # [0] * self.data_length
32
+
33
+ self.is_param_changed = True
34
+ return True
35
+
36
+ def removeParam(self, scs_id):
37
+ if scs_id not in self.data_dict: # NOT exist
38
+ return
39
+
40
+ del self.data_dict[scs_id]
41
+
42
+ self.is_param_changed = True
43
+
44
+ def clearParam(self):
45
+ self.data_dict.clear()
46
+
47
+ def txPacket(self):
48
+ if len(self.data_dict.keys()) == 0:
49
+
50
+ return COMM_NOT_AVAILABLE
51
+
52
+ if self.is_param_changed is True or not self.param:
53
+ self.makeParam()
54
+
55
+ return self.ph.syncReadTx(self.start_address, self.data_length, self.param, len(self.data_dict.keys()))
56
+
57
+ def rxPacket(self):
58
+ self.last_result = True
59
+
60
+ result = COMM_RX_FAIL
61
+
62
+ if len(self.data_dict.keys()) == 0:
63
+ return COMM_NOT_AVAILABLE
64
+
65
+ result, rxpacket = self.ph.syncReadRx(self.data_length, len(self.data_dict.keys()))
66
+ # print(rxpacket)
67
+ if len(rxpacket) >= (self.data_length+6):
68
+ for scs_id in self.data_dict:
69
+ self.data_dict[scs_id], result = self.readRx(rxpacket, scs_id, self.data_length)
70
+ if result != COMM_SUCCESS:
71
+ self.last_result = False
72
+ # print(scs_id)
73
+ else:
74
+ self.last_result = False
75
+ # print(self.last_result)
76
+ return result
77
+
78
+ def txRxPacket(self):
79
+ result = self.txPacket()
80
+ if result != COMM_SUCCESS:
81
+ return result
82
+
83
+ return self.rxPacket()
84
+
85
+ def readRx(self, rxpacket, scs_id, data_length):
86
+ # print(scs_id)
87
+ # print(rxpacket)
88
+ data = []
89
+ rx_length = len(rxpacket)
90
+ # print(rx_length)
91
+ rx_index = 0;
92
+ while (rx_index+6+data_length) <= rx_length:
93
+ headpacket = [0x00, 0x00, 0x00]
94
+ while rx_index < rx_length:
95
+ headpacket[2] = headpacket[1];
96
+ headpacket[1] = headpacket[0];
97
+ headpacket[0] = rxpacket[rx_index];
98
+ rx_index += 1
99
+ if (headpacket[2] == 0xFF) and (headpacket[1] == 0xFF) and headpacket[0] == scs_id:
100
+ # print(rx_index)
101
+ break
102
+ # print(rx_index+3+data_length)
103
+ if (rx_index+3+data_length) > rx_length:
104
+ break;
105
+ if rxpacket[rx_index] != (data_length+2):
106
+ rx_index += 1
107
+ # print(rx_index)
108
+ continue
109
+ rx_index += 1
110
+ Error = rxpacket[rx_index]
111
+ rx_index += 1
112
+ calSum = scs_id + (data_length+2) + Error
113
+ data = [Error]
114
+ data.extend(rxpacket[rx_index : rx_index+data_length])
115
+ for i in range(0, data_length):
116
+ calSum += rxpacket[rx_index]
117
+ rx_index += 1
118
+ calSum = ~calSum & 0xFF
119
+ # print(calSum)
120
+ if calSum != rxpacket[rx_index]:
121
+ return None, COMM_RX_CORRUPT
122
+ return data, COMM_SUCCESS
123
+ # print(rx_index)
124
+ return None, COMM_RX_CORRUPT
125
+
126
+ def isAvailable(self, scs_id, address, data_length):
127
+ #if self.last_result is False or scs_id not in self.data_dict:
128
+ if scs_id not in self.data_dict:
129
+ return False, 0
130
+
131
+ if (address < self.start_address) or (self.start_address + self.data_length - data_length < address):
132
+ return False, 0
133
+ if not self.data_dict[scs_id]:
134
+ return False, 0
135
+ if len(self.data_dict[scs_id])<(data_length+1):
136
+ return False, 0
137
+ return True, self.data_dict[scs_id][0]
138
+
139
+ def getData(self, scs_id, address, data_length):
140
+ if data_length == 1:
141
+ return self.data_dict[scs_id][address-self.start_address+1]
142
+ elif data_length == 2:
143
+ return self.ph.scs_makeword(self.data_dict[scs_id][address-self.start_address+1],
144
+ self.data_dict[scs_id][address-self.start_address+2])
145
+ elif data_length == 4:
146
+ return self.ph.scs_makedword(self.ph.scs_makeword(self.data_dict[scs_id][address-self.start_address+1],
147
+ self.data_dict[scs_id][address-self.start_address+2]),
148
+ self.ph.scs_makeword(self.data_dict[scs_id][address-self.start_address+3],
149
+ self.data_dict[scs_id][address-self.start_address+4]))
150
+ else:
151
+ return 0
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env python
2
+
3
+ from .scservo_def import *
4
+
5
+ class GroupSyncWrite:
6
+ def __init__(self, ph, start_address, data_length):
7
+ self.ph = ph
8
+ self.start_address = start_address
9
+ self.data_length = data_length
10
+
11
+ self.is_param_changed = False
12
+ self.param = []
13
+ self.data_dict = {}
14
+
15
+ self.clearParam()
16
+
17
+ def makeParam(self):
18
+ if not self.data_dict:
19
+ return
20
+
21
+ self.param = []
22
+
23
+ for scs_id in self.data_dict:
24
+ if not self.data_dict[scs_id]:
25
+ return
26
+
27
+ self.param.append(scs_id)
28
+ self.param.extend(self.data_dict[scs_id])
29
+
30
+ def addParam(self, scs_id, data):
31
+ if scs_id in self.data_dict: # scs_id already exist
32
+ return False
33
+
34
+ if len(data) > self.data_length: # input data is longer than set
35
+ return False
36
+
37
+ self.data_dict[scs_id] = data
38
+
39
+ self.is_param_changed = True
40
+ return True
41
+
42
+ def removeParam(self, scs_id):
43
+ if scs_id not in self.data_dict: # NOT exist
44
+ return
45
+
46
+ del self.data_dict[scs_id]
47
+
48
+ self.is_param_changed = True
49
+
50
+ def changeParam(self, scs_id, data):
51
+ if scs_id not in self.data_dict: # NOT exist
52
+ return False
53
+
54
+ if len(data) > self.data_length: # input data is longer than set
55
+ return False
56
+
57
+ self.data_dict[scs_id] = data
58
+
59
+ self.is_param_changed = True
60
+ return True
61
+
62
+ def clearParam(self):
63
+ self.data_dict.clear()
64
+
65
+ def txPacket(self):
66
+ if len(self.data_dict.keys()) == 0:
67
+ return COMM_NOT_AVAILABLE
68
+
69
+ if self.is_param_changed is True or not self.param:
70
+ self.makeParam()
71
+
72
+ return self.ph.syncWriteTxOnly(self.start_address, self.data_length, self.param,
73
+ len(self.data_dict.keys()) * (1 + self.data_length))
@@ -0,0 +1,115 @@
1
+ #!/usr/bin/env python
2
+
3
+ import time
4
+ import serial
5
+ import sys
6
+ import platform
7
+
8
+ DEFAULT_BAUDRATE = 1000000
9
+ LATENCY_TIMER = 50
10
+
11
+ class PortHandler(object):
12
+ def __init__(self, port_name):
13
+ self.is_open = False
14
+ self.baudrate = DEFAULT_BAUDRATE
15
+ self.packet_start_time = 0.0
16
+ self.packet_timeout = 0.0
17
+ self.tx_time_per_byte = 0.0
18
+
19
+ self.is_using = False
20
+ self.port_name = port_name
21
+ self.ser = None
22
+
23
+ def openPort(self):
24
+ return self.setBaudRate(self.baudrate)
25
+
26
+ def closePort(self):
27
+ self.ser.close()
28
+ self.is_open = False
29
+
30
+ def clearPort(self):
31
+ self.ser.flush()
32
+
33
+ def setPortName(self, port_name):
34
+ self.port_name = port_name
35
+
36
+ def getPortName(self):
37
+ return self.port_name
38
+
39
+ def setBaudRate(self, baudrate):
40
+ baud = self.getCFlagBaud(baudrate)
41
+
42
+ if baud <= 0:
43
+ # self.setupPort(38400)
44
+ # self.baudrate = baudrate
45
+ return False # TODO: setCustomBaudrate(baudrate)
46
+ else:
47
+ self.baudrate = baudrate
48
+ return self.setupPort(baud)
49
+
50
+ def getBaudRate(self):
51
+ return self.baudrate
52
+
53
+ def getBytesAvailable(self):
54
+ return self.ser.in_waiting
55
+
56
+ def readPort(self, length):
57
+ if (sys.version_info > (3, 0)):
58
+ return self.ser.read(length)
59
+ else:
60
+ return [ord(ch) for ch in self.ser.read(length)]
61
+
62
+ def writePort(self, packet):
63
+ return self.ser.write(packet)
64
+
65
+ def setPacketTimeout(self, packet_length):
66
+ self.packet_start_time = self.getCurrentTime()
67
+ self.packet_timeout = (self.tx_time_per_byte * packet_length) + (self.tx_time_per_byte * 3.0) + LATENCY_TIMER
68
+
69
+ def setPacketTimeoutMillis(self, msec):
70
+ self.packet_start_time = self.getCurrentTime()
71
+ self.packet_timeout = msec
72
+
73
+ def isPacketTimeout(self):
74
+ if self.getTimeSinceStart() > self.packet_timeout:
75
+ self.packet_timeout = 0
76
+ return True
77
+
78
+ return False
79
+
80
+ def getCurrentTime(self):
81
+ return round(time.time() * 1000000000) / 1000000.0
82
+
83
+ def getTimeSinceStart(self):
84
+ time_since = self.getCurrentTime() - self.packet_start_time
85
+ if time_since < 0.0:
86
+ self.packet_start_time = self.getCurrentTime()
87
+
88
+ return time_since
89
+
90
+ def setupPort(self, cflag_baud):
91
+ if self.is_open:
92
+ self.closePort()
93
+
94
+ self.ser = serial.Serial(
95
+ port=self.port_name,
96
+ baudrate=self.baudrate,
97
+ # parity = serial.PARITY_ODD,
98
+ # stopbits = serial.STOPBITS_TWO,
99
+ bytesize=serial.EIGHTBITS,
100
+ timeout=0
101
+ )
102
+
103
+ self.is_open = True
104
+
105
+ self.ser.reset_input_buffer()
106
+
107
+ self.tx_time_per_byte = (1000.0 / self.baudrate) * 10.0
108
+
109
+ return True
110
+
111
+ def getCFlagBaud(self, baudrate):
112
+ if baudrate in [4800, 9600, 14400, 19200, 38400, 57600, 115200, 128000, 250000, 500000, 1000000]:
113
+ return baudrate
114
+ else:
115
+ return -1
@@ -0,0 +1,530 @@
1
+ #!/usr/bin/env python
2
+
3
+ from .scservo_def import *
4
+
5
+ TXPACKET_MAX_LEN = 250
6
+ RXPACKET_MAX_LEN = 250
7
+
8
+ # for Protocol Packet
9
+ PKT_HEADER0 = 0
10
+ PKT_HEADER1 = 1
11
+ PKT_ID = 2
12
+ PKT_LENGTH = 3
13
+ PKT_INSTRUCTION = 4
14
+ PKT_ERROR = 4
15
+ PKT_PARAMETER0 = 5
16
+
17
+ # Protocol Error bit
18
+ ERRBIT_VOLTAGE = 1
19
+ ERRBIT_ANGLE = 2
20
+ ERRBIT_OVERHEAT = 4
21
+ ERRBIT_OVERELE = 8
22
+ ERRBIT_OVERLOAD = 32
23
+
24
+
25
+ class protocol_packet_handler(object):
26
+ def __init__(self, portHandler, protocol_end):
27
+ #self.scs_setend(protocol_end)# SCServo bit end(STS/SMS=0, SCS=1)
28
+ self.portHandler = portHandler
29
+ self.scs_end = protocol_end
30
+
31
+ def scs_getend(self):
32
+ return self.scs_end
33
+
34
+ def scs_setend(self, e):
35
+ self.scs_end = e
36
+
37
+ def scs_tohost(self, a, b):
38
+ if (a & (1<<b)):
39
+ return -(a & ~(1<<b))
40
+ else:
41
+ return a
42
+
43
+ def scs_toscs(self, a, b):
44
+ if (a<0):
45
+ return (-a | (1<<b))
46
+ else:
47
+ return a
48
+
49
+ def scs_makeword(self, a, b):
50
+ if self.scs_end==0:
51
+ return (a & 0xFF) | ((b & 0xFF) << 8)
52
+ else:
53
+ return (b & 0xFF) | ((a & 0xFF) << 8)
54
+
55
+ def scs_makedword(self, a, b):
56
+ return (a & 0xFFFF) | (b & 0xFFFF) << 16
57
+
58
+ def scs_loword(self, l):
59
+ return l & 0xFFFF
60
+
61
+ def scs_hiword(self, h):
62
+ return (h >> 16) & 0xFFFF
63
+
64
+ def scs_lobyte(self, w):
65
+ if self.scs_end==0:
66
+ return w & 0xFF
67
+ else:
68
+ return (w >> 8) & 0xFF
69
+
70
+ def scs_hibyte(self, w):
71
+ if self.scs_end==0:
72
+ return (w >> 8) & 0xFF
73
+ else:
74
+ return w & 0xFF
75
+
76
+ def getProtocolVersion(self):
77
+ return 1.0
78
+
79
+ def getTxRxResult(self, result):
80
+ if result == COMM_SUCCESS:
81
+ return "[TxRxResult] Communication success!"
82
+ elif result == COMM_PORT_BUSY:
83
+ return "[TxRxResult] Port is in use!"
84
+ elif result == COMM_TX_FAIL:
85
+ return "[TxRxResult] Failed transmit instruction packet!"
86
+ elif result == COMM_RX_FAIL:
87
+ return "[TxRxResult] Failed get status packet from device!"
88
+ elif result == COMM_TX_ERROR:
89
+ return "[TxRxResult] Incorrect instruction packet!"
90
+ elif result == COMM_RX_WAITING:
91
+ return "[TxRxResult] Now receiving status packet!"
92
+ elif result == COMM_RX_TIMEOUT:
93
+ return "[TxRxResult] There is no status packet!"
94
+ elif result == COMM_RX_CORRUPT:
95
+ return "[TxRxResult] Incorrect status packet!"
96
+ elif result == COMM_NOT_AVAILABLE:
97
+ return "[TxRxResult] Protocol does not support this function!"
98
+ else:
99
+ return ""
100
+
101
+ def getRxPacketError(self, error):
102
+ if error & ERRBIT_VOLTAGE:
103
+ return "[ServoStatus] Input voltage error!"
104
+
105
+ if error & ERRBIT_ANGLE:
106
+ return "[ServoStatus] Angle sen error!"
107
+
108
+ if error & ERRBIT_OVERHEAT:
109
+ return "[ServoStatus] Overheat error!"
110
+
111
+ if error & ERRBIT_OVERELE:
112
+ return "[ServoStatus] OverEle error!"
113
+
114
+ if error & ERRBIT_OVERLOAD:
115
+ return "[ServoStatus] Overload error!"
116
+
117
+ return ""
118
+
119
+ def txPacket(self, txpacket):
120
+ checksum = 0
121
+ total_packet_length = txpacket[PKT_LENGTH] + 4 # 4: HEADER0 HEADER1 ID LENGTH
122
+
123
+ if self.portHandler.is_using:
124
+ return COMM_PORT_BUSY
125
+ self.portHandler.is_using = True
126
+
127
+ # check max packet length
128
+ if total_packet_length > TXPACKET_MAX_LEN:
129
+ self.portHandler.is_using = False
130
+ return COMM_TX_ERROR
131
+
132
+ # make packet header
133
+ txpacket[PKT_HEADER0] = 0xFF
134
+ txpacket[PKT_HEADER1] = 0xFF
135
+
136
+ # add a checksum to the packet
137
+ for idx in range(2, total_packet_length - 1): # except header, checksum
138
+ checksum += txpacket[idx]
139
+
140
+ txpacket[total_packet_length - 1] = ~checksum & 0xFF
141
+
142
+ #print "[TxPacket] %r" % txpacket
143
+
144
+ # tx packet
145
+ self.portHandler.clearPort()
146
+ written_packet_length = self.portHandler.writePort(txpacket)
147
+ if total_packet_length != written_packet_length:
148
+ self.portHandler.is_using = False
149
+ return COMM_TX_FAIL
150
+
151
+ return COMM_SUCCESS
152
+
153
+ def rxPacket(self):
154
+ rxpacket = []
155
+
156
+ result = COMM_TX_FAIL
157
+ checksum = 0
158
+ rx_length = 0
159
+ wait_length = 6 # minimum length (HEADER0 HEADER1 ID LENGTH ERROR CHKSUM)
160
+
161
+ while True:
162
+ rxpacket.extend(self.portHandler.readPort(wait_length - rx_length))
163
+ rx_length = len(rxpacket)
164
+ if rx_length >= wait_length:
165
+ # find packet header
166
+ for idx in range(0, (rx_length - 1)):
167
+ if (rxpacket[idx] == 0xFF) and (rxpacket[idx + 1] == 0xFF):
168
+ break
169
+
170
+ if idx == 0: # found at the beginning of the packet
171
+ if (rxpacket[PKT_ID] > 0xFD) or (rxpacket[PKT_LENGTH] > RXPACKET_MAX_LEN) or (
172
+ rxpacket[PKT_ERROR] > 0x7F):
173
+ # unavailable ID or unavailable Length or unavailable Error
174
+ # remove the first byte in the packet
175
+ del rxpacket[0]
176
+ rx_length -= 1
177
+ continue
178
+
179
+ # re-calculate the exact length of the rx packet
180
+ if wait_length != (rxpacket[PKT_LENGTH] + PKT_LENGTH + 1):
181
+ wait_length = rxpacket[PKT_LENGTH] + PKT_LENGTH + 1
182
+ continue
183
+
184
+ if rx_length < wait_length:
185
+ # check timeout
186
+ if self.portHandler.isPacketTimeout():
187
+ if rx_length == 0:
188
+ result = COMM_RX_TIMEOUT
189
+ else:
190
+ result = COMM_RX_CORRUPT
191
+ break
192
+ else:
193
+ continue
194
+
195
+ # calculate checksum
196
+ for i in range(2, wait_length - 1): # except header, checksum
197
+ checksum += rxpacket[i]
198
+ checksum = ~checksum & 0xFF
199
+
200
+ # verify checksum
201
+ if rxpacket[wait_length - 1] == checksum:
202
+ result = COMM_SUCCESS
203
+ else:
204
+ result = COMM_RX_CORRUPT
205
+ break
206
+
207
+ else:
208
+ # remove unnecessary packets
209
+ del rxpacket[0: idx]
210
+ rx_length -= idx
211
+
212
+ else:
213
+ # check timeout
214
+ if self.portHandler.isPacketTimeout():
215
+ if rx_length == 0:
216
+ result = COMM_RX_TIMEOUT
217
+ else:
218
+ result = COMM_RX_CORRUPT
219
+ break
220
+
221
+ self.portHandler.is_using = False
222
+ return rxpacket, result
223
+
224
+ def txRxPacket(self, txpacket):
225
+ rxpacket = None
226
+ error = 0
227
+
228
+ # tx packet
229
+ result = self.txPacket(txpacket)
230
+ if result != COMM_SUCCESS:
231
+ return rxpacket, result, error
232
+
233
+ # (ID == Broadcast ID) == no need to wait for status packet or not available
234
+ if (txpacket[PKT_ID] == BROADCAST_ID):
235
+ self.portHandler.is_using = False
236
+ return rxpacket, result, error
237
+
238
+ # set packet timeout
239
+ if txpacket[PKT_INSTRUCTION] == INST_READ:
240
+ self.portHandler.setPacketTimeout(txpacket[PKT_PARAMETER0 + 1] + 6)
241
+ else:
242
+ self.portHandler.setPacketTimeout(6) # HEADER0 HEADER1 ID LENGTH ERROR CHECKSUM
243
+
244
+ # rx packet
245
+ while True:
246
+ rxpacket, result = self.rxPacket()
247
+ if result != COMM_SUCCESS or txpacket[PKT_ID] == rxpacket[PKT_ID]:
248
+ break
249
+
250
+ if result == COMM_SUCCESS and txpacket[PKT_ID] == rxpacket[PKT_ID]:
251
+ error = rxpacket[PKT_ERROR]
252
+
253
+ return rxpacket, result, error
254
+
255
+ def ping(self, scs_id):
256
+ model_number = 0
257
+ error = 0
258
+
259
+ txpacket = [0] * 6
260
+
261
+ if scs_id > BROADCAST_ID:
262
+ return model_number, COMM_NOT_AVAILABLE, error
263
+
264
+ txpacket[PKT_ID] = scs_id
265
+ txpacket[PKT_LENGTH] = 2
266
+ txpacket[PKT_INSTRUCTION] = INST_PING
267
+
268
+ rxpacket, result, error = self.txRxPacket(txpacket)
269
+
270
+ if result == COMM_SUCCESS:
271
+ data_read, result, error = self.readTxRx(scs_id, 3, 2) # Address 3 : Model Number
272
+ if result == COMM_SUCCESS:
273
+ model_number = self.scs_makeword(data_read[0], data_read[1])
274
+
275
+ return model_number, result, error
276
+
277
+ def action(self, scs_id):
278
+ txpacket = [0] * 6
279
+
280
+ txpacket[PKT_ID] = scs_id
281
+ txpacket[PKT_LENGTH] = 2
282
+ txpacket[PKT_INSTRUCTION] = INST_ACTION
283
+
284
+ _, result, _ = self.txRxPacket(txpacket)
285
+
286
+ return result
287
+
288
+ def readTx(self, scs_id, address, length):
289
+
290
+ txpacket = [0] * 8
291
+
292
+ if scs_id >= BROADCAST_ID:
293
+ return COMM_NOT_AVAILABLE
294
+
295
+ txpacket[PKT_ID] = scs_id
296
+ txpacket[PKT_LENGTH] = 4
297
+ txpacket[PKT_INSTRUCTION] = INST_READ
298
+ txpacket[PKT_PARAMETER0 + 0] = address
299
+ txpacket[PKT_PARAMETER0 + 1] = length
300
+
301
+ result = self.txPacket(txpacket)
302
+
303
+ # set packet timeout
304
+ if result == COMM_SUCCESS:
305
+ self.portHandler.setPacketTimeout(length + 6)
306
+
307
+ return result
308
+
309
+ def readRx(self, scs_id, length):
310
+ result = COMM_TX_FAIL
311
+ error = 0
312
+
313
+ rxpacket = None
314
+ data = []
315
+
316
+ while True:
317
+ rxpacket, result = self.rxPacket()
318
+
319
+ if result != COMM_SUCCESS or rxpacket[PKT_ID] == scs_id:
320
+ break
321
+
322
+ if result == COMM_SUCCESS and rxpacket[PKT_ID] == scs_id:
323
+ error = rxpacket[PKT_ERROR]
324
+
325
+ data.extend(rxpacket[PKT_PARAMETER0 : PKT_PARAMETER0+length])
326
+
327
+ return data, result, error
328
+
329
+ def readTxRx(self, scs_id, address, length):
330
+ txpacket = [0] * 8
331
+ data = []
332
+
333
+ if scs_id >= BROADCAST_ID:
334
+ return data, COMM_NOT_AVAILABLE, 0
335
+
336
+ txpacket[PKT_ID] = scs_id
337
+ txpacket[PKT_LENGTH] = 4
338
+ txpacket[PKT_INSTRUCTION] = INST_READ
339
+ txpacket[PKT_PARAMETER0 + 0] = address
340
+ txpacket[PKT_PARAMETER0 + 1] = length
341
+
342
+ rxpacket, result, error = self.txRxPacket(txpacket)
343
+ if result == COMM_SUCCESS:
344
+ error = rxpacket[PKT_ERROR]
345
+
346
+ data.extend(rxpacket[PKT_PARAMETER0 : PKT_PARAMETER0+length])
347
+
348
+ return data, result, error
349
+
350
+ def read1ByteTx(self, scs_id, address):
351
+ return self.readTx(scs_id, address, 1)
352
+
353
+ def read1ByteRx(self, scs_id):
354
+ data, result, error = self.readRx(scs_id, 1)
355
+ data_read = data[0] if (result == COMM_SUCCESS) else 0
356
+ return data_read, result, error
357
+
358
+ def read1ByteTxRx(self, scs_id, address):
359
+ data, result, error = self.readTxRx(scs_id, address, 1)
360
+ data_read = data[0] if (result == COMM_SUCCESS) else 0
361
+ return data_read, result, error
362
+
363
+ def read2ByteTx(self, scs_id, address):
364
+ return self.readTx(scs_id, address, 2)
365
+
366
+ def read2ByteRx(self, scs_id):
367
+ data, result, error = self.readRx(scs_id, 2)
368
+ data_read = self.scs_makeword(data[0], data[1]) if (result == COMM_SUCCESS) else 0
369
+ return data_read, result, error
370
+
371
+ def read2ByteTxRx(self, scs_id, address):
372
+ data, result, error = self.readTxRx(scs_id, address, 2)
373
+ data_read = self.scs_makeword(data[0], data[1]) if (result == COMM_SUCCESS) else 0
374
+ return data_read, result, error
375
+
376
+ def read4ByteTx(self, scs_id, address):
377
+ return self.readTx(scs_id, address, 4)
378
+
379
+ def read4ByteRx(self, scs_id):
380
+ data, result, error = self.readRx(scs_id, 4)
381
+ data_read = self.scs_makedword(self.scs_makeword(data[0], data[1]),
382
+ self.scs_makeword(data[2], data[3])) if (result == COMM_SUCCESS) else 0
383
+ return data_read, result, error
384
+
385
+ def read4ByteTxRx(self, scs_id, address):
386
+ data, result, error = self.readTxRx(scs_id, address, 4)
387
+ data_read = self.scs_makedword(self.scs_makeword(data[0], data[1]),
388
+ self.scs_makeword(data[2], data[3])) if (result == COMM_SUCCESS) else 0
389
+ return data_read, result, error
390
+
391
+ def writeTxOnly(self, scs_id, address, length, data):
392
+ txpacket = [0] * (length + 7)
393
+
394
+ txpacket[PKT_ID] = scs_id
395
+ txpacket[PKT_LENGTH] = length + 3
396
+ txpacket[PKT_INSTRUCTION] = INST_WRITE
397
+ txpacket[PKT_PARAMETER0] = address
398
+
399
+ txpacket[PKT_PARAMETER0 + 1: PKT_PARAMETER0 + 1 + length] = data[0: length]
400
+
401
+ result = self.txPacket(txpacket)
402
+ self.portHandler.is_using = False
403
+
404
+ return result
405
+
406
+ def writeTxRx(self, scs_id, address, length, data):
407
+ txpacket = [0] * (length + 7)
408
+
409
+ txpacket[PKT_ID] = scs_id
410
+ txpacket[PKT_LENGTH] = length + 3
411
+ txpacket[PKT_INSTRUCTION] = INST_WRITE
412
+ txpacket[PKT_PARAMETER0] = address
413
+
414
+ txpacket[PKT_PARAMETER0 + 1: PKT_PARAMETER0 + 1 + length] = data[0: length]
415
+ rxpacket, result, error = self.txRxPacket(txpacket)
416
+
417
+ return result, error
418
+
419
+ def write1ByteTxOnly(self, scs_id, address, data):
420
+ data_write = [data]
421
+ return self.writeTxOnly(scs_id, address, 1, data_write)
422
+
423
+ def write1ByteTxRx(self, scs_id, address, data):
424
+ data_write = [data]
425
+ return self.writeTxRx(scs_id, address, 1, data_write)
426
+
427
+ def write2ByteTxOnly(self, scs_id, address, data):
428
+ data_write = [self.scs_lobyte(data), self.scs_hibyte(data)]
429
+ return self.writeTxOnly(scs_id, address, 2, data_write)
430
+
431
+ def write2ByteTxRx(self, scs_id, address, data):
432
+ data_write = [self.scs_lobyte(data), self.scs_hibyte(data)]
433
+ return self.writeTxRx(scs_id, address, 2, data_write)
434
+
435
+ def write4ByteTxOnly(self, scs_id, address, data):
436
+ data_write = [self.scs_lobyte(self.scs_loword(data)),
437
+ self.scs_hibyte(self.scs_loword(data)),
438
+ self.scs_lobyte(self.scs_hiword(data)),
439
+ self.scs_hibyte(self.scs_hiword(data))]
440
+ return self.writeTxOnly(scs_id, address, 4, data_write)
441
+
442
+ def write4ByteTxRx(self, scs_id, address, data):
443
+ data_write = [self.scs_lobyte(self.scs_loword(data)),
444
+ self.scs_hibyte(self.scs_loword(data)),
445
+ self.scs_lobyte(self.scs_hiword(data)),
446
+ self.scs_hibyte(self.scs_hiword(data))]
447
+ return self.writeTxRx(scs_id, address, 4, data_write)
448
+
449
+ def regWriteTxOnly(self, scs_id, address, length, data):
450
+ txpacket = [0] * (length + 7)
451
+
452
+ txpacket[PKT_ID] = scs_id
453
+ txpacket[PKT_LENGTH] = length + 3
454
+ txpacket[PKT_INSTRUCTION] = INST_REG_WRITE
455
+ txpacket[PKT_PARAMETER0] = address
456
+
457
+ txpacket[PKT_PARAMETER0 + 1: PKT_PARAMETER0 + 1 + length] = data[0: length]
458
+
459
+ result = self.txPacket(txpacket)
460
+ self.portHandler.is_using = False
461
+
462
+ return result
463
+
464
+ def regWriteTxRx(self, scs_id, address, length, data):
465
+ txpacket = [0] * (length + 7)
466
+
467
+ txpacket[PKT_ID] = scs_id
468
+ txpacket[PKT_LENGTH] = length + 3
469
+ txpacket[PKT_INSTRUCTION] = INST_REG_WRITE
470
+ txpacket[PKT_PARAMETER0] = address
471
+
472
+ txpacket[PKT_PARAMETER0 + 1: PKT_PARAMETER0 + 1 + length] = data[0: length]
473
+
474
+ _, result, error = self.txRxPacket(txpacket)
475
+
476
+ return result, error
477
+
478
+ def syncReadTx(self, start_address, data_length, param, param_length):
479
+ txpacket = [0] * (param_length + 8)
480
+ # 8: HEADER0 HEADER1 ID LEN INST START_ADDR DATA_LEN CHKSUM
481
+
482
+ txpacket[PKT_ID] = BROADCAST_ID
483
+ txpacket[PKT_LENGTH] = param_length + 4 # 7: INST START_ADDR DATA_LEN CHKSUM
484
+ txpacket[PKT_INSTRUCTION] = INST_SYNC_READ
485
+ txpacket[PKT_PARAMETER0 + 0] = start_address
486
+ txpacket[PKT_PARAMETER0 + 1] = data_length
487
+
488
+ txpacket[PKT_PARAMETER0 + 2: PKT_PARAMETER0 + 2 + param_length] = param[0: param_length]
489
+
490
+ # print(txpacket)
491
+ result = self.txPacket(txpacket)
492
+ return result
493
+
494
+ def syncReadRx(self, data_length, param_length):
495
+ wait_length = (6 + data_length) * param_length
496
+ self.portHandler.setPacketTimeout(wait_length)
497
+ rxpacket = []
498
+ rx_length = 0
499
+ while True:
500
+ rxpacket.extend(self.portHandler.readPort(wait_length - rx_length))
501
+ rx_length = len(rxpacket)
502
+ if rx_length >= wait_length:
503
+ result = COMM_SUCCESS
504
+ break
505
+ else:
506
+ # check timeout
507
+ if self.portHandler.isPacketTimeout():
508
+ if rx_length == 0:
509
+ result = COMM_RX_TIMEOUT
510
+ else:
511
+ result = COMM_RX_CORRUPT
512
+ break
513
+ self.portHandler.is_using = False
514
+ return result, rxpacket
515
+
516
+ def syncWriteTxOnly(self, start_address, data_length, param, param_length):
517
+ txpacket = [0] * (param_length + 8)
518
+ # 8: HEADER0 HEADER1 ID LEN INST START_ADDR DATA_LEN ... CHKSUM
519
+
520
+ txpacket[PKT_ID] = BROADCAST_ID
521
+ txpacket[PKT_LENGTH] = param_length + 4 # 4: INST START_ADDR DATA_LEN ... CHKSUM
522
+ txpacket[PKT_INSTRUCTION] = INST_SYNC_WRITE
523
+ txpacket[PKT_PARAMETER0 + 0] = start_address
524
+ txpacket[PKT_PARAMETER0 + 1] = data_length
525
+
526
+ txpacket[PKT_PARAMETER0 + 2: PKT_PARAMETER0 + 2 + param_length] = param[0: param_length]
527
+
528
+ _, result, _ = self.txRxPacket(txpacket)
529
+
530
+ return result
scservo_sdk/scscl.py ADDED
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env python
2
+
3
+ from .scservo_def import *
4
+ from .protocol_packet_handler import *
5
+ from .group_sync_write import *
6
+
7
+ #波特率定义
8
+ SCSCL_1M = 0
9
+ SCSCL_0_5M = 1
10
+ SCSCL_250K = 2
11
+ SCSCL_128K = 3
12
+ SCSCL_115200 = 4
13
+ SCSCL_76800 = 5
14
+ SCSCL_57600 = 6
15
+ SCSCL_38400 = 7
16
+
17
+ #内存表定义
18
+ #-------EPROM(只读)--------
19
+ SCSCL_MODEL_L = 3
20
+ SCSCL_MODEL_H = 4
21
+
22
+ #-------EPROM(读写)--------
23
+ scs_id = 5
24
+ SCSCL_BAUD_RATE = 6
25
+ SCSCL_MIN_ANGLE_LIMIT_L = 9
26
+ SCSCL_MIN_ANGLE_LIMIT_H = 10
27
+ SCSCL_MAX_ANGLE_LIMIT_L = 11
28
+ SCSCL_MAX_ANGLE_LIMIT_H = 12
29
+ SCSCL_CW_DEAD = 26
30
+ SCSCL_CCW_DEAD = 27
31
+
32
+ #-------SRAM(读写)--------
33
+ SCSCL_TORQUE_ENABLE = 40
34
+ SCSCL_GOAL_POSITION_L = 42
35
+ SCSCL_GOAL_POSITION_H = 43
36
+ SCSCL_GOAL_TIME_L = 44
37
+ SCSCL_GOAL_TIME_H = 45
38
+ SCSCL_GOAL_SPEED_L = 46
39
+ SCSCL_GOAL_SPEED_H = 47
40
+ SCSCL_LOCK = 48
41
+
42
+ #-------SRAM(只读)--------
43
+ SCSCL_PRESENT_POSITION_L = 56
44
+ SCSCL_PRESENT_POSITION_H = 57
45
+ SCSCL_PRESENT_SPEED_L = 58
46
+ SCSCL_PRESENT_SPEED_H = 59
47
+ SCSCL_PRESENT_LOAD_L = 60
48
+ SCSCL_PRESENT_LOAD_H = 61
49
+ SCSCL_PRESENT_VOLTAGE = 62
50
+ SCSCL_PRESENT_TEMPERATURE = 63
51
+ SCSCL_MOVING = 66
52
+ SCSCL_PRESENT_CURRENT_L = 69
53
+ SCSCL_PRESENT_CURRENT_H = 70
54
+
55
+ class scscl(protocol_packet_handler):
56
+ def __init__(self, portHandler):
57
+ protocol_packet_handler.__init__(self, portHandler, 1)
58
+ self.groupSyncWrite = GroupSyncWrite(self, SCSCL_GOAL_POSITION_L, 6)
59
+
60
+ def WritePos(self, scs_id, position, time, speed):
61
+ txpacket = [self.scs_lobyte(position), self.scs_hibyte(position), self.scs_lobyte(time), self.scs_hibyte(time), self.scs_lobyte(speed), self.scs_hibyte(speed)]
62
+ return self.writeTxRx(scs_id, SCSCL_GOAL_POSITION_L, len(txpacket), txpacket)
63
+
64
+ def ReadPos(self, scs_id):
65
+ scs_present_position, scs_comm_result, scs_error = self.read2ByteTxRx(scs_id, SCSCL_PRESENT_POSITION_L)
66
+ return scs_present_position, scs_comm_result, scs_error
67
+
68
+ def ReadSpeed(self, scs_id):
69
+ scs_present_speed, scs_comm_result, scs_error = self.read2ByteTxRx(scs_id, SCSCL_PRESENT_SPEED_L)
70
+ return self.scs_tohost(scs_present_speed, 15), scs_comm_result, scs_error
71
+
72
+ def ReadPosSpeed(self, scs_id):
73
+ scs_present_position_speed, scs_comm_result, scs_error = self.read4ByteTxRx(scs_id, SCSCL_PRESENT_POSITION_L)
74
+ scs_present_position = self.scs_loword(scs_present_position_speed)
75
+ scs_present_speed = self.scs_hiword(scs_present_position_speed)
76
+ return scs_present_position, self.scs_tohost(scs_present_speed, 15), scs_comm_result, scs_error
77
+
78
+ def ReadMoving(self, scs_id):
79
+ moving, scs_comm_result, scs_error = self.read1ByteTxRx(scs_id, SCSCL_MOVING)
80
+ return moving, scs_comm_result, scs_error
81
+
82
+ def SyncWritePos(self, scs_id, position, time, speed):
83
+ txpacket = [self.scs_lobyte(position), self.scs_hibyte(position), self.scs_lobyte(time), self.scs_hibyte(time), self.scs_lobyte(speed), self.scs_hibyte(speed)]
84
+ return self.groupSyncWrite.addParam(scs_id, txpacket)
85
+
86
+ def RegWritePos(self, scs_id, position, time, speed):
87
+ txpacket = [self.scs_lobyte(position), self.scs_hibyte(position), self.scs_lobyte(time), self.scs_hibyte(time), self.scs_lobyte(speed), self.scs_hibyte(speed)]
88
+ return self.regWriteTxRx(scs_id, SCSCL_GOAL_POSITION_L, len(txpacket), txpacket)
89
+
90
+ def RegAction(self):
91
+ return self.action(BROADCAST_ID)
92
+
93
+ def PWMMode(self, scs_id):
94
+ txpacket = [0, 0, 0, 0]
95
+ return self.writeTxRx(scs_id, SCSCL_MIN_ANGLE_LIMIT_L, len(txpacket), txpacket)
96
+
97
+ def WritePWM(self, scs_id, time):
98
+ return self.write2ByteTxRx(scs_id, SCSCL_GOAL_TIME_L, self.scs_toscs(time, 10))
99
+
100
+ def LockEprom(self, scs_id):
101
+ return self.write1ByteTxRx(scs_id, SCSCL_LOCK, 1)
102
+
103
+ def unLockEprom(self, scs_id):
104
+ return self.write1ByteTxRx(scs_id, SCSCL_LOCK, 0)
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env python
2
+
3
+ BROADCAST_ID = 0xFE # 254
4
+ MAX_ID = 0xFC # 252
5
+ SCS_END = 0
6
+
7
+ # Instruction for SCS Protocol
8
+ INST_PING = 1
9
+ INST_READ = 2
10
+ INST_WRITE = 3
11
+ INST_REG_WRITE = 4
12
+ INST_ACTION = 5
13
+ INST_SYNC_WRITE = 131 # 0x83
14
+ INST_SYNC_READ = 130 # 0x82
15
+
16
+ # Communication Result
17
+ COMM_SUCCESS = 0 # tx or rx packet communication success
18
+ COMM_PORT_BUSY = -1 # Port is busy (in use)
19
+ COMM_TX_FAIL = -2 # Failed transmit instruction packet
20
+ COMM_RX_FAIL = -3 # Failed get status packet
21
+ COMM_TX_ERROR = -4 # Incorrect instruction packet
22
+ COMM_RX_WAITING = -5 # Now recieving status packet
23
+ COMM_RX_TIMEOUT = -6 # There is no status packet
24
+ COMM_RX_CORRUPT = -7 # Incorrect status packet
25
+ COMM_NOT_AVAILABLE = -9 #
scservo_sdk/sms_sts.py ADDED
@@ -0,0 +1,111 @@
1
+ #!/usr/bin/env python
2
+
3
+ from .scservo_def import *
4
+ from .protocol_packet_handler import *
5
+ from .group_sync_read import *
6
+ from .group_sync_write import *
7
+
8
+ #波特率定义
9
+ SMS_STS_1M = 0
10
+ SMS_STS_0_5M = 1
11
+ SMS_STS_250K = 2
12
+ SMS_STS_128K = 3
13
+ SMS_STS_115200 = 4
14
+ SMS_STS_76800 = 5
15
+ SMS_STS_57600 = 6
16
+ SMS_STS_38400 = 7
17
+
18
+ #内存表定义
19
+ #-------EPROM(只读)--------
20
+ SMS_STS_MODEL_L = 3
21
+ SMS_STS_MODEL_H = 4
22
+
23
+ #-------EPROM(读写)--------
24
+ SMS_STS_ID = 5
25
+ SMS_STS_BAUD_RATE = 6
26
+ SMS_STS_MIN_ANGLE_LIMIT_L = 9
27
+ SMS_STS_MIN_ANGLE_LIMIT_H = 10
28
+ SMS_STS_MAX_ANGLE_LIMIT_L = 11
29
+ SMS_STS_MAX_ANGLE_LIMIT_H = 12
30
+ SMS_STS_CW_DEAD = 26
31
+ SMS_STS_CCW_DEAD = 27
32
+ SMS_STS_OFS_L = 31
33
+ SMS_STS_OFS_H = 32
34
+ SMS_STS_MODE = 33
35
+
36
+ #-------SRAM(读写)--------
37
+ SMS_STS_TORQUE_ENABLE = 40
38
+ SMS_STS_ACC = 41
39
+ SMS_STS_GOAL_POSITION_L = 42
40
+ SMS_STS_GOAL_POSITION_H = 43
41
+ SMS_STS_GOAL_TIME_L = 44
42
+ SMS_STS_GOAL_TIME_H = 45
43
+ SMS_STS_GOAL_SPEED_L = 46
44
+ SMS_STS_GOAL_SPEED_H = 47
45
+ SMS_STS_LOCK = 55
46
+
47
+ #-------SRAM(只读)--------
48
+ SMS_STS_PRESENT_POSITION_L = 56
49
+ SMS_STS_PRESENT_POSITION_H = 57
50
+ SMS_STS_PRESENT_SPEED_L = 58
51
+ SMS_STS_PRESENT_SPEED_H = 59
52
+ SMS_STS_PRESENT_LOAD_L = 60
53
+ SMS_STS_PRESENT_LOAD_H = 61
54
+ SMS_STS_PRESENT_VOLTAGE = 62
55
+ SMS_STS_PRESENT_TEMPERATURE = 63
56
+ SMS_STS_MOVING = 66
57
+ SMS_STS_PRESENT_CURRENT_L = 69
58
+ SMS_STS_PRESENT_CURRENT_H = 70
59
+
60
+ class sms_sts(protocol_packet_handler):
61
+ def __init__(self, portHandler):
62
+ protocol_packet_handler.__init__(self, portHandler, 0)
63
+ self.groupSyncWrite = GroupSyncWrite(self, SMS_STS_ACC, 7)
64
+
65
+ def WritePosEx(self, scs_id, position, speed, acc):
66
+ txpacket = [acc, self.scs_lobyte(position), self.scs_hibyte(position), 0, 0, self.scs_lobyte(speed), self.scs_hibyte(speed)]
67
+ return self.writeTxRx(scs_id, SMS_STS_ACC, len(txpacket), txpacket)
68
+
69
+ def ReadPos(self, scs_id):
70
+ scs_present_position, scs_comm_result, scs_error = self.read2ByteTxRx(scs_id, SMS_STS_PRESENT_POSITION_L)
71
+ return self.scs_tohost(scs_present_position, 15), scs_comm_result, scs_error
72
+
73
+ def ReadSpeed(self, scs_id):
74
+ scs_present_speed, scs_comm_result, scs_error = self.read2ByteTxRx(scs_id, SMS_STS_PRESENT_SPEED_L)
75
+ return self.scs_tohost(scs_present_speed, 15), scs_comm_result, scs_error
76
+
77
+ def ReadPosSpeed(self, scs_id):
78
+ scs_present_position_speed, scs_comm_result, scs_error = self.read4ByteTxRx(scs_id, SMS_STS_PRESENT_POSITION_L)
79
+ scs_present_position = self.scs_loword(scs_present_position_speed)
80
+ scs_present_speed = self.scs_hiword(scs_present_position_speed)
81
+ return self.scs_tohost(scs_present_position, 15), self.scs_tohost(scs_present_speed, 15), scs_comm_result, scs_error
82
+
83
+ def ReadMoving(self, scs_id):
84
+ moving, scs_comm_result, scs_error = self.read1ByteTxRx(scs_id, SMS_STS_MOVING)
85
+ return moving, scs_comm_result, scs_error
86
+
87
+ def SyncWritePosEx(self, scs_id, position, speed, acc):
88
+ txpacket = [acc, self.scs_lobyte(position), self.scs_hibyte(position), 0, 0, self.scs_lobyte(speed), self.scs_hibyte(speed)]
89
+ return self.groupSyncWrite.addParam(scs_id, txpacket)
90
+
91
+ def RegWritePosEx(self, scs_id, position, speed, acc):
92
+ txpacket = [acc, self.scs_lobyte(position), self.scs_hibyte(position), 0, 0, self.scs_lobyte(speed), self.scs_hibyte(speed)]
93
+ return self.regWriteTxRx(scs_id, SMS_STS_ACC, len(txpacket), txpacket)
94
+
95
+ def RegAction(self):
96
+ return self.action(BROADCAST_ID)
97
+
98
+ def WheelMode(self, scs_id):
99
+ return self.write1ByteTxRx(scs_id, SMS_STS_MODE, 1)
100
+
101
+ def WriteSpec(self, scs_id, speed, acc):
102
+ speed = self.scs_toscs(speed, 15)
103
+ txpacket = [acc, 0, 0, 0, 0, self.scs_lobyte(speed), self.scs_hibyte(speed)]
104
+ return self.writeTxRx(scs_id, SMS_STS_ACC, len(txpacket), txpacket)
105
+
106
+ def LockEprom(self, scs_id):
107
+ return self.write1ByteTxRx(scs_id, SMS_STS_LOCK, 1)
108
+
109
+ def unLockEprom(self, scs_id):
110
+ return self.write1ByteTxRx(scs_id, SMS_STS_LOCK, 0)
111
+