12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- # Copyright (c) 2018 Ultimaker B.V.
- # Cura is released under the terms of the LGPLv3 or higher.
- from UM.Job import Job
- from UM.Logger import Logger
- from .avr_isp import ispBase
- from .avr_isp.stk500v2 import Stk500v2
- from time import time, sleep
- from serial import Serial, SerialException
- # An async job that attempts to find the correct baud rate for a USB printer.
- # It tries a pre-set list of baud rates. All these baud rates are validated by requesting the temperature a few times
- # and checking if the results make sense. If getResult() is not None, it was able to find a correct baud rate.
- class AutoDetectBaudJob(Job):
- def __init__(self, serial_port: int) -> None:
- super().__init__()
- self._serial_port = serial_port
- self._all_baud_rates = [115200, 250000, 500000, 230400, 76800, 57600, 38400, 19200, 9600]
- def run(self) -> None:
- Logger.debug(f"Auto detect baud rate started for {self._serial_port}")
- wait_response_timeouts = [3, 15, 30]
- wait_bootloader_times = [1.5, 5, 15]
- write_timeout = 3
- read_timeout = 3
- tries = 2
- programmer = Stk500v2()
- serial = None
- try:
- programmer.connect(self._serial_port)
- serial = programmer.leaveISP()
- except ispBase.IspError:
- programmer.close()
- for retry in range(tries):
- for baud_rate in self._all_baud_rates:
- if retry < len(wait_response_timeouts):
- wait_response_timeout = wait_response_timeouts[retry]
- else:
- wait_response_timeout = wait_response_timeouts[-1]
- if retry < len(wait_bootloader_times):
- wait_bootloader = wait_bootloader_times[retry]
- else:
- wait_bootloader = wait_bootloader_times[-1]
- Logger.debug(f"Checking {self._serial_port} if baud rate {baud_rate} works. Retry nr: {retry}. Wait timeout: {wait_response_timeout}")
- if serial is None:
- try:
- serial = Serial(str(self._serial_port), baud_rate, timeout = read_timeout, writeTimeout = write_timeout)
- except SerialException:
- Logger.warning(f"Unable to create serial connection to {serial} with baud rate {baud_rate}")
- continue
- else:
- # We already have a serial connection, just change the baud rate.
- try:
- serial.baudrate = baud_rate
- except ValueError:
- continue
- # Ensure that we are not talking to the boot loader. 1.5 seconds seems to be the magic number
- sleep(wait_bootloader)
- serial.write(b"\n") # Ensure we clear out previous responses
- serial.write(b"M105\n")
- start_timeout_time = time()
- timeout_time = time() + wait_response_timeout
- while timeout_time > time():
- # If baudrate is wrong, then readline() might never
- # return, even with timeouts set. Using read_until
- # with size limit seems to fix this.
- line = serial.read_until(size = 100)
- if b"ok" in line and b"T:" in line:
- self.setResult(baud_rate)
- Logger.log("d", "Detected baud rate {baud_rate} on serial {serial} on retry {retry} with after {time_elapsed:0.2f} seconds.".format(
- serial = self._serial_port, baud_rate = baud_rate, retry = retry, time_elapsed = time() - start_timeout_time))
- serial.close() # close serial port so it can be opened by the USBPrinterOutputDevice
- return
- serial.write(b"M105\n")
- sleep(15) # Give the printer some time to init and try again.
- Logger.debug(f"Unable to find a working baudrate for {serial}")
- self.setResult(None) # Unable to detect the correct baudrate.
|