mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-05-07 09:04:31 +08:00
backend of usb printing now works
This commit is contained in:
parent
208e9d28bf
commit
4de4273966
@ -5,6 +5,7 @@ import threading
|
|||||||
import time
|
import time
|
||||||
import queue
|
import queue
|
||||||
import re
|
import re
|
||||||
|
import functools
|
||||||
|
|
||||||
class PrinterConnection():
|
class PrinterConnection():
|
||||||
def __init__(self, serial_port):
|
def __init__(self, serial_port):
|
||||||
@ -87,6 +88,8 @@ class PrinterConnection():
|
|||||||
if self.isPrinting() or not self._is_connected:
|
if self.isPrinting() or not self._is_connected:
|
||||||
return
|
return
|
||||||
self._gcode = gcode_list
|
self._gcode = gcode_list
|
||||||
|
#Reset line number. If this is not done, first line is sometimes ignored
|
||||||
|
self._gcode.insert(0,"M110 N0")
|
||||||
self._gcode_position = 0
|
self._gcode_position = 0
|
||||||
self._print_start_time_100 = None
|
self._print_start_time_100 = None
|
||||||
self._is_printing = True
|
self._is_printing = True
|
||||||
@ -196,6 +199,7 @@ class PrinterConnection():
|
|||||||
#Logger.log('i','Sending: %s' % (cmd))
|
#Logger.log('i','Sending: %s' % (cmd))
|
||||||
try:
|
try:
|
||||||
command = (cmd + '\n').encode()
|
command = (cmd + '\n').encode()
|
||||||
|
#self._serial.write(b'\n')
|
||||||
self._serial.write(command)
|
self._serial.write(command)
|
||||||
except serial.SerialTimeoutException:
|
except serial.SerialTimeoutException:
|
||||||
Logger.log("w","Serial timeout while writing to serial port, trying again.")
|
Logger.log("w","Serial timeout while writing to serial port, trying again.")
|
||||||
@ -224,9 +228,9 @@ class PrinterConnection():
|
|||||||
## Listen thread function.
|
## Listen thread function.
|
||||||
def _listen(self):
|
def _listen(self):
|
||||||
temperature_request_timeout = time.time()
|
temperature_request_timeout = time.time()
|
||||||
|
ok_timeout = time.time()
|
||||||
while self._is_connected:
|
while self._is_connected:
|
||||||
line = self._readline()
|
line = self._readline()
|
||||||
#print("listening: " ,line.decode('utf-8',"replace"))
|
|
||||||
if line is None:
|
if line is None:
|
||||||
break #None is only returned when something went wrong. Stop listening
|
break #None is only returned when something went wrong. Stop listening
|
||||||
if line.startswith(b'Error:'):
|
if line.startswith(b'Error:'):
|
||||||
@ -242,7 +246,6 @@ class PrinterConnection():
|
|||||||
self._error_state = line[6:]
|
self._error_state = line[6:]
|
||||||
elif b' T:' in line or line.startswith(b'T:'): #Temperature message
|
elif b' T:' in line or line.startswith(b'T:'): #Temperature message
|
||||||
try:
|
try:
|
||||||
print("TEMPERATURE", float(re.search(b"T: *([0-9\.]*)", line).group(1)))
|
|
||||||
self._extruder_temperatures[self._temperatureRequestExtruder] = float(re.search(b"T: *([0-9\.]*)", line).group(1))
|
self._extruder_temperatures[self._temperatureRequestExtruder] = float(re.search(b"T: *([0-9\.]*)", line).group(1))
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
@ -255,21 +258,23 @@ class PrinterConnection():
|
|||||||
|
|
||||||
if self._is_printing:
|
if self._is_printing:
|
||||||
if time.time() > temperature_request_timeout: #When printing, request temperature every 5 seconds.
|
if time.time() > temperature_request_timeout: #When printing, request temperature every 5 seconds.
|
||||||
if self._extruderCount > 0:
|
if self._extruder_count > 0:
|
||||||
self._temperatureRequestExtruder = (self._temperatureRequestExtruder + 1) % self._extruderCount
|
self._temperature_requested_extruder_index = (self._temperature_requested_extruder_index + 1) % self._extruder_count
|
||||||
self.sendCommand("M105 T%d" % (self._temperatureRequestExtruder))
|
self.sendCommand("M105 T%d" % (self._temperature_requested_extruder_index))
|
||||||
else:
|
else:
|
||||||
self.sendCommand("M105")
|
self.sendCommand("M105")
|
||||||
temperature_request_timeout = time.time() + 5
|
temperature_request_timeout = time.time() + 5
|
||||||
|
if line == b'' and time.time() > ok_timeout:
|
||||||
|
line = b'ok' #Force a timeout (basicly, send next command)
|
||||||
if b'ok' in line:
|
if b'ok' in line:
|
||||||
if not self._commandQueue.empty():
|
ok_timeout = time.time() + 5
|
||||||
self._sendCommand(self._commandQueue.get())
|
if not self._command_queue.empty():
|
||||||
|
self._sendCommand(self._command_queue.get())
|
||||||
else:
|
else:
|
||||||
self._sendNextGcodeLine()
|
self._sendNextGcodeLine()
|
||||||
elif b"resend" in line.lower() or b"rs" in line:
|
elif b"resend" in line.lower() or b"rs" in line:
|
||||||
try:
|
try:
|
||||||
self._gcode_position = int(line.replace("N:"," ").replace("N"," ").replace(":"," ").split()[-1])
|
self._gcode_position = int(line.replace(b"N:",b" ").replace(b"N",b" ").replace(b":",b" ").split()[-1])
|
||||||
except:
|
except:
|
||||||
if b"rs" in line:
|
if b"rs" in line:
|
||||||
self._gcode_position = int(line.split()[1])
|
self._gcode_position = int(line.split()[1])
|
||||||
@ -283,13 +288,15 @@ class PrinterConnection():
|
|||||||
self.sendCommand("M105")
|
self.sendCommand("M105")
|
||||||
## Send next Gcode in the gcode list
|
## Send next Gcode in the gcode list
|
||||||
def _sendNextGcodeLine(self):
|
def _sendNextGcodeLine(self):
|
||||||
if self._gcode_position >= len(self._gcode_list):
|
if self._gcode_position >= len(self._gcode):
|
||||||
#self._changeState(self.STATE_OPERATIONAL)
|
#self._changeState(self.STATE_OPERATIONAL)
|
||||||
return
|
return
|
||||||
if self._gcode_position == 100:
|
if self._gcode_position == 100:
|
||||||
self._print_start_time_100 = time.time()
|
self._print_start_time_100 = time.time()
|
||||||
line = self._gcode_list[self._gcode_position]
|
line = self._gcode[self._gcode_position]
|
||||||
|
if ';' in line:
|
||||||
|
line = line[:line.find(';')]
|
||||||
|
line = line.strip()
|
||||||
try:
|
try:
|
||||||
if line == 'M0' or line == 'M1':
|
if line == 'M0' or line == 'M1':
|
||||||
#self.setPause(True)
|
#self.setPause(True)
|
||||||
@ -300,11 +307,11 @@ class PrinterConnection():
|
|||||||
self._current_z = z
|
self._current_z = z
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self._log("Unexpected error: %s" % e)
|
self._log("Unexpected error: %s" % e)
|
||||||
checksum = reduce(lambda x,y:x^y, map(ord, "N%d%s" % (self._gcode_position, line)))
|
checksum = functools.reduce(lambda x,y: x^y, map(ord, 'N%d%s' % (self._gcode_position, line)))
|
||||||
|
|
||||||
self._sendCommand("N%d%s*%d" % (self._gcode_position, line, checksum))
|
self._sendCommand("N%d%s*%d" % (self._gcode_position, line, checksum))
|
||||||
self._gcode_position += 1
|
self._gcode_position += 1
|
||||||
|
|
||||||
|
|
||||||
def hasError(self):
|
def hasError(self):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -13,14 +13,21 @@ class USBPrinterManager(SignalEmitter,PluginObject):
|
|||||||
super().__init__()
|
super().__init__()
|
||||||
self._serial_port_list = []
|
self._serial_port_list = []
|
||||||
self._printer_connections = []
|
self._printer_connections = []
|
||||||
|
|
||||||
self._check_ports_thread = threading.Thread(target=self._updateConnectionList)
|
self._check_ports_thread = threading.Thread(target=self._updateConnectionList)
|
||||||
self._check_ports_thread.daemon = True
|
self._check_ports_thread.daemon = True
|
||||||
self._check_ports_thread.start()
|
self._check_ports_thread.start()
|
||||||
time.sleep(2)
|
|
||||||
self.connectAllConnections()
|
## DEBUG CODE
|
||||||
#time.sleep(1)
|
#time.sleep(1)
|
||||||
#self._printer_connections[0]._sendCommand("M109")
|
#self.connectAllConnections()
|
||||||
|
#time.sleep(5)
|
||||||
|
#f = open("Orb.gcode")
|
||||||
|
#lines = f.readlines()
|
||||||
|
#print(len(lines))
|
||||||
|
#print(len(self._printer_connections))
|
||||||
|
#self.sendGCodeToAllActive(lines)
|
||||||
|
#print("sending heat " , self.sendCommandToAllActive("M104 S190"))
|
||||||
|
|
||||||
|
|
||||||
## Check all serial ports and create a PrinterConnection object for them.
|
## Check all serial ports and create a PrinterConnection object for them.
|
||||||
# Note that this does not validate if the serial ports are actually usable!
|
# Note that this does not validate if the serial ports are actually usable!
|
||||||
@ -28,6 +35,7 @@ class USBPrinterManager(SignalEmitter,PluginObject):
|
|||||||
def _updateConnectionList(self):
|
def _updateConnectionList(self):
|
||||||
while True:
|
while True:
|
||||||
temp_serial_port_list = self.getSerialPortList(only_list_usb = True)
|
temp_serial_port_list = self.getSerialPortList(only_list_usb = True)
|
||||||
|
print(temp_serial_port_list)
|
||||||
if temp_serial_port_list != self._serial_port_list: # Something changed about the list since we last changed something.
|
if temp_serial_port_list != self._serial_port_list: # Something changed about the list since we last changed something.
|
||||||
disconnected_ports = [port for port in self._serial_port_list if port not in temp_serial_port_list ]
|
disconnected_ports = [port for port in self._serial_port_list if port not in temp_serial_port_list ]
|
||||||
self._serial_port_list = temp_serial_port_list
|
self._serial_port_list = temp_serial_port_list
|
||||||
@ -42,14 +50,58 @@ class USBPrinterManager(SignalEmitter,PluginObject):
|
|||||||
self._printer_connections.remove(connection)
|
self._printer_connections.remove(connection)
|
||||||
time.sleep(5) #Throttle, as we don't need this information to be updated every single second.
|
time.sleep(5) #Throttle, as we don't need this information to be updated every single second.
|
||||||
|
|
||||||
|
## Attempt to connect with all possible connections.
|
||||||
def connectAllConnections(self):
|
def connectAllConnections(self):
|
||||||
|
print("DERP DERP")
|
||||||
for connection in self._printer_connections:
|
for connection in self._printer_connections:
|
||||||
|
print("connection ",connection)
|
||||||
connection.connect()
|
connection.connect()
|
||||||
|
|
||||||
|
## send gcode to printer and start printing
|
||||||
|
def sendGCodeByPort(self, serial_port, gcode_list):
|
||||||
|
printer_connection = self.getConnectionByPort(serial_port)
|
||||||
|
if printer_connection is not None:
|
||||||
|
printer_connection.printGCode(gcode_list)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
## Send gcode to all active printers.
|
||||||
|
# \return True if there was at least one active connection.
|
||||||
|
def sendGCodeToAllActive(self, gcode_list):
|
||||||
|
for printer_connection in self.getActiveConnections():
|
||||||
|
printer_connection.printGCode(gcode_list)
|
||||||
|
if len(self.getActiveConnections()):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
## Send a command to a printer indentified by port
|
||||||
|
# \param serial port String indentifieing the port
|
||||||
|
# \param command String with the g-code command to send.
|
||||||
|
# \return True if connection was found, false otherwise
|
||||||
|
def sendCommandByPort(self, serial_port, command):
|
||||||
|
printer_connection = self.getConnectionByPort(serial_port)
|
||||||
|
if printer_connection is not None:
|
||||||
|
printer_connection.sendCommand(command)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
## Send a command to all active (eg; connected) printers
|
||||||
|
# \param command String with the g-code command to send.
|
||||||
|
# \return True if at least one connection was found, false otherwise
|
||||||
|
def sendCommandToAllActive(self, command):
|
||||||
|
for printer_connection in self.getActiveConnections():
|
||||||
|
printer_connection.sendCommand(command)
|
||||||
|
if len(self.getActiveConnections()):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
## Get a list of printer connection objects that are connected.
|
||||||
def getActiveConnections(self):
|
def getActiveConnections(self):
|
||||||
return [connection for connection in self._printer_connections if connection.isConnected()]
|
return [connection for connection in self._printer_connections if connection.isConnected()]
|
||||||
|
|
||||||
##
|
## get a printer connection object by serial port
|
||||||
def getConnectionByPort(self, serial_port):
|
def getConnectionByPort(self, serial_port):
|
||||||
for printer_connection in self._printer_connections:
|
for printer_connection in self._printer_connections:
|
||||||
if serial_port == printer_connection.getSerialPort():
|
if serial_port == printer_connection.getSerialPort():
|
||||||
|
Loading…
x
Reference in New Issue
Block a user