From 16ecf15a912c72cce3d9d6e617828c8aa03f13d8 Mon Sep 17 00:00:00 2001 From: FanDjango <51046875+FanDjango@users.noreply.github.com> Date: Mon, 24 Feb 2020 04:32:07 +0100 Subject: [PATCH] bltouch: BTLOUCH V3.0/V3.1 Enable 5V/OD mode set commands (#2540) Signed-off-by: Mike Stiemke --- config/example-extras.cfg | 9 +++++++ docs/BLTouch.md | 40 +++++++++++++++++++++++++++ docs/G-Codes.md | 9 ++++++- klippy/extras/bltouch.py | 57 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 114 insertions(+), 1 deletion(-) diff --git a/config/example-extras.cfg b/config/example-extras.cfg index 16b6e9bf..4c5d0d8c 100644 --- a/config/example-extras.cfg +++ b/config/example-extras.cfg @@ -637,6 +637,15 @@ #stow_on_each_sample: True # If set to False, intermediate STOW/DEPLOY sequences on certain # operations that use the probe multiple times will be omitted. +#set_ouput_mode: [Possible values: 5V, OD, or do not specify this +# parameter at all if you don't want a mode setting to be performed] +# A BLTouch Smart V3.0 or V3.1(+) supports selection of an output +# mode, 5V or OPEN DRAIN. If your controller board NEEDs 5V mode +# AND it is 5V tolerant on its input signal line, you can use this +# parameter. Note also that for a V3.1, it is possible to not specify +# this parameter at all and instead to manually use a "BLTOUCH_STORE +# MODE=" command to store the desired output mode permanently in the +# probes EEPROM (see the documentation for this command). #x_offset: #y_offset: #z_offset: diff --git a/docs/BLTouch.md b/docs/BLTouch.md index 199ca153..562c372b 100644 --- a/docs/BLTouch.md +++ b/docs/BLTouch.md @@ -105,6 +105,46 @@ to find the right position so it is able to lower and raise the pin and the red light turns on and of. Use the `reset`, `pin_up` and `pin_down` commands to achieve this. +BL-Touch output mode +==================== + +* A BL-Touch V3.0 supports setting a 5V or OPEN-DRAIN output mode, + a BL-Touch V3.1 supports this too, but can also store this in its + internal EEPROM. If your controller board needs the fixed 5V high + logic level of the 5V mode you may set the 'set_output_mode' + parameter in the [bltouch] section of the printer config file to + "5V". + + *** Only use the 5V mode if your controller boards input line is + 5V tolerant. This is why the default configuration of these BL-Touch + versions is OPEN-DRAIN mode. You could potentially damage your + controller boards CPU *** + + So therefore: + If a controller board NEEDs 5V mode AND it is 5V tolerant on its + input signal line AND if + + - you have a BL-Touch Smart V3.0, you need the use 'set_output_mode: 5V' + parameter to ensure this setting at each startup, since the probe + cannot remember the needed setting. + - you have a BL-Touch Smart V3.1, you have the choice of using + 'set_output_mode: 5V' or storing the mode once by use of a + 'BLTOUCH_STORE MODE=5V' command manually and NOT using the parameter + 'set_output_mode:'. + - you have some other probe: Some probes have a trace on the circuit board + to cut or a jumper to set in order to (permanently) set the output mode. + In that case, omit the 'set_output_mode' parameter completely. + + If you have a V3.1, do not automate or repeat storing the output mode to + avoid wearing out the EEPROM of the probe.The BLTouch EEPROM is good for + about 100.000 updates. 100 stores per day would add up to about 3 years + of operation prior to wearing it out. Thus, storing the output mode in a + V3.1 is designed by the vendor to be a complicated operation (the factory + default being a safe OPEN DRAIN mode) and is not suited to be repeatedly + issued by any slicer, macro or anything else, it is preferably only to be + used when first integrating the probe into a printers electronics. + + Troubleshooting =============== diff --git a/docs/G-Codes.md b/docs/G-Codes.md index e5b6427b..7a7da6cf 100644 --- a/docs/G-Codes.md +++ b/docs/G-Codes.md @@ -300,7 +300,14 @@ The following command is available when a "bltouch" config section is enabled: - `BLTOUCH_DEBUG COMMAND=`: This sends a command to the BLTouch. It may be useful for debugging. Available commands are: - pin_down, touch_mode, pin_up, self_test, reset. + `pin_down`, `touch_mode`, `pin_up`, `self_test`, `reset`, + (*1): `set_5V_output_mode`, `set_OD_output_mode`, `output_mode_store` + + *** Note that the commands marked by (*1) are solely supported + by a BL-Touch V3.0 or V3.1(+) + +- `BLTOUCH_STORE MODE=`: This stores an output mode in the + EEPROM of a BLTouch V3.1 Available output_modes are: `5V`, `OD` See [Working with the BL-Touch](BLTouch.md) for more details. diff --git a/klippy/extras/bltouch.py b/klippy/extras/bltouch.py index d5b4becc..8f8dabaa 100644 --- a/klippy/extras/bltouch.py +++ b/klippy/extras/bltouch.py @@ -18,6 +18,8 @@ ENDSTOP_SAMPLE_COUNT = 4 Commands = { None: 0.0, 'pin_down': 0.000650, 'touch_mode': 0.001165, 'pin_up': 0.001475, 'self_test': 0.001780, 'reset': 0.002190, + 'set_5V_output_mode' : 0.001988, 'set_OD_output_mode' : 0.002091, + 'output_mode_store' : 0.001884, } # BLTouch "endstop" wrapper @@ -41,6 +43,10 @@ class BLTouchEndstopWrapper: mcu = pin_params['chip'] mcu.register_config_callback(self._build_config) self.mcu_endstop = mcu.setup_pin('endstop', pin_params) + # output mode + self.output_mode = config.getchoice('set_output_mode', + {'5V': '5V', 'OD': 'OD', + None: None}, None) # Setup for sensor test self.next_test_time = 0. self.pin_up_not_triggered = config.getboolean( @@ -61,6 +67,8 @@ class BLTouchEndstopWrapper: self.gcode = self.printer.lookup_object('gcode') self.gcode.register_command("BLTOUCH_DEBUG", self.cmd_BLTOUCH_DEBUG, desc=self.cmd_BLTOUCH_DEBUG_help) + self.gcode.register_command("BLTOUCH_STORE", self.cmd_BLTOUCH_STORE, + desc=self.cmd_BLTOUCH_STORE_help) # multi probes state self.multi = 'OFF' def _build_config(self): @@ -69,6 +77,7 @@ class BLTouchEndstopWrapper: if stepper.is_active_axis('z'): self.add_stepper(stepper) def handle_connect(self): + self.set_output_mode(self.output_mode) try: self.raise_probe() except homing.CommandError as e: @@ -178,6 +187,44 @@ class BLTouchEndstopWrapper: sample_count, rest_time) def get_position_endstop(self): return self.position_endstop + def set_output_mode(self, mode): + # If this is inadvertently/purposely issued for a + # BLTOUCH pre V3.0 and clones: + # No reaction at all. + # BLTOUCH V3.0 and V3.1: + # This will set the mode. + if mode is None: + return + logging.info("BLTouch set output mode: %s", mode) + self.sync_mcu_print_time() + if mode == '5V': + self.send_cmd('set_5V_output_mode') + if mode == 'OD': + self.send_cmd('set_OD_output_mode') + def store_output_mode(self, mode): + # If this command is inadvertently/purposely issued for a + # BLTOUCH pre V3.0 and clones: + # No reaction at all to this sequence apart from a pin-down/pin-up + # BLTOUCH V3.0: + # This will set the mode (twice) and sadly, a pin-up is needed at + # the end, because of the pin-down + # BLTOUCH V3.1: + # This will set the mode and store it in the eeprom. + # The pin-up is not needed but does not hurt + logging.info("BLTouch store output mode: %s", mode) + self.sync_print_time() + self.send_cmd('pin_down') + if mode == '5V': + self.send_cmd('set_5V_output_mode') + else: + self.send_cmd('set_OD_output_mode') + self.send_cmd('output_mode_store') + if mode == '5V': + self.send_cmd('set_5V_output_mode') + else: + self.send_cmd('set_OD_output_mode') + self.send_cmd('pin_up') + self.send_cmd(None) cmd_BLTOUCH_DEBUG_help = "Send a command to the bltouch for debugging" def cmd_BLTOUCH_DEBUG(self, params): cmd = self.gcode.get_str('COMMAND', params, None) @@ -190,6 +237,16 @@ class BLTouchEndstopWrapper: self.send_cmd(cmd, duration=self.pin_move_time) self.send_cmd(None) self.sync_print_time() + cmd_BLTOUCH_STORE_help = "Store an output mode in the BLTouch EEPROM" + def cmd_BLTOUCH_STORE(self, params): + cmd = self.gcode.get_str('MODE', params, None) + if cmd is None or cmd not in ['5V', 'OD']: + self.gcode.respond_info("BLTouch output modes: 5V, OD") + return + self.gcode.respond_info("Storing BLTouch output mode: %s" % (cmd,)) + self.sync_print_time() + self.store_output_mode(cmd) + self.sync_print_time() def load_config(config): blt = BLTouchEndstopWrapper(config)