moons-motor 0.0.11__py3-none-any.whl → 0.1.3__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.
- moons_motor/motor.py +211 -279
- {moons_motor-0.0.11.dist-info → moons_motor-0.1.3.dist-info}/METADATA +3 -2
- moons_motor-0.1.3.dist-info/RECORD +11 -0
- {moons_motor-0.0.11.dist-info → moons_motor-0.1.3.dist-info}/WHEEL +1 -1
- moons_motor-0.0.11.dist-info/RECORD +0 -11
- {moons_motor-0.0.11.dist-info → moons_motor-0.1.3.dist-info/licenses}/LICENSE +0 -0
- {moons_motor-0.0.11.dist-info → moons_motor-0.1.3.dist-info}/top_level.txt +0 -0
moons_motor/motor.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import serial
|
2
|
+
import serial.rs485
|
2
3
|
from serial.tools import list_ports
|
3
4
|
import re
|
4
5
|
import threading
|
@@ -8,12 +9,51 @@ from rich.panel import Panel
|
|
8
9
|
import queue
|
9
10
|
from moons_motor.subject import Subject
|
10
11
|
import time
|
12
|
+
import threading
|
13
|
+
|
14
|
+
from dataclasses import dataclass
|
11
15
|
|
12
16
|
|
13
17
|
class StepperModules:
|
14
18
|
STM17S_3RN = "STM17S-3RN"
|
15
19
|
|
16
20
|
|
21
|
+
@dataclass(frozen=True)
|
22
|
+
class StepperCommand:
|
23
|
+
JOG: str = "CJ" # Start jogging
|
24
|
+
JOG_SPEED: str = "JS" # Jogging speed (Need to set before start jogging)
|
25
|
+
CHANGE_JOG_SPEED: str = "CS" # Change jogging speed while jogging
|
26
|
+
STOP_JOG: str = "SJ" # Stop jogging with deceleration
|
27
|
+
STOP: str = "ST" # Stop immediately (No deceleration)
|
28
|
+
STOP_DECEL: str = "STD" # Stop with deceleration
|
29
|
+
STOP_KILL: str = (
|
30
|
+
"SK" # Stop with deceleration(Control by AM) and kill all unexecuted commands
|
31
|
+
)
|
32
|
+
STOP_KILL_DECEL: str = (
|
33
|
+
"SKD" # Stop and kill all unexecuted commands with deceleration(Control by DE)
|
34
|
+
)
|
35
|
+
ENABLE: str = "ME" # Enable motor
|
36
|
+
DISABLE: str = "MD" # Disable motor
|
37
|
+
MOVE_ABSOLUTE: str = "FP" # Move to absolute position
|
38
|
+
MOVE_FIXED_DISTANCE: str = "FL" # Move to fixed distance
|
39
|
+
POSITION: str = "IP" # Motor absolute position(Calculated trajectory position)
|
40
|
+
TEMPERATURE: str = "IT" # Motor temperature
|
41
|
+
VOLTAGE: str = "IU" # Motor voltage
|
42
|
+
|
43
|
+
ENCODER_POSITION: str = "EP" # Encoder position
|
44
|
+
SET_POSITION: str = "SP" # Set encoder position
|
45
|
+
|
46
|
+
HOME: str = "SH" # Home position
|
47
|
+
VELOCITY: str = "VE" # Set velocity
|
48
|
+
|
49
|
+
ALARM_RESET: str = "AR" # Reset alarm
|
50
|
+
|
51
|
+
SET_RETURN_FORMAT_DECIMAL: str = "IFD" # Set return format to decimal
|
52
|
+
SET_RETURN_FORMAT_HEXADECIMAL: str = "IFH" # Set return format to hexadecimal
|
53
|
+
|
54
|
+
SET_TRANSMIT_DELAY: str = "TD" # Set transmit delay
|
55
|
+
|
56
|
+
|
17
57
|
class MoonsStepper(Subject):
|
18
58
|
motorAdress = [
|
19
59
|
"0",
|
@@ -61,25 +101,20 @@ class MoonsStepper(Subject):
|
|
61
101
|
):
|
62
102
|
super().__init__()
|
63
103
|
self.universe = universe
|
64
|
-
self.model = model
|
104
|
+
self.model = model # Motor model
|
65
105
|
self.only_simulate = only_simlate
|
66
|
-
self.device = ""
|
106
|
+
self.device = "" # COM port description
|
67
107
|
self.VID = VID
|
68
108
|
self.PID = PID
|
69
|
-
self.SERIAL_NUM = SERIAL_NUM
|
109
|
+
self.SERIAL_NUM = SERIAL_NUM # ID for determent the deivice had same VID and PID, can be config using chips manufacturer tool
|
70
110
|
self.ser = None
|
71
|
-
self.listeningBuffer = ""
|
72
|
-
self.listeningBufferPre = ""
|
73
|
-
self.transmitDelay = 0.010
|
74
|
-
self.lock = False
|
75
111
|
self.Opened = False
|
76
|
-
self.new_data_event = threading.Event()
|
77
|
-
self.new_value_event = threading.Event()
|
78
|
-
self.on_send_event = threading.Event()
|
79
112
|
self.recvQueue = queue.Queue()
|
80
113
|
self.sendQueue = queue.Queue()
|
81
|
-
self.
|
82
|
-
self.
|
114
|
+
self.pending_callbacks = queue.Queue()
|
115
|
+
self.update_thread = None
|
116
|
+
self.is_updating = False
|
117
|
+
self.readBuffer = ""
|
83
118
|
|
84
119
|
self.console = Console()
|
85
120
|
|
@@ -117,7 +152,29 @@ class MoonsStepper(Subject):
|
|
117
152
|
print(Panel(port_info, title="All COMPorts"))
|
118
153
|
return simple_ports
|
119
154
|
|
155
|
+
@staticmethod
|
156
|
+
def process_response(response):
|
157
|
+
equal_sign_index = response.index("=")
|
158
|
+
address = response[0]
|
159
|
+
command = response[1:equal_sign_index]
|
160
|
+
value = response[equal_sign_index + 1 :]
|
161
|
+
|
162
|
+
if command == "IT" or command == "IU":
|
163
|
+
# Handle temperature response
|
164
|
+
value = int(value) / 10.0
|
165
|
+
return {
|
166
|
+
"address": address,
|
167
|
+
"command": command,
|
168
|
+
"value": value,
|
169
|
+
}
|
170
|
+
|
171
|
+
def __start_update_thread(self):
|
172
|
+
self.update_thread = threading.Thread(target=self.update, daemon=True)
|
173
|
+
self.is_updating = True
|
174
|
+
self.update_thread.start()
|
175
|
+
|
120
176
|
def connect(self, COM=None, baudrate=9600, callback=None):
|
177
|
+
# Simulate mode
|
121
178
|
if self.only_simulate:
|
122
179
|
self.Opened = True
|
123
180
|
self.device = f"Simulate-{self.universe}"
|
@@ -128,57 +185,80 @@ class MoonsStepper(Subject):
|
|
128
185
|
|
129
186
|
def attempt_connect(COM, baudrate):
|
130
187
|
try:
|
131
|
-
self.ser = serial.Serial(
|
188
|
+
# self.ser = serial.Serial(
|
189
|
+
# port=COM,
|
190
|
+
# baudrate=baudrate,
|
191
|
+
# bytesize=serial.EIGHTBITS,
|
192
|
+
# parity=serial.PARITY_NONE,
|
193
|
+
# stopbits=serial.STOPBITS_ONE,
|
194
|
+
# timeout=0.5,
|
195
|
+
# )
|
196
|
+
self.ser = serial.rs485.RS485(port=COM, baudrate=baudrate)
|
197
|
+
self.ser.rs485_mode = serial.rs485.RS485Settings(
|
198
|
+
rts_level_for_tx=True,
|
199
|
+
rts_level_for_rx=False,
|
200
|
+
loopback=False,
|
201
|
+
delay_before_tx=0.02,
|
202
|
+
delay_before_rx=0.02,
|
203
|
+
)
|
132
204
|
if self.ser is None:
|
133
|
-
# print("> Device not found")
|
134
205
|
self.Opened = False
|
135
206
|
if self.ser.is_open:
|
136
|
-
# print(f"Device: {self.device} | COM: {COM} connected")
|
137
207
|
self.Opened = True
|
138
|
-
|
139
|
-
|
208
|
+
print(f"[bold green]Device connected[/bold green]: {self.device}")
|
209
|
+
|
210
|
+
except Exception as e:
|
211
|
+
print(f"[bold red]Device error:[/bold red] {e} ")
|
140
212
|
self.Opened = False
|
141
213
|
|
214
|
+
ports = list(list_ports.comports())
|
142
215
|
if COM is not None and not self.only_simulate:
|
143
216
|
attempt_connect(COM, baudrate)
|
144
217
|
if callback:
|
145
218
|
callback(self.device, self.Opened)
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
attempt_connect(p.device, baudrate)
|
168
|
-
if callback:
|
169
|
-
callback(self.device, self.Opened)
|
219
|
+
else:
|
220
|
+
for p in ports:
|
221
|
+
m = re.match(
|
222
|
+
r"USB\s*VID:PID=(\w+):(\w+)\s*SER=([A-Za-z0-9]*)", p.usb_info()
|
223
|
+
)
|
224
|
+
print(p.usb_info())
|
225
|
+
if (
|
226
|
+
m
|
227
|
+
and m.group(1) == self.VID
|
228
|
+
and m.group(2) == self.PID
|
229
|
+
# and m.group(3) == self.SERIAL_NUM
|
230
|
+
):
|
231
|
+
if m.group(3) == self.SERIAL_NUM or self.SERIAL_NUM == "":
|
232
|
+
print(
|
233
|
+
f"[bold yellow]Device founded:[/bold yellow] {p.description} | VID: {m.group(1)} | PID: {m.group(2)} | SER: {m.group(3)}"
|
234
|
+
)
|
235
|
+
|
236
|
+
self.device = p.description
|
237
|
+
|
238
|
+
attempt_connect(p.device, baudrate)
|
239
|
+
|
170
240
|
break
|
171
|
-
break
|
172
241
|
|
173
|
-
|
174
|
-
|
175
|
-
|
242
|
+
if self.only_simulate:
|
243
|
+
self.device = "Simulate"
|
244
|
+
self.Opened = True
|
245
|
+
time.sleep(0.5)
|
246
|
+
self.__start_update_thread()
|
247
|
+
if callback:
|
248
|
+
callback(self.device, self.Opened)
|
249
|
+
|
176
250
|
if not self.Opened:
|
177
|
-
print("
|
251
|
+
print(f"[bold red]Device not found[/bold red]")
|
178
252
|
if callback:
|
179
253
|
callback(self.device, self.Opened)
|
180
254
|
|
181
255
|
def disconnect(self):
|
256
|
+
self.send_command(command=StepperCommand.STOP_KILL)
|
257
|
+
time.sleep(0.5)
|
258
|
+
self.sendQueue.queue.clear()
|
259
|
+
self.recvQueue.queue.clear()
|
260
|
+
self.is_updating = False
|
261
|
+
self.update_thread = None
|
182
262
|
if self.only_simulate:
|
183
263
|
self.listen = False
|
184
264
|
self.is_sending = False
|
@@ -191,19 +271,13 @@ class MoonsStepper(Subject):
|
|
191
271
|
self.Opened = False
|
192
272
|
self.ser.flush()
|
193
273
|
self.ser.close()
|
194
|
-
print(f"{self.device}
|
274
|
+
print(f"[bold red]Device disconnected[/bold red]: {self.device}")
|
195
275
|
|
196
276
|
def send(self, command, eol=b"\r"):
|
197
277
|
if (self.ser != None and self.ser.is_open) or self.only_simulate:
|
198
278
|
self.temp_cmd = command + "\r"
|
199
279
|
|
200
|
-
if "~" in self.temp_cmd:
|
201
|
-
# remove ~ in self.temp_cmd
|
202
|
-
self.temp_cmd = self.temp_cmd[1:]
|
203
|
-
else:
|
204
|
-
self.usedSendQueue.put(self.temp_cmd)
|
205
280
|
if self.ser is not None or not self.only_simulate:
|
206
|
-
self.temp_cmd += "\r"
|
207
281
|
self.ser.write(self.temp_cmd.encode("ascii"))
|
208
282
|
if self.is_log_message:
|
209
283
|
print(
|
@@ -213,249 +287,107 @@ class MoonsStepper(Subject):
|
|
213
287
|
else:
|
214
288
|
print(f"Target device is not opened. Command: {command}")
|
215
289
|
|
216
|
-
def
|
217
|
-
if
|
218
|
-
print("
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
290
|
+
def send_command(self, address="", command="", value=None):
|
291
|
+
if command == "":
|
292
|
+
print("Command can't be empty")
|
293
|
+
return
|
294
|
+
if value is not None:
|
295
|
+
command = self.addressed_cmd(address, command + str(value))
|
296
|
+
else:
|
297
|
+
command = self.addressed_cmd(address, command)
|
298
|
+
|
299
|
+
self.sendQueue.put_nowait(command)
|
300
|
+
|
301
|
+
def update(self):
|
302
|
+
|
303
|
+
while self.is_updating:
|
304
|
+
if self.ser is not None:
|
305
|
+
if self.ser.in_waiting > 0:
|
306
|
+
response = self.ser.read(self.ser.in_waiting)
|
307
|
+
response = response.decode("ascii", errors="ignore").strip()
|
308
|
+
response = response.split("\r")
|
309
|
+
|
310
|
+
for r in response:
|
311
|
+
if r != "":
|
312
|
+
self.readBuffer += r
|
313
|
+
self.handle_recv(r)
|
314
|
+
|
315
|
+
if self.sendQueue.empty() != True:
|
316
|
+
# time.sleep(
|
317
|
+
# 0.02
|
318
|
+
# ) # Time for RS485 converter to switch between Transmit and Receive mode
|
319
|
+
while not self.sendQueue.empty():
|
320
|
+
# time.sleep(
|
321
|
+
# 0.05
|
322
|
+
# ) # Time for RS485 converter to switch between Transmit and Receive mode
|
323
|
+
cmd = self.sendQueue.get_nowait()
|
324
|
+
self.send(cmd)
|
325
|
+
self.sendQueue.task_done()
|
326
|
+
|
327
|
+
def handle_recv(self, response):
|
328
|
+
if "*" in response:
|
329
|
+
print(f"[bold green](o)buffered_ack[/bold green]")
|
330
|
+
elif "%" in response:
|
331
|
+
print(f"[bold green](v)success_ack[/bold green]")
|
332
|
+
elif "?" in response:
|
333
|
+
print(f"[bold red](x)fail_ack[/bold red]")
|
243
334
|
else:
|
244
|
-
print("
|
245
|
-
|
335
|
+
print(f"[bold blue]Received from {self.device}: [/bold blue]", response)
|
336
|
+
self.recvQueue.put_nowait(response)
|
337
|
+
|
338
|
+
if "=" in response:
|
339
|
+
callback = self.pending_callbacks.get_nowait()
|
340
|
+
if callback:
|
341
|
+
callback(response)
|
342
|
+
# for command, callback in list(self.pending_callbacks.items()):
|
343
|
+
# if command in response:
|
344
|
+
# if callback:
|
345
|
+
# callback(response)
|
346
|
+
# del self.pending_callbacks[command]
|
347
|
+
# break
|
246
348
|
|
247
349
|
# endregion
|
248
350
|
|
249
351
|
# region motor motion functions
|
250
|
-
def enable(self, motor_address="", enable=True):
|
251
|
-
cmd = "ME" if enable else "MD"
|
252
|
-
self.send(self.addressed_cmd(motor_address, cmd))
|
253
|
-
|
254
|
-
def move_absolute(self, motor_address="", position=0, speed=0.15):
|
255
|
-
self.send(self.addressed_cmd(motor_address, f"VE{speed}"))
|
256
|
-
self.send(self.addressed_cmd(motor_address, f"FP{position}"))
|
257
352
|
|
258
|
-
def
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
self.send(self.addressed_cmd(motor_address, "JS{}".format(speed)))
|
264
|
-
time.sleep(0.01)
|
265
|
-
self.send(self.addressed_cmd(motor_address, "CJ"))
|
266
|
-
# self.send(self.addressed_cmd(motor_address, "CS{}".format(speed)))
|
267
|
-
|
268
|
-
def change_jog_speed(self, motor_address="", speed=0.15):
|
269
|
-
self.send(self.addressed_cmd(motor_address, "CS{}".format(speed)))
|
270
|
-
|
271
|
-
def stop_jog(self, motor_address=""):
|
272
|
-
self.send(self.addressed_cmd(motor_address, "SJ"))
|
273
|
-
|
274
|
-
def stop(self, motor_address=""):
|
275
|
-
self.send(self.addressed_cmd(motor_address, "ST"))
|
276
|
-
|
277
|
-
def stop_with_deceleration(self, motor_address=""):
|
278
|
-
self.send(self.addressed_cmd(motor_address, "STD"))
|
279
|
-
|
280
|
-
def stop_and_kill(self, motor_address="", with_deceleration=True):
|
281
|
-
if with_deceleration:
|
282
|
-
self.send(self.addressed_cmd(motor_address, "SKD"))
|
283
|
-
else:
|
284
|
-
self.send(self.addressed_cmd(motor_address, "SK"))
|
285
|
-
|
286
|
-
def setup_motor(self, motor_address="", kill=False):
|
287
|
-
if kill:
|
288
|
-
self.stop_and_kill(motor_address)
|
289
|
-
self.set_transmit_delay(motor_address, 25)
|
290
|
-
self.set_return_format_dexcimal(motor_address)
|
291
|
-
|
292
|
-
def calibrate(self, motor_address="", speed=0.3, onStart=None, onComplete=None):
|
293
|
-
self.send(self.addressed_cmd(motor_address, "VE{}".format(speed)))
|
294
|
-
# time.sleep(0.01)
|
295
|
-
# self.send(self.addressed_cmd(motor_address, "DI10"))
|
296
|
-
# time.sleep(0.01)
|
297
|
-
self.send(self.addressed_cmd(motor_address, "SH3F"))
|
298
|
-
# time.sleep(0.01)
|
299
|
-
self.send(self.addressed_cmd(motor_address, "EP0"))
|
300
|
-
# time.sleep(0.01)
|
301
|
-
self.send(self.addressed_cmd(motor_address, "SP0"))
|
302
|
-
|
303
|
-
def alarm_reset(self, motor_address=""):
|
304
|
-
self.send(self.addressed_cmd(motor_address, "AR"))
|
305
|
-
|
306
|
-
# speed slow= 0.25, medium=1, fast=5
|
307
|
-
def set_transmit_delay(self, motor_address="", delay=15):
|
308
|
-
self.send(self.addressed_cmd(motor_address, "TD{}".format(delay)))
|
353
|
+
# def setup_motor(self, motor_address="", kill=False):
|
354
|
+
# if kill:
|
355
|
+
# self.stop_and_kill(motor_address)
|
356
|
+
# self.set_transmit_delay(motor_address, 25)
|
357
|
+
# self.set_return_format_dexcimal(motor_address)
|
309
358
|
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
def get_position(self, motor_address):
|
314
|
-
self.send(self.addressed_cmd(motor_address, "IP"))
|
315
|
-
return self.read()
|
316
|
-
# self.new_value_event.wait(timeout=0.5)
|
317
|
-
# return self.get_value()
|
318
|
-
|
319
|
-
def get_temperature(self, motor_address):
|
320
|
-
self.send(self.addressed_cmd(motor_address, "IT"))
|
321
|
-
# self.new_value_event.wait(timeout=0.5)
|
322
|
-
return self.read()
|
323
|
-
# return int(self.get_value()) / 10
|
324
|
-
|
325
|
-
def get_sensor_status(self, motor_address):
|
326
|
-
self.send(self.addressed_cmd(motor_address, "IS"))
|
327
|
-
return self.read()
|
328
|
-
# self.new_value_event.wait(timeout=0.5)
|
329
|
-
# return self.get_value()
|
330
|
-
|
331
|
-
def get_votalge(self, motor_address):
|
332
|
-
self.send(self.addressed_cmd(motor_address, "IU"))
|
333
|
-
return self.read()
|
334
|
-
# self.new_value_event.wait(timeout=0.5)
|
335
|
-
# return self.get_value()
|
336
|
-
|
337
|
-
def get_acceleration(self, motor_address):
|
338
|
-
self.send(self.addressed_cmd(motor_address, "AC"))
|
339
|
-
return self.read()
|
340
|
-
# self.new_value_event.wait(timeout=0.5)
|
341
|
-
# return self.get_value()
|
342
|
-
|
343
|
-
def get_deceleration(self, motor_address):
|
344
|
-
self.send(self.addressed_cmd(motor_address, "DE"))
|
345
|
-
return self.read()
|
346
|
-
# self.new_value_event.wait(timeout=0.5)
|
347
|
-
# return self.get_value()
|
348
|
-
|
349
|
-
def get_velocity(self, motor_address):
|
350
|
-
self.send(self.addressed_cmd(motor_address, "VE"))
|
351
|
-
return self.read()
|
352
|
-
# self.new_value_event.wait(timeout=0.5)
|
353
|
-
# return self.get_value()
|
354
|
-
|
355
|
-
def get_distance(self, motor_address):
|
356
|
-
self.send(self.addressed_cmd(motor_address, "DI"))
|
357
|
-
return self.read()
|
358
|
-
# self.new_value_event.wait(timeout=0.5)
|
359
|
-
# return self.get_value()
|
360
|
-
|
361
|
-
def get_jog_speed(self, motor_address):
|
362
|
-
self.send(self.addressed_cmd(motor_address, "JS"))
|
363
|
-
# self.new_value_event.wait(timeout=0.5)
|
364
|
-
# return self.get_value()
|
365
|
-
return self.read()
|
366
|
-
|
367
|
-
def get_info(self, motor_address, progress=None):
|
368
|
-
self.set_return_format_dexcimal(motor_address)
|
369
|
-
self.motor_wait(motor_address, 0.1)
|
370
|
-
totalInfoCount = 7
|
371
|
-
pos = self.extractValueFromResponse(self.get_position(motor_address))
|
372
|
-
if progress:
|
373
|
-
progress(round(1 / totalInfoCount, 1))
|
374
|
-
temp = (
|
375
|
-
int(self.extractValueFromResponse(self.get_temperature(motor_address))) / 10
|
359
|
+
def home(self, motor_address="", speed=0.3, onComplete=None):
|
360
|
+
self.send_command(
|
361
|
+
address=motor_address, command=StepperCommand.VELOCITY, value=speed
|
376
362
|
)
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
if
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
progress(round(6 / totalInfoCount, 1))
|
391
|
-
info = {
|
392
|
-
"pos": pos,
|
393
|
-
"temp": temp,
|
394
|
-
"vol": vol,
|
395
|
-
"accel": accel,
|
396
|
-
"decel": decel,
|
397
|
-
"jogsp": jogsp,
|
398
|
-
}
|
399
|
-
if progress:
|
400
|
-
progress(round(7 / totalInfoCount))
|
401
|
-
|
402
|
-
return info
|
403
|
-
|
404
|
-
def get_status(self, motor_address) -> str:
|
405
|
-
self.set_return_format_dexcimal(motor_address)
|
406
|
-
self.send(self.addressed_cmd(motor_address, "RS"))
|
407
|
-
self.new_value_event.wait(timeout=0.5)
|
408
|
-
return str(self.get_value())
|
409
|
-
|
410
|
-
def set_return_format_dexcimal(self, motor_address):
|
411
|
-
self.send(self.addressed_cmd(motor_address, "IFD"))
|
363
|
+
self.send_command(
|
364
|
+
address=motor_address, command=StepperCommand.HOME, value="3F"
|
365
|
+
)
|
366
|
+
self.send_command(
|
367
|
+
address=motor_address, command=StepperCommand.ENCODER_POSITION
|
368
|
+
)
|
369
|
+
self.send_command(
|
370
|
+
address=motor_address, command=StepperCommand.SET_POSITION, value=0
|
371
|
+
)
|
372
|
+
if onComplete:
|
373
|
+
self.get_status(
|
374
|
+
motor_address, StepperCommand.SET_POSITION, callback=onComplete
|
375
|
+
)
|
412
376
|
|
413
|
-
|
414
|
-
|
377
|
+
# endregion
|
378
|
+
def get_status(self, motor_address, command: StepperCommand, callback=None):
|
379
|
+
command = self.addressed_cmd(motor_address, command)
|
380
|
+
if callback:
|
381
|
+
self.pending_callbacks.put_nowait(callback)
|
382
|
+
self.sendQueue.put_nowait(command)
|
415
383
|
|
416
384
|
# endregion
|
417
385
|
|
418
386
|
# region utility functions
|
419
|
-
def motor_wait(self, motor_address, wait_time):
|
420
|
-
self.send(self.addressed_cmd(motor_address, "WT{}".format(wait_time)))
|
421
387
|
|
422
388
|
def addressed_cmd(self, motor_address, command):
|
423
|
-
if motor_address == "":
|
424
|
-
return f"~{command}"
|
425
389
|
return f"{motor_address}{command}"
|
426
390
|
|
427
|
-
def extractValueFromResponse(self, response):
|
428
|
-
pattern = r"=(.*)"
|
429
|
-
if response == None:
|
430
|
-
return None
|
431
|
-
result = re.search(pattern, response)
|
432
|
-
if result:
|
433
|
-
return result.group(1)
|
434
|
-
else:
|
435
|
-
return None
|
436
|
-
|
437
|
-
def get_value(self):
|
438
|
-
print("Waiting for value")
|
439
|
-
self.new_data_event.wait(timeout=0.5)
|
440
|
-
print("Recv:" + self.listeningBufferPre)
|
441
|
-
self.new_data_event.clear()
|
442
|
-
return self.listeningBufferPre
|
443
|
-
# if "%" in self.listeningBufferPre:
|
444
|
-
# return "success_ack"
|
445
|
-
# if "?" in self.listeningBufferPre:
|
446
|
-
# return "fail_ack"
|
447
|
-
# if "*" in self.listeningBufferPre:
|
448
|
-
# return "buffered_ack"
|
449
|
-
# self.new_value_event.set()
|
450
|
-
# pattern = r"=(\w+(?:\.\w+)?|\d+(?:\.\d+)?)"
|
451
|
-
# result = re.search(pattern, self.listeningBufferPre)
|
452
|
-
# self.listeningBufferPre = ""
|
453
|
-
# self.new_value_event.clear()
|
454
|
-
# if result:
|
455
|
-
# return result.group(1)
|
456
|
-
# else:
|
457
|
-
# return "No_value_found"
|
458
|
-
|
459
391
|
|
460
392
|
# endregion
|
461
393
|
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: moons_motor
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.1.3
|
4
4
|
Summary: This is a python library for controlling the Moons' motor through the serial port.
|
5
5
|
Author-email: miroc <mike8503111@gmail.com>
|
6
6
|
Project-URL: Repository, https://github.com/miroc99/moons_motor.git
|
@@ -16,6 +16,7 @@ Requires-Dist: pyserial
|
|
16
16
|
Requires-Dist: rich
|
17
17
|
Requires-Dist: python-socketio
|
18
18
|
Requires-Dist: requests
|
19
|
+
Dynamic: license-file
|
19
20
|
|
20
21
|
# Moons Motor
|
21
22
|
|
@@ -0,0 +1,11 @@
|
|
1
|
+
moons_motor/__init__.py,sha256=qOpsRwizV-DpKSvNzyvj8ju3cs6vwgIICur1Oe6sxOA,27
|
2
|
+
moons_motor/motor.py,sha256=rpunJXViqvSpMW9uRJDctBPyfSJnZh5WZtBtci16-Ck,13308
|
3
|
+
moons_motor/observer.py,sha256=PXzuPYKRb2HpjArJcD8HakYIPfFGAs1uBDIL8PSizgA,124
|
4
|
+
moons_motor/simulate.py,sha256=J0y1fZhoOim9i-BAkprxnPern1SAdkDfKPqT2MWyDwU,2561
|
5
|
+
moons_motor/status.py,sha256=jXQZFZTt9ugHktkWKLII8MpEQQaeO-UjlwTrrP4LJNE,2872
|
6
|
+
moons_motor/subject.py,sha256=L_GS6fvJTeX7X23o3T92oiZ4rtLVKA2OEd9GpHn_Dz4,445
|
7
|
+
moons_motor-0.1.3.dist-info/licenses/LICENSE,sha256=nsYjO800SjIjI85y2kVHR5mC3tca2vs4kK_BhNe89bM,1074
|
8
|
+
moons_motor-0.1.3.dist-info/METADATA,sha256=Zaj25TLKPvBv0qJWRInaALURr8bcOtDLNWfxQymFdtY,1304
|
9
|
+
moons_motor-0.1.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
10
|
+
moons_motor-0.1.3.dist-info/top_level.txt,sha256=0dE-CR5_NYBw34jHIDGQNWpMllzO6mtUIuKyRv_rJLg,12
|
11
|
+
moons_motor-0.1.3.dist-info/RECORD,,
|
@@ -1,11 +0,0 @@
|
|
1
|
-
moons_motor/__init__.py,sha256=qOpsRwizV-DpKSvNzyvj8ju3cs6vwgIICur1Oe6sxOA,27
|
2
|
-
moons_motor/motor.py,sha256=Fbp08XMgAjLiyGqFD-WXsGXBNrgCiclsopYxT0tq9Xk,16077
|
3
|
-
moons_motor/observer.py,sha256=PXzuPYKRb2HpjArJcD8HakYIPfFGAs1uBDIL8PSizgA,124
|
4
|
-
moons_motor/simulate.py,sha256=J0y1fZhoOim9i-BAkprxnPern1SAdkDfKPqT2MWyDwU,2561
|
5
|
-
moons_motor/status.py,sha256=jXQZFZTt9ugHktkWKLII8MpEQQaeO-UjlwTrrP4LJNE,2872
|
6
|
-
moons_motor/subject.py,sha256=L_GS6fvJTeX7X23o3T92oiZ4rtLVKA2OEd9GpHn_Dz4,445
|
7
|
-
moons_motor-0.0.11.dist-info/LICENSE,sha256=nsYjO800SjIjI85y2kVHR5mC3tca2vs4kK_BhNe89bM,1074
|
8
|
-
moons_motor-0.0.11.dist-info/METADATA,sha256=Pde70Xqjwl4hZmQZMig8ik6_T1XqutMWs5wkkAkTVdg,1282
|
9
|
-
moons_motor-0.0.11.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
10
|
-
moons_motor-0.0.11.dist-info/top_level.txt,sha256=0dE-CR5_NYBw34jHIDGQNWpMllzO6mtUIuKyRv_rJLg,12
|
11
|
-
moons_motor-0.0.11.dist-info/RECORD,,
|
File without changes
|
File without changes
|