Improved handshake procedure on comm layer
"Hello" command sent to printer to trigger initial handshake can now be configured. Commands that _always_ necessitate to be sent with checksum/ line number (e.g. M110 on Marlin) can be configured as such too. Also fixed an issue causing the "Hello" command to not be actually enqueued first thing on opening a connection. Seems to not have caused harm in the wild, but was unintentional.
This commit is contained in:
parent
ac3409a223
commit
5c2ae378e1
3 changed files with 53 additions and 14 deletions
|
|
@ -613,8 +613,30 @@ Use the following settings to configure the serial connection to the printer:
|
||||||
|
|
||||||
# Use this to define additional baud rates to offer for connecting to serial ports. Must be a
|
# Use this to define additional baud rates to offer for connecting to serial ports. Must be a
|
||||||
# valid integer. Defaults to not set
|
# valid integer. Defaults to not set
|
||||||
|
additionalBaudrates:
|
||||||
- 123456
|
- 123456
|
||||||
|
|
||||||
|
# Commands which are known to take a long time to be acknowledged by the firmware. E.g.
|
||||||
|
# homing, dwelling, auto leveling etc. Defaults to the below commands.
|
||||||
|
longRunningCommands:
|
||||||
|
- G4
|
||||||
|
- G28
|
||||||
|
- G29
|
||||||
|
- G30
|
||||||
|
- G32
|
||||||
|
- M400
|
||||||
|
- M226
|
||||||
|
|
||||||
|
# Commands which need to always be send with a checksum. Defaults to only M110
|
||||||
|
checksumRequiringCommands:
|
||||||
|
- M110
|
||||||
|
|
||||||
|
# Command to send in order to initiate a handshake with the printer.
|
||||||
|
# Defaults to "M110 N0" which simply resets the line numbers in the firmware and which
|
||||||
|
# should be acknowledged with a simple "ok".
|
||||||
|
helloCommand:
|
||||||
|
- M110 N0
|
||||||
|
|
||||||
.. _sec-configuration-config_yaml-server:
|
.. _sec-configuration-config_yaml-server:
|
||||||
|
|
||||||
Server
|
Server
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,9 @@ default_settings = {
|
||||||
},
|
},
|
||||||
"additionalPorts": [],
|
"additionalPorts": [],
|
||||||
"additionalBaudrates": [],
|
"additionalBaudrates": [],
|
||||||
"longRunningCommands": ["G4", "G28", "G29", "G30", "G32", "M400", "M226"]
|
"longRunningCommands": ["G4", "G28", "G29", "G30", "G32", "M400", "M226"],
|
||||||
|
"checksumRequiringCommands": ["M110"],
|
||||||
|
"helloCommand": "M110 N0"
|
||||||
},
|
},
|
||||||
"server": {
|
"server": {
|
||||||
"host": "0.0.0.0",
|
"host": "0.0.0.0",
|
||||||
|
|
|
||||||
|
|
@ -165,6 +165,8 @@ class MachineCom(object):
|
||||||
|
|
||||||
self._timeout = None
|
self._timeout = None
|
||||||
|
|
||||||
|
self._hello_command = settings().get(["serial", "helloCommand"])
|
||||||
|
|
||||||
self._alwaysSendChecksum = settings().getBoolean(["feature", "alwaysSendChecksum"])
|
self._alwaysSendChecksum = settings().getBoolean(["feature", "alwaysSendChecksum"])
|
||||||
self._sendChecksumWithUnknownCommands = settings().getBoolean(["feature", "sendChecksumWithUnknownCommands"])
|
self._sendChecksumWithUnknownCommands = settings().getBoolean(["feature", "sendChecksumWithUnknownCommands"])
|
||||||
self._unknownCommandsNeedAck = settings().getBoolean(["feature", "unknownCommandsNeedAck"])
|
self._unknownCommandsNeedAck = settings().getBoolean(["feature", "unknownCommandsNeedAck"])
|
||||||
|
|
@ -175,6 +177,7 @@ class MachineCom(object):
|
||||||
self._lastResendNumber = None
|
self._lastResendNumber = None
|
||||||
self._currentResendCount = 0
|
self._currentResendCount = 0
|
||||||
self._resendSwallowNextOk = False
|
self._resendSwallowNextOk = False
|
||||||
|
self._checksum_requiring_commands = settings().get(["serial", "checksumRequiringCommands"])
|
||||||
|
|
||||||
self._clear_to_send = CountedEvent(max=10, name="comm.clear_to_send")
|
self._clear_to_send = CountedEvent(max=10, name="comm.clear_to_send")
|
||||||
self._send_queue = TypedQueue()
|
self._send_queue = TypedQueue()
|
||||||
|
|
@ -478,7 +481,7 @@ class MachineCom(object):
|
||||||
def fakeOk(self):
|
def fakeOk(self):
|
||||||
self._clear_to_send.set()
|
self._clear_to_send.set()
|
||||||
|
|
||||||
def sendCommand(self, cmd, cmd_type=None, processed=False):
|
def sendCommand(self, cmd, cmd_type=None, processed=False, force=False):
|
||||||
cmd = cmd.encode('ascii', 'replace')
|
cmd = cmd.encode('ascii', 'replace')
|
||||||
if not processed:
|
if not processed:
|
||||||
cmd = process_gcode_line(cmd)
|
cmd = process_gcode_line(cmd)
|
||||||
|
|
@ -487,7 +490,7 @@ class MachineCom(object):
|
||||||
|
|
||||||
if self.isPrinting() and not self.isSdFileSelected():
|
if self.isPrinting() and not self.isSdFileSelected():
|
||||||
self._commandQueue.put((cmd, cmd_type))
|
self._commandQueue.put((cmd, cmd_type))
|
||||||
elif self.isOperational():
|
elif self.isOperational() or force:
|
||||||
self._sendCommand(cmd, cmd_type=cmd_type)
|
self._sendCommand(cmd, cmd_type=cmd_type)
|
||||||
|
|
||||||
def sendGcodeScript(self, scriptName, replacements=None):
|
def sendGcodeScript(self, scriptName, replacements=None):
|
||||||
|
|
@ -559,7 +562,7 @@ class MachineCom(object):
|
||||||
|
|
||||||
self._changeState(self.STATE_PRINTING)
|
self._changeState(self.STATE_PRINTING)
|
||||||
|
|
||||||
self.sendCommand("M110 N0")
|
self.resetLineNumbers()
|
||||||
|
|
||||||
payload = {
|
payload = {
|
||||||
"file": self._currentFile.getFilename(),
|
"file": self._currentFile.getFilename(),
|
||||||
|
|
@ -757,6 +760,16 @@ class MachineCom(object):
|
||||||
self._callback.on_comm_sd_state_change(self._sdAvailable)
|
self._callback.on_comm_sd_state_change(self._sdAvailable)
|
||||||
self._callback.on_comm_sd_files(self._sdFiles)
|
self._callback.on_comm_sd_files(self._sdFiles)
|
||||||
|
|
||||||
|
def sayHello(self):
|
||||||
|
self.sendCommand(self._hello_command, force=True)
|
||||||
|
self._clear_to_send.set()
|
||||||
|
|
||||||
|
def resetLineNumbers(self, number=0):
|
||||||
|
if not self.isOperational():
|
||||||
|
return
|
||||||
|
|
||||||
|
self.sendCommand("M110 N%d" % number)
|
||||||
|
|
||||||
##~~ communication monitoring and handling
|
##~~ communication monitoring and handling
|
||||||
|
|
||||||
def _parseTemperatures(self, line):
|
def _parseTemperatures(self, line):
|
||||||
|
|
@ -865,10 +878,9 @@ class MachineCom(object):
|
||||||
connection_timeout = settings().getFloat(["serial", "timeout", "connection"])
|
connection_timeout = settings().getFloat(["serial", "timeout", "connection"])
|
||||||
detection_timeout = settings().getFloat(["serial", "timeout", "detection"])
|
detection_timeout = settings().getFloat(["serial", "timeout", "detection"])
|
||||||
|
|
||||||
# enqueue an M105 first thing
|
# enqueue the "hello command" first thing
|
||||||
if try_hello:
|
if try_hello:
|
||||||
self._sendCommand("M110")
|
self.sayHello()
|
||||||
self._clear_to_send.set()
|
|
||||||
|
|
||||||
while self._monitoring_active:
|
while self._monitoring_active:
|
||||||
try:
|
try:
|
||||||
|
|
@ -1089,8 +1101,7 @@ class MachineCom(object):
|
||||||
self._baudrateDetectRetry -= 1
|
self._baudrateDetectRetry -= 1
|
||||||
self._serial.write('\n')
|
self._serial.write('\n')
|
||||||
self._log("Baudrate test retry: %d" % (self._baudrateDetectRetry))
|
self._log("Baudrate test retry: %d" % (self._baudrateDetectRetry))
|
||||||
self._sendCommand("M110")
|
self.sayHello()
|
||||||
self._clear_to_send.set()
|
|
||||||
elif len(self._baudrateDetectList) > 0:
|
elif len(self._baudrateDetectList) > 0:
|
||||||
baudrate = self._baudrateDetectList.pop(0)
|
baudrate = self._baudrateDetectList.pop(0)
|
||||||
try:
|
try:
|
||||||
|
|
@ -1101,8 +1112,7 @@ class MachineCom(object):
|
||||||
self._baudrateDetectRetry = 5
|
self._baudrateDetectRetry = 5
|
||||||
self._timeout = get_new_timeout("communication")
|
self._timeout = get_new_timeout("communication")
|
||||||
self._serial.write('\n')
|
self._serial.write('\n')
|
||||||
self._sendCommand("M110")
|
self.sayHello()
|
||||||
self._clear_to_send.set()
|
|
||||||
except:
|
except:
|
||||||
self._log("Unexpected error while setting baudrate: %d %s" % (baudrate, get_exception_string()))
|
self._log("Unexpected error while setting baudrate: %d %s" % (baudrate, get_exception_string()))
|
||||||
else:
|
else:
|
||||||
|
|
@ -1118,8 +1128,7 @@ class MachineCom(object):
|
||||||
elif self._state == self.STATE_CONNECTING:
|
elif self._state == self.STATE_CONNECTING:
|
||||||
if "start" in line and not startSeen:
|
if "start" in line and not startSeen:
|
||||||
startSeen = True
|
startSeen = True
|
||||||
self._sendCommand("M110")
|
self.sayHello()
|
||||||
self._clear_to_send.set()
|
|
||||||
elif "ok" in line:
|
elif "ok" in line:
|
||||||
self._onConnected()
|
self._onConnected()
|
||||||
elif time.time() > self._timeout:
|
elif time.time() > self._timeout:
|
||||||
|
|
@ -1241,6 +1250,8 @@ class MachineCom(object):
|
||||||
|
|
||||||
self._changeState(self.STATE_OPERATIONAL)
|
self._changeState(self.STATE_OPERATIONAL)
|
||||||
|
|
||||||
|
self.resetLineNumbers()
|
||||||
|
|
||||||
if self._sdAvailable:
|
if self._sdAvailable:
|
||||||
self.refreshSdFiles()
|
self.refreshSdFiles()
|
||||||
else:
|
else:
|
||||||
|
|
@ -1588,7 +1599,11 @@ class MachineCom(object):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# now comes the part where we increase line numbers and send stuff - no turning back now
|
# now comes the part where we increase line numbers and send stuff - no turning back now
|
||||||
if (gcode is not None or self._sendChecksumWithUnknownCommands) and (self.isPrinting() or self._alwaysSendChecksum):
|
command_requiring_checksum = gcode is not None and gcode in self._checksum_requiring_commands
|
||||||
|
command_allowing_checksum = gcode is not None or self._sendChecksumWithUnknownCommands
|
||||||
|
checksum_enabled = self.isPrinting() or self._alwaysSendChecksum
|
||||||
|
|
||||||
|
if command_requiring_checksum or (command_allowing_checksum and checksum_enabled):
|
||||||
linenumber = self._currentLine
|
linenumber = self._currentLine
|
||||||
self._addToLastLines(command)
|
self._addToLastLines(command)
|
||||||
self._currentLine += 1
|
self._currentLine += 1
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue