AutoDetectBaudJob.py 3.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. # Copyright (c) 2018 Ultimaker B.V.
  2. # Cura is released under the terms of the LGPLv3 or higher.
  3. from UM.Job import Job
  4. from UM.Logger import Logger
  5. from .avr_isp.stk500v2 import Stk500v2
  6. from time import time, sleep
  7. from serial import Serial, SerialException
  8. # An async job that attempts to find the correct baud rate for a USB printer.
  9. # It tries a pre-set list of baud rates. All these baud rates are validated by requesting the temperature a few times
  10. # and checking if the results make sense. If getResult() is not None, it was able to find a correct baud rate.
  11. class AutoDetectBaudJob(Job):
  12. def __init__(self, serial_port):
  13. super().__init__()
  14. self._serial_port = serial_port
  15. self._all_baud_rates = [115200, 250000, 230400, 57600, 38400, 19200, 9600]
  16. def run(self):
  17. Logger.log("d", "Auto detect baud rate started.")
  18. wait_response_timeouts = [3, 15, 30]
  19. wait_bootloader_times = [1.5, 5, 15]
  20. write_timeout = 3
  21. read_timeout = 3
  22. tries = 2
  23. programmer = Stk500v2()
  24. serial = None
  25. try:
  26. programmer.connect(self._serial_port)
  27. serial = programmer.leaveISP()
  28. except:
  29. programmer.close()
  30. for retry in range(tries):
  31. for baud_rate in self._all_baud_rates:
  32. if retry < len(wait_response_timeouts):
  33. wait_response_timeout = wait_response_timeouts[retry]
  34. else:
  35. wait_response_timeout = wait_response_timeouts[-1]
  36. if retry < len(wait_bootloader_times):
  37. wait_bootloader = wait_bootloader_times[retry]
  38. else:
  39. wait_bootloader = wait_bootloader_times[-1]
  40. Logger.log("d", "Checking {serial} if baud rate {baud_rate} works. Retry nr: {retry}. Wait timeout: {timeout}".format(
  41. serial = self._serial_port, baud_rate = baud_rate, retry = retry, timeout = wait_response_timeout))
  42. if serial is None:
  43. try:
  44. serial = Serial(str(self._serial_port), baud_rate, timeout = read_timeout, writeTimeout = write_timeout)
  45. except SerialException:
  46. Logger.logException("w", "Unable to create serial")
  47. continue
  48. else:
  49. # We already have a serial connection, just change the baud rate.
  50. try:
  51. serial.baudrate = baud_rate
  52. except:
  53. continue
  54. sleep(wait_bootloader) # Ensure that we are not talking to the boot loader. 1.5 seconds seems to be the magic number
  55. successful_responses = 0
  56. serial.write(b"\n") # Ensure we clear out previous responses
  57. serial.write(b"M105\n")
  58. start_timeout_time = time()
  59. timeout_time = time() + wait_response_timeout
  60. while timeout_time > time():
  61. line = serial.readline()
  62. if b"ok " in line and b"T:" in line:
  63. successful_responses += 1
  64. if successful_responses >= 3:
  65. self.setResult(baud_rate)
  66. Logger.log("d", "Detected baud rate {baud_rate} on serial {serial} on retry {retry} with after {time_elapsed:0.2f} seconds.".format(
  67. serial = self._serial_port, baud_rate = baud_rate, retry = retry, time_elapsed = time() - start_timeout_time))
  68. serial.close() # close serial port so it can be opened by the USBPrinterOutputDevice
  69. return
  70. serial.write(b"M105\n")
  71. sleep(15) # Give the printer some time to init and try again.
  72. self.setResult(None) # Unable to detect the correct baudrate.