mirror of
				https://github.com/Klipper3d/klipper.git
				synced 2025-10-31 02:15:52 +01:00 
			
		
		
		
	pwm_cycle_time: New module for output pins with dynamic cycle times
Remove support for changing the cycle time of pwm pins from the output_pin module. Use a new pwm_cycle_time module that supports setting dynamic cycle times. This simplifies the output_pin code and low-level pin update code. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
		| @@ -61,12 +61,10 @@ gcode: | |||||||
| #   P is the tone duration, S the tone frequency. | #   P is the tone duration, S the tone frequency. | ||||||
| # The frequency won't be pitch perfect. | # The frequency won't be pitch perfect. | ||||||
|  |  | ||||||
| [output_pin BEEPER_pin] | [pwm_cycle_time BEEPER_pin] | ||||||
| pin: ar37 | pin: ar37 | ||||||
| #   Beeper pin. This parameter must be provided. | #   Beeper pin. This parameter must be provided. | ||||||
| #   ar37 is the default RAMPS/MKS pin. | #   ar37 is the default RAMPS/MKS pin. | ||||||
| pwm: True |  | ||||||
| #   A piezo beeper needs a PWM signal, a DC buzzer doesn't. |  | ||||||
| value: 0 | value: 0 | ||||||
| #   Silent at power on, set to 1 if active low. | #   Silent at power on, set to 1 if active low. | ||||||
| shutdown_value: 0 | shutdown_value: 0 | ||||||
|   | |||||||
| @@ -8,6 +8,11 @@ All dates in this document are approximate. | |||||||
|  |  | ||||||
| ## Changes | ## Changes | ||||||
|  |  | ||||||
|  | 20240123: The output_pin SET_PIN CYCLE_TIME parameter has been | ||||||
|  | removed. Use the new | ||||||
|  | [pwm_cycle_time](Config_Reference.md#pwm_cycle_time) module if it is | ||||||
|  | necessary to dynamically change a pwm pin's cycle time. | ||||||
|  |  | ||||||
| 20240123: The output_pin `maximum_mcu_duration` parameter is | 20240123: The output_pin `maximum_mcu_duration` parameter is | ||||||
| deprecated. Use a [pwm_tool config section](Config_Reference.md#pwm_tool) | deprecated. Use a [pwm_tool config section](Config_Reference.md#pwm_tool) | ||||||
| instead. The option will be removed in the near future. | instead. The option will be removed in the near future. | ||||||
|   | |||||||
| @@ -3153,6 +3153,24 @@ pin: | |||||||
| #   See the "output_pin" section for the definition of these parameters. | #   See the "output_pin" section for the definition of these parameters. | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
|  | ### [pwm_cycle_time] | ||||||
|  |  | ||||||
|  | Run-time configurable output pins with dynamic pwm cycle timing (one | ||||||
|  | may define any number of sections with an "pwm_cycle_time" prefix). | ||||||
|  | Pins configured here will be setup as output pins and one may modify | ||||||
|  | them at run-time using "SET_PIN PIN=my_pin VALUE=.1 CYCLE_TIME=0.100" | ||||||
|  | type extended [g-code commands](G-Codes.md#pwm_cycle_time). | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | [pwm_cycle_time my_pin] | ||||||
|  | pin: | ||||||
|  | #value: | ||||||
|  | #shutdown_value: | ||||||
|  | #cycle_time: 0.100 | ||||||
|  | #scale: | ||||||
|  | #   See the "output_pin" section for information on these parameters. | ||||||
|  | ``` | ||||||
|  |  | ||||||
| ### [static_digital_output] | ### [static_digital_output] | ||||||
|  |  | ||||||
| Statically configured digital output pins (one may define any number | Statically configured digital output pins (one may define any number | ||||||
|   | |||||||
| @@ -839,17 +839,10 @@ The following command is available when an | |||||||
| enabled. | enabled. | ||||||
|  |  | ||||||
| #### SET_PIN | #### SET_PIN | ||||||
| `SET_PIN PIN=config_name VALUE=<value> [CYCLE_TIME=<cycle_time>]`: Set | `SET_PIN PIN=config_name VALUE=<value>`: Set the pin to the given | ||||||
| the pin to the given output `VALUE`. VALUE should be 0 or 1 for | output `VALUE`. VALUE should be 0 or 1 for "digital" output pins. For | ||||||
| "digital" output pins. For PWM pins, set to a value between 0.0 and | PWM pins, set to a value between 0.0 and 1.0, or between 0.0 and | ||||||
| 1.0, or between 0.0 and `scale` if a scale is configured in the | `scale` if a scale is configured in the output_pin config section. | ||||||
| output_pin config section. |  | ||||||
|  |  | ||||||
| Some pins (currently only "soft PWM" pins) support setting an explicit |  | ||||||
| cycle time using the CYCLE_TIME parameter (specified in seconds). Note |  | ||||||
| that the CYCLE_TIME parameter is not stored between SET_PIN commands |  | ||||||
| (any SET_PIN command without an explicit CYCLE_TIME parameter will use |  | ||||||
| the `cycle_time` specified in the output_pin config section). |  | ||||||
|  |  | ||||||
| ### [palette2] | ### [palette2] | ||||||
|  |  | ||||||
| @@ -978,6 +971,21 @@ babystepping), and subtract if from the probe's z_offset.  This acts | |||||||
| to take a frequently used babystepping value, and "make it permanent". | to take a frequently used babystepping value, and "make it permanent". | ||||||
| Requires a `SAVE_CONFIG` to take effect. | Requires a `SAVE_CONFIG` to take effect. | ||||||
|  |  | ||||||
|  | ### [pwm_cycle_time] | ||||||
|  |  | ||||||
|  | The following command is available when a | ||||||
|  | [pwm_cycle_time config section](Config_Reference.md#pwm_cycle_time) | ||||||
|  | is enabled. | ||||||
|  |  | ||||||
|  | #### SET_PIN | ||||||
|  | `SET_PIN PIN=config_name VALUE=<value> [CYCLE_TIME=<cycle_time>]`: | ||||||
|  | This command works similarly to [output_pin](#output_pin) SET_PIN | ||||||
|  | commands. The command here supports setting an explicit cycle time | ||||||
|  | using the CYCLE_TIME parameter (specified in seconds). Note that the | ||||||
|  | CYCLE_TIME parameter is not stored between SET_PIN commands (any | ||||||
|  | SET_PIN command without an explicit CYCLE_TIME parameter will use the | ||||||
|  | `cycle_time` specified in the pwm_cycle_time config section). | ||||||
|  |  | ||||||
| ### [query_adc] | ### [query_adc] | ||||||
|  |  | ||||||
| The query_adc module is automatically loaded. | The query_adc module is automatically loaded. | ||||||
|   | |||||||
| @@ -374,6 +374,13 @@ is defined): | |||||||
|   template expansion, the PROBE (or similar) command must be run prior |   template expansion, the PROBE (or similar) command must be run prior | ||||||
|   to the macro containing this reference. |   to the macro containing this reference. | ||||||
|  |  | ||||||
|  | ## pwm_cycle_time | ||||||
|  |  | ||||||
|  | The following information is available in | ||||||
|  | [pwm_cycle_time some_name](Config_Reference.md#pwm_cycle_time) | ||||||
|  | objects: | ||||||
|  | - `value`: The "value" of the pin, as set by a `SET_PIN` command. | ||||||
|  |  | ||||||
| ## quad_gantry_level | ## quad_gantry_level | ||||||
|  |  | ||||||
| The following information is available in the `quad_gantry_level` object | The following information is available in the `quad_gantry_level` object | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| # Code to configure miscellaneous chips | # PWM and digital output pin handling | ||||||
| # | # | ||||||
| # Copyright (C) 2017-2021  Kevin O'Connor <kevin@koconnor.net> | # Copyright (C) 2017-2024  Kevin O'Connor <kevin@koconnor.net> | ||||||
| # | # | ||||||
| # This file may be distributed under the terms of the GNU GPLv3 license. | # This file may be distributed under the terms of the GNU GPLv3 license. | ||||||
|  |  | ||||||
| @@ -21,11 +21,9 @@ class PrinterOutputPin: | |||||||
|             hardware_pwm = config.getboolean('hardware_pwm', False) |             hardware_pwm = config.getboolean('hardware_pwm', False) | ||||||
|             self.mcu_pin.setup_cycle_time(cycle_time, hardware_pwm) |             self.mcu_pin.setup_cycle_time(cycle_time, hardware_pwm) | ||||||
|             self.scale = config.getfloat('scale', 1., above=0.) |             self.scale = config.getfloat('scale', 1., above=0.) | ||||||
|             self.last_cycle_time = self.default_cycle_time = cycle_time |  | ||||||
|         else: |         else: | ||||||
|             self.mcu_pin = ppins.setup_pin('digital_out', config.get('pin')) |             self.mcu_pin = ppins.setup_pin('digital_out', config.get('pin')) | ||||||
|             self.scale = 1. |             self.scale = 1. | ||||||
|             self.last_cycle_time = self.default_cycle_time = 0. |  | ||||||
|         self.last_print_time = 0. |         self.last_print_time = 0. | ||||||
|         # Support mcu checking for maximum duration |         # Support mcu checking for maximum duration | ||||||
|         self.reactor = self.printer.get_reactor() |         self.reactor = self.printer.get_reactor() | ||||||
| @@ -58,32 +56,30 @@ class PrinterOutputPin: | |||||||
|                                    desc=self.cmd_SET_PIN_help) |                                    desc=self.cmd_SET_PIN_help) | ||||||
|     def get_status(self, eventtime): |     def get_status(self, eventtime): | ||||||
|         return {'value': self.last_value} |         return {'value': self.last_value} | ||||||
|     def _set_pin(self, print_time, value, cycle_time, is_resend=False): |     def _set_pin(self, print_time, value, is_resend=False): | ||||||
|         if value == self.last_value and cycle_time == self.last_cycle_time: |         if value == self.last_value and not is_resend: | ||||||
|             if not is_resend: |  | ||||||
|             return |             return | ||||||
|         print_time = max(print_time, self.last_print_time + PIN_MIN_TIME) |         print_time = max(print_time, self.last_print_time + PIN_MIN_TIME) | ||||||
|         if self.is_pwm: |         if self.is_pwm: | ||||||
|             self.mcu_pin.set_pwm(print_time, value, cycle_time) |             self.mcu_pin.set_pwm(print_time, value) | ||||||
|         else: |         else: | ||||||
|             self.mcu_pin.set_digital(print_time, value) |             self.mcu_pin.set_digital(print_time, value) | ||||||
|         self.last_value = value |         self.last_value = value | ||||||
|         self.last_cycle_time = cycle_time |  | ||||||
|         self.last_print_time = print_time |         self.last_print_time = print_time | ||||||
|         if self.resend_interval and self.resend_timer is None: |         if self.resend_interval and self.resend_timer is None: | ||||||
|             self.resend_timer = self.reactor.register_timer( |             self.resend_timer = self.reactor.register_timer( | ||||||
|                 self._resend_current_val, self.reactor.NOW) |                 self._resend_current_val, self.reactor.NOW) | ||||||
|     cmd_SET_PIN_help = "Set the value of an output pin" |     cmd_SET_PIN_help = "Set the value of an output pin" | ||||||
|     def cmd_SET_PIN(self, gcmd): |     def cmd_SET_PIN(self, gcmd): | ||||||
|  |         # Read requested value | ||||||
|         value = gcmd.get_float('VALUE', minval=0., maxval=self.scale) |         value = gcmd.get_float('VALUE', minval=0., maxval=self.scale) | ||||||
|         value /= self.scale |         value /= self.scale | ||||||
|         cycle_time = gcmd.get_float('CYCLE_TIME', self.default_cycle_time, |  | ||||||
|                                     above=0., maxval=MAX_SCHEDULE_TIME) |  | ||||||
|         if not self.is_pwm and value not in [0., 1.]: |         if not self.is_pwm and value not in [0., 1.]: | ||||||
|             raise gcmd.error("Invalid pin value") |             raise gcmd.error("Invalid pin value") | ||||||
|  |         # Obtain print_time and apply requested settings | ||||||
|         toolhead = self.printer.lookup_object('toolhead') |         toolhead = self.printer.lookup_object('toolhead') | ||||||
|         toolhead.register_lookahead_callback( |         toolhead.register_lookahead_callback( | ||||||
|             lambda print_time: self._set_pin(print_time, value, cycle_time)) |             lambda print_time: self._set_pin(print_time, value)) | ||||||
|  |  | ||||||
|     def _resend_current_val(self, eventtime): |     def _resend_current_val(self, eventtime): | ||||||
|         if self.last_value == self.shutdown_value: |         if self.last_value == self.shutdown_value: | ||||||
| @@ -97,8 +93,7 @@ class PrinterOutputPin: | |||||||
|         if time_diff > 0.: |         if time_diff > 0.: | ||||||
|             # Reschedule for resend time |             # Reschedule for resend time | ||||||
|             return systime + time_diff |             return systime + time_diff | ||||||
|         self._set_pin(print_time + PIN_MIN_TIME, |         self._set_pin(print_time + PIN_MIN_TIME, self.last_value, True) | ||||||
|                       self.last_value, self.last_cycle_time, True) |  | ||||||
|         return systime + self.resend_interval |         return systime + self.resend_interval | ||||||
|  |  | ||||||
| def load_config_prefix(config): | def load_config_prefix(config): | ||||||
|   | |||||||
							
								
								
									
										123
									
								
								klippy/extras/pwm_cycle_time.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								klippy/extras/pwm_cycle_time.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,123 @@ | |||||||
|  | # Handle pwm output pins with variable frequency | ||||||
|  | # | ||||||
|  | # Copyright (C) 2017-2023  Kevin O'Connor <kevin@koconnor.net> | ||||||
|  | # | ||||||
|  | # This file may be distributed under the terms of the GNU GPLv3 license. | ||||||
|  |  | ||||||
|  | PIN_MIN_TIME = 0.100 | ||||||
|  | MAX_SCHEDULE_TIME = 5.0 | ||||||
|  |  | ||||||
|  | class MCU_pwm_cycle: | ||||||
|  |     def __init__(self, pin_params, cycle_time, start_value, shutdown_value): | ||||||
|  |         self._mcu = pin_params['chip'] | ||||||
|  |         self._cycle_time = cycle_time | ||||||
|  |         self._oid = None | ||||||
|  |         self._mcu.register_config_callback(self._build_config) | ||||||
|  |         self._pin = pin_params['pin'] | ||||||
|  |         self._invert = pin_params['invert'] | ||||||
|  |         if self._invert: | ||||||
|  |             start_value = 1. - start_value | ||||||
|  |             shutdown_value = 1. - shutdown_value | ||||||
|  |         self._start_value = max(0., min(1., start_value)) | ||||||
|  |         self._shutdown_value = max(0., min(1., shutdown_value)) | ||||||
|  |         self._last_clock = self._cycle_ticks = 0 | ||||||
|  |         self._set_cmd = self._set_cycle_ticks = None | ||||||
|  |     def _build_config(self): | ||||||
|  |         cmd_queue = self._mcu.alloc_command_queue() | ||||||
|  |         curtime = self._mcu.get_printer().get_reactor().monotonic() | ||||||
|  |         printtime = self._mcu.estimated_print_time(curtime) | ||||||
|  |         self._last_clock = self._mcu.print_time_to_clock(printtime + 0.200) | ||||||
|  |         cycle_ticks = self._mcu.seconds_to_clock(self._cycle_time) | ||||||
|  |         if self._shutdown_value not in [0., 1.]: | ||||||
|  |             raise self._mcu.get_printer().config_error( | ||||||
|  |                 "shutdown value must be 0.0 or 1.0 on soft pwm") | ||||||
|  |         if cycle_ticks >= 1<<31: | ||||||
|  |             raise self._mcu.get_printer().config_error( | ||||||
|  |                 "PWM pin cycle time too large") | ||||||
|  |         self._mcu.request_move_queue_slot() | ||||||
|  |         self._oid = self._mcu.create_oid() | ||||||
|  |         self._mcu.add_config_cmd( | ||||||
|  |             "config_digital_out oid=%d pin=%s value=%d" | ||||||
|  |             " default_value=%d max_duration=%d" | ||||||
|  |             % (self._oid, self._pin, self._start_value >= 1.0, | ||||||
|  |                self._shutdown_value >= 0.5, 0)) | ||||||
|  |         self._mcu.add_config_cmd( | ||||||
|  |             "set_digital_out_pwm_cycle oid=%d cycle_ticks=%d" | ||||||
|  |             % (self._oid, cycle_ticks)) | ||||||
|  |         self._cycle_ticks = cycle_ticks | ||||||
|  |         svalue = int(self._start_value * cycle_ticks + 0.5) | ||||||
|  |         self._mcu.add_config_cmd( | ||||||
|  |             "queue_digital_out oid=%d clock=%d on_ticks=%d" | ||||||
|  |             % (self._oid, self._last_clock, svalue), is_init=True) | ||||||
|  |         self._set_cmd = self._mcu.lookup_command( | ||||||
|  |             "queue_digital_out oid=%c clock=%u on_ticks=%u", cq=cmd_queue) | ||||||
|  |         self._set_cycle_ticks = self._mcu.lookup_command( | ||||||
|  |             "set_digital_out_pwm_cycle oid=%c cycle_ticks=%u", cq=cmd_queue) | ||||||
|  |     def set_pwm_cycle(self, print_time, value, cycle_time): | ||||||
|  |         clock = self._mcu.print_time_to_clock(print_time) | ||||||
|  |         minclock = self._last_clock | ||||||
|  |         # Send updated cycle_time if necessary | ||||||
|  |         cycle_ticks = self._mcu.seconds_to_clock(cycle_time) | ||||||
|  |         if cycle_ticks != self._cycle_ticks: | ||||||
|  |             if cycle_ticks >= 1<<31: | ||||||
|  |                 raise self._mcu.get_printer().command_error( | ||||||
|  |                     "PWM cycle time too large") | ||||||
|  |             self._set_cycle_ticks.send([self._oid, cycle_ticks], | ||||||
|  |                                        minclock=minclock, reqclock=clock) | ||||||
|  |             self._cycle_ticks = cycle_ticks | ||||||
|  |         # Send pwm update | ||||||
|  |         if self._invert: | ||||||
|  |             value = 1. - value | ||||||
|  |         v = int(max(0., min(1., value)) * float(self._cycle_ticks) + 0.5) | ||||||
|  |         self._set_cmd.send([self._oid, clock, v], | ||||||
|  |                            minclock=self._last_clock, reqclock=clock) | ||||||
|  |         self._last_clock = clock | ||||||
|  |  | ||||||
|  | class PrinterOutputPWMCycle: | ||||||
|  |     def __init__(self, config): | ||||||
|  |         self.printer = config.get_printer() | ||||||
|  |         self.last_print_time = 0. | ||||||
|  |         cycle_time = config.getfloat('cycle_time', 0.100, above=0., | ||||||
|  |                                      maxval=MAX_SCHEDULE_TIME) | ||||||
|  |         self.last_cycle_time = self.default_cycle_time = cycle_time | ||||||
|  |         # Determine start and shutdown values | ||||||
|  |         self.scale = config.getfloat('scale', 1., above=0.) | ||||||
|  |         self.last_value = config.getfloat( | ||||||
|  |             'value', 0., minval=0., maxval=self.scale) / self.scale | ||||||
|  |         self.shutdown_value = config.getfloat( | ||||||
|  |             'shutdown_value', 0., minval=0., maxval=self.scale) / self.scale | ||||||
|  |         # Create pwm pin object | ||||||
|  |         ppins = self.printer.lookup_object('pins') | ||||||
|  |         pin_params = ppins.lookup_pin(config.get('pin'), can_invert=True) | ||||||
|  |         self.mcu_pin = MCU_pwm_cycle(pin_params, cycle_time, | ||||||
|  |                                      self.last_value, self.shutdown_value) | ||||||
|  |         # Register commands | ||||||
|  |         pin_name = config.get_name().split()[1] | ||||||
|  |         gcode = self.printer.lookup_object('gcode') | ||||||
|  |         gcode.register_mux_command("SET_PIN", "PIN", pin_name, | ||||||
|  |                                    self.cmd_SET_PIN, | ||||||
|  |                                    desc=self.cmd_SET_PIN_help) | ||||||
|  |     def get_status(self, eventtime): | ||||||
|  |         return {'value': self.last_value} | ||||||
|  |     def _set_pin(self, print_time, value, cycle_time): | ||||||
|  |         if value == self.last_value and cycle_time == self.last_cycle_time: | ||||||
|  |             return | ||||||
|  |         print_time = max(print_time, self.last_print_time + PIN_MIN_TIME) | ||||||
|  |         self.mcu_pin.set_pwm_cycle(print_time, value, cycle_time) | ||||||
|  |         self.last_value = value | ||||||
|  |         self.last_cycle_time = cycle_time | ||||||
|  |         self.last_print_time = print_time | ||||||
|  |     cmd_SET_PIN_help = "Set the value of an output pin" | ||||||
|  |     def cmd_SET_PIN(self, gcmd): | ||||||
|  |         # Read requested value | ||||||
|  |         value = gcmd.get_float('VALUE', minval=0., maxval=self.scale) | ||||||
|  |         value /= self.scale | ||||||
|  |         cycle_time = gcmd.get_float('CYCLE_TIME', self.default_cycle_time, | ||||||
|  |                                     above=0., maxval=MAX_SCHEDULE_TIME) | ||||||
|  |         # Obtain print_time and apply requested settings | ||||||
|  |         toolhead = self.printer.lookup_object('toolhead') | ||||||
|  |         toolhead.register_lookahead_callback( | ||||||
|  |             lambda print_time: self._set_pin(print_time, value, cycle_time)) | ||||||
|  |  | ||||||
|  | def load_config_prefix(config): | ||||||
|  |     return PrinterOutputPWMCycle(config) | ||||||
| @@ -5,6 +5,12 @@ value: 0 | |||||||
| shutdown_value: 0 | shutdown_value: 0 | ||||||
| cycle_time: 0.01 | cycle_time: 0.01 | ||||||
|  |  | ||||||
|  | [pwm_cycle_time cycle_pwm_pin] | ||||||
|  | pin: PH7 | ||||||
|  | value: 0 | ||||||
|  | shutdown_value: 0 | ||||||
|  | cycle_time: 0.01 | ||||||
|  |  | ||||||
| [output_pin hard_pwm_pin] | [output_pin hard_pwm_pin] | ||||||
| pin: PH6 | pin: PH6 | ||||||
| pwm: True | pwm: True | ||||||
|   | |||||||
| @@ -16,18 +16,24 @@ SET_PIN PIN=soft_pwm_pin VALUE=0 | |||||||
| SET_PIN PIN=soft_pwm_pin VALUE=0.5 | SET_PIN PIN=soft_pwm_pin VALUE=0.5 | ||||||
| SET_PIN PIN=soft_pwm_pin VALUE=1 | SET_PIN PIN=soft_pwm_pin VALUE=1 | ||||||
|  |  | ||||||
|  | # Soft PWM with dynamic cycle time | ||||||
|  | # Test basic on off | ||||||
|  | SET_PIN PIN=cycle_pwm_pin VALUE=0 | ||||||
|  | SET_PIN PIN=cycle_pwm_pin VALUE=0.5 | ||||||
|  | SET_PIN PIN=cycle_pwm_pin VALUE=1 | ||||||
|  |  | ||||||
| # Test cycle time | # Test cycle time | ||||||
| SET_PIN PIN=soft_pwm_pin VALUE=0 CYCLE_TIME=0.1 | SET_PIN PIN=cycle_pwm_pin VALUE=0 CYCLE_TIME=0.1 | ||||||
| SET_PIN PIN=soft_pwm_pin VALUE=1 CYCLE_TIME=0.5 | SET_PIN PIN=cycle_pwm_pin VALUE=1 CYCLE_TIME=0.5 | ||||||
| SET_PIN PIN=soft_pwm_pin VALUE=0.5 CYCLE_TIME=0.001 | SET_PIN PIN=cycle_pwm_pin VALUE=0.5 CYCLE_TIME=0.001 | ||||||
| SET_PIN PIN=soft_pwm_pin VALUE=0.75 CYCLE_TIME=0.01 | SET_PIN PIN=cycle_pwm_pin VALUE=0.75 CYCLE_TIME=0.01 | ||||||
| SET_PIN PIN=soft_pwm_pin VALUE=0.5 CYCLE_TIME=1 | SET_PIN PIN=cycle_pwm_pin VALUE=0.5 CYCLE_TIME=1 | ||||||
|  |  | ||||||
| # Test duplicate values | # Test duplicate values | ||||||
| SET_PIN PIN=soft_pwm_pin VALUE=0.5 CYCLE_TIME=0.5 | SET_PIN PIN=cycle_pwm_pin VALUE=0.5 CYCLE_TIME=0.5 | ||||||
| SET_PIN PIN=soft_pwm_pin VALUE=0.5 CYCLE_TIME=0.5 | SET_PIN PIN=cycle_pwm_pin VALUE=0.5 CYCLE_TIME=0.5 | ||||||
| SET_PIN PIN=soft_pwm_pin VALUE=0.75 CYCLE_TIME=0.5 | SET_PIN PIN=cycle_pwm_pin VALUE=0.75 CYCLE_TIME=0.5 | ||||||
| SET_PIN PIN=soft_pwm_pin VALUE=0.75 CYCLE_TIME=0.75 | SET_PIN PIN=cycle_pwm_pin VALUE=0.75 CYCLE_TIME=0.75 | ||||||
|  |  | ||||||
| # PWM tool | # PWM tool | ||||||
| # Basic test | # Basic test | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user