Switch module

The Switch module takes care of basic input from things like buttons and switches and controls simple devices like fans and pumps.

It is an incredibly versatile tool that allows you to setup a lot of on-off type systems. It listens to input pins and outputs custom G/M-codes or accepts custom G/M-codes and set outputs to GPIO pins.

This allows you to do one of the following:

  • Make a G-code control an output GPIO pin
  • Make a GPIO input pin cause a G/M-code to be executed
  • Make a GPIO pin control another GPIO pin (this may not work anymore)

You can create several different switch modules to fit your needs, within the same configuration file.

If you come from the industry, the Switch module is Smoothie’s implementation of a Programmable Logic Controller feature.

Configuration

Like TemperatureControl, there can be multiple Switch modules. All you need to do is give each module its own name in the config file.

switch.fan1.enable                        false
switch.fan1.output_pin                    2.7
etc ...

switch.fan2.enable                        false
switch.fan2.output_pin                    2.6
etc ...

switch.zplus10.enable                     true
switch.zplus10.input_pin                  1.7
switch.zplus10.output_on_command          G91G0Z10G90      # G90 and G91 switch to relative positioning then back to absolute

etc ...
[switch]
fan1.enable = false
fan1.output_pin = 2.7
; etc ...

fan2.enable = false
fan2.output_pin = 2.6
; etc ...

zplus10.enable = true
zplus10.input_pin = 1.7
zplus10.output_on_command = G91G0Z10G90      # G90 and G91 switch to relative positioning then back to absolute

; etc ...

All options

V1 Setting V2 Setting Description
Creates and enables a new Switch module instance. When set to true, the switch module is active and will respond to configured inputs and control outputs. Set to false to disable the switch instance without removing its configuration. Each switch instance requires a unique name.
Specifies a GPIO pin that controls the switch state through hardware input. When this pin becomes high the switch changes to the ON state, and when it becomes low the switch changes to the OFF state (behavior depends on input_pin_behavior). Input pins are polled at 100ms intervals. Pin can be configured with pullup (^) or inverted (!) modifiers.
Defines how the input pin controls the switch state. If set to momentary (default), the switch state tracks the pin state directly - when the input pin becomes high the switch changes to ON, and when it becomes low the switch changes to OFF. If set to toggle, pin state transitions (low-to-high) flip the switch state between ON and OFF.
Specifies a G-code or M-code command that sets the switch to the ON state. When this command is received, the switch turns ON. Supports optional subcode matching via switch.{name}.subcode. The S parameter can control PWM value for PWM-type outputs. Commands are queued and executed synchronously with motion.
Specifies a G-code or M-code command that sets the switch to the OFF state. When this command is received, the switch turns OFF. Supports optional subcode matching via switch.{name}.subcode. Commands are queued and executed synchronously with motion.
Specifies a subcode for input command matching. Allows multiple switch instances to respond to different subcodes of the same base command (e.g., M106.1 vs M106.2). Subcode 0 is the default and matches commands without explicit subcodes. Only evaluated when input_on_command and/or input_off_command are set.
Specifies the GPIO pin that is controlled by the switch. This pin will be set low when the switch is OFF, and high when the switch is ON. The pin's behavior depends on output_type (digital on/off, PWM, hardware PWM, or software PWM). For hardware PWM (hwpwm), pin must be PWM-capable.
Sets the type of output for the switch output pin. If set to digital the pin can only be low or high. If set to pwm (the default, using Sigma-Delta PWM) the pin can be set to any PWM value between 0 and 255 using the S parameter. If set to hwpwm will use Real PWM (requires PWM-capable pin), with S value as duty cycle in percent. Can also be set to swpwm for software-emulated PWM that won't interfere with hardware PWM peripherals. Can be set to none to disable the output entirely.
Specifies a G-code command to execute when the switch transitions to the ON state. The command is sent to the G-code parser and executed. Underscores in the command are replaced with spaces to allow multi-word commands (e.g., M117_Hello_World becomes M117 Hello World). Commands execute in the main loop when switch state changes to ON.
Specifies a G-code command to execute when the switch transitions to the OFF state. The command is sent to the G-code parser and executed. Underscores in the command are replaced with spaces before execution. Commands execute in the main loop when switch state changes to OFF. Special handling: $J STOP triggers emergency stop request for continuous jog (only works with input pins).
Sets the initial state of the switch when the system boots. If set to false (default) the module is initialized OFF, if set to true the module is initialized ON. For PWM outputs with startup_state true, uses default_on_value instead of startup_value. For input-pin switches (momentary mode), initial state is read from pin and overrides this setting.
Sets the PWM value when the switch is in the OFF state or at startup if startup_state is false. For SIGMADELTA PWM, this is a 0-255 value. For hardware/software PWM (hwpwm/swpwm), this is a 0-100 percentage. This value is also used as the PWM value on HALT for HWPWM and SWPWM. The startup_state must be false for this to take effect.
Sets the PWM duty cycle percentage when the switch is turned ON without an explicit S parameter. Only applies to hardware PWM (hwpwm) and software PWM (swpwm) output types. Value range is 0-100 (percentage). This is the value used when switch is turned on via command or when startup_state is true. Can be overridden by S parameter in commands (e.g., M106 S75 sets to 75%).
Sets the maximum PWM value for sigma-delta PWM output. Allows limiting the maximum output power/speed when using PWM mode. The S parameter in commands is scaled from 0-255 to 0-max_pwm. Only applies to SIGMADELTA (pwm) output type, not for hwpwm or swpwm. Default 255 means no limiting (full range).
Sets the PWM period in milliseconds for hardware PWM and software PWM outputs. This determines the PWM frequency. For servo control, typical value is 20ms (50Hz). Only applies to HWPWM and SWPWM output types. Lower period means higher frequency and faster PWM switching. For servos, standard is 20ms (50Hz), some servos support 10ms (100Hz). For LEDs, higher frequencies prevent visible flicker.
Defines the pin state (0 or 1) to set during a crash, watchdog reset, or debug halt condition. This is a safety feature to ensure outputs are in a safe state when the system fails. Different from halt_set_to which handles M112 HALT commands. Can be overridden by ignore_on_halt setting. Choose a value that puts your system in a safe state for your hardware.
Defines the switch state (true or false) to set during a HALT condition (typically triggered by M112 emergency stop or system halt). When a halt occurs, the switch is set to this state unless ignore_on_halt is true. For digital outputs, this boolean directly controls the pin state (high/low). For PWM outputs (hwpwm/swpwm), startup_value is used as the actual value. Different from failsafe_set_to which handles crash/debug conditions.
When set to true, prevents the switch from changing state during HALT conditions (M112 emergency stop). Set to true to not set the failsafe or startup_value value when a HALT condition is triggered. Automatically set to true for input-pin switches and cannot be overridden. Useful for non-safety-critical outputs (lights, status indicators) that should maintain their state during emergency stops.

Startup State

The initial internal state of the switch at boot is set by the setting, which should be set to “true” or “false”.

Also remember that individual pins can be inverted with a ! ( see Pin Configuration ). Default is false.

There is also a setting that sets the default analog value used for pwm on an output pin. This value defaults to always on.

switch.fan1.startup_state                 false
switch.fan1.startup_value                 127
[switch]
fan1.startup_state = false
fan1.startup_value = 127

Input and Output Pins

NOTE a switch can have either an input pin defined or an output pin but not both. If for some reason you needed an input pin to control one or more output pins you could define two (or more) switches, one input and one or more outputs. Then the input pin would define the M-codes that turn on/off the output pins in its output_on_command (and/or its output_off_command).

Input Pin

This setting will enable a pin that can be used to change the state of the switch. For example, a button can be configured that toggles the state of a fan. By default input_pin is set to “nc” which stands for “not connected”.

There is also a behavior setting for the input pin. Currently the valid options are momentary (default) and toggle.

The toggle behavior allows a momentary button to behave like an on-off toggle switch. If you are connecting a physical toggle switch you would probably want the behavior set to momentary.

switch.fan1.input_pin                     1.7!
switch.fan1.input_pin_behavior            toggle
[switch]
fan1.input_pin = 1.7!
fan1.input_pin_behavior = toggle

Output Pin

Set this config value to drive an output pin based on the internal state of the Switch module. Remember that the pin can always be inverted with a ! ( see Pin Configuration ).

switch.fan1.output_pin                    2.7
switch.fan1.output_type                  pwm             # pwm output settable with S parameter on the on command
switch.fan1.max_pwm                     255               # sets the max pwm for this pin
[switch]
fan1.output_pin = 2.7
fan1.output_type = pwm             # pwm output settable with S parameter on the on command
fan1.max_pwm = 255                 # sets the max pwm for this pin

To set an output pin to be non-pwm so it just turns on or off set output_type digital

switch.psu.output_type                    digital           # just on or off
switch.psu.output_pin                      1.30o!          # set to open drain, inverted to control an ATX PSON signal
[switch]
psu.output_type = digital           # just on or off
psu.output_pin = 1.30o!             # set to open drain, inverted to control an ATX PSON signal

Output type

There are four different output types: digital, pwm, swpwm and hwpwm, the default is pwm so a PWM output pin is configured by default. (The names MUST be lower case)

Note that pwm is actually SigmaDelta Modulation and will allow you to set PWM intensity via the S parameter to your G-codes, values between 0 and max_pwm are accepted, which is usually 255.

hwpwm is PWM controlled by the Hardware, and is PWM compatible with Hobby servos/bltouch and ESCs. The S parameter specifies the duty cycle in percent, and for a typical servo will be between 5% and 10% (1ms to 2ms when running at 50Hz) for a 180° turn. the default frequency is 50Hz but can be set with the pwm_period_ms config setting.

swpwm is PWM emulated by the software, and is PWM compatible with Hobby servos/bltouch and ESCs. And is otherwise similar to hwpwm. This is useful if your hwpwm clock must be set to a very high value for example for the laser module, as this would mean a hwpwm switch would need to have the same high value which can be incompatible with some hardware. Having a lower frequency swpwm allows for both the laser module and servos/bltouch control.

Commands and Gcodes

There are also a set of config settings that allow the Switch module to both generate and react to Gcodes as necessary. The input_on_command is also able to read an S parameter to set an analog value for pwm over the output pin. This allows things like driving a fan at less than full speed or dimming an led.

switch.fan1.input_on_command              M106     # any command that starts with this exact string turns this switch on
switch.fan1.input_off_command             M107     # any command starting with this exact string turns off the switch
[switch]
fan1.input_on_command = M106     # any command that starts with this exact string turns this switch on
fan1.input_off_command = M107    # any command starting with this exact string turns off the switch

In addition to input_on_command and input_off_command there are also corresponding config settings output_on_command and output_off_command. Offhand, it seems unlikely that a single switch module would need to use both input_ and output_ commands.

If you want to learn more about this module, or are curious how it works, Smoothie is Open-Source and you can simply go look at the code, here.

Examples

Fan

This configuration will allow you to control a fan using the standard reprap G-codes for controlling a fan

This is already present in the default configuration file

# Switch module for fan control
switch.fan.enable                            true             # Enable this module
switch.fan.input_on_command                  M106             # This switch is turned on when M106 is sent
switch.fan.input_off_command                 M107             # This switch is turned off when M107 is sent
switch.fan.output_pin                        2.6              # This pin is turned on when this switch is turned on, and vice-versa
switch.fan.output_type                       pwm              # PWM output settable with S parameter in the input_on_comand
#switch.fan.max_pwm                          255              # Set max PWM for the pin default is 255
[switch]
# Switch module for fan control
fan.enable = true                            # Enable this module
fan.input_on_command = M106                  # This switch is turned on when M106 is sent
fan.input_off_command = M107                 # This switch is turned off when M107 is sent
fan.output_pin = 2.6                         # This pin is turned on when this switch is turned on, and vice-versa
fan.output_type = pwm                        # PWM output settable with S parameter in the input_on_comand
#fan.max_pwm = 255                           # Set max PWM for the pin default is 255

Hobby Servo

This configuration will allow you to control a servo using the standard reprap G-codes for controlling a servo.

M280 S5 would be fully to the left and M280 S10 would be fully to the right.

# Switch module for servo control using S/W PWM
switch.servo.enable                            true             # Enable this module
switch.servo.input_on_command                  M280             # M280 S7.5 would be midway
switch.servo.input_off_command                 M281             # Same as M280 S0 0% duty cycle, effectively off
switch.servo.output_pin                        3.25             # May be any spare pin
switch.servo.output_type                       swpwm            # Software pwm output settable with S parameter in the input_on_command
#switch.servo.pwm_period_ms                    20               # set period to 20ms (50Hz) default is 50Hz
#switch.servo.startup_state                    false            # false uses startup_value on boot true uses default_on_value
#switch.servo.startup_value                    7.43             # On boot and HALT it will set this PWM value
#switch.servo.default_on_value                 3.3              # This PWM value will be set if M280 doe snot have an S parameter, it is also the value used if startup_state is true
[switch]
# Switch module for servo control using S/W PWM
servo.enable = true                            # Enable this module
servo.input_on_command = M280                  # M280 S7.5 would be midway
servo.input_off_command = M281                 # Same as M280 S0 0% duty cycle, effectively off
servo.output_pin = 3.25                        # May be any spare pin
servo.output_type = swpwm                      # Software pwm output settable with S parameter in the input_on_command
#servo.pwm_period_ms = 20                      # set period to 20ms (50Hz) default is 50Hz
#servo.startup_state = false                   # false uses startup_value on boot true uses default_on_value
#servo.startup_value = 7.43                    # On boot and HALT it will set this PWM value
#servo.default_on_value = 3.3                  # This PWM value will be set if M280 doe snot have an S parameter, it is also the value used if startup_state is true
# Switch module for a second servo control using H/W PWM
switch.servo2.enable                            true             # Enable this module
switch.servo2.input_on_command                  M280             # M280.1 S7.5 would be midway
switch.servo2.input_off_command                 M281             # Same as M280.1 S0 0% duty cycle, effectively off
switch.servo2.subcode                           1                # M280.1 will trigger this switch
switch.servo2.output_pin                        3.26             # Must be a PWM capable pin
switch.servo2.output_type                       hwpwm            # H/W pwm output settable with S parameter in the input_on_command
[switch]
# Switch module for a second servo control using H/W PWM
servo2.enable = true                           # Enable this module
servo2.input_on_command = M280                 # M280.1 S7.5 would be midway
servo2.input_off_command = M281                # Same as M280.1 S0 0% duty cycle, effectively off
servo2.subcode = 1                             # M280.1 will trigger this switch
servo2.output_pin = 3.26                       # Must be a PWM capable pin
servo2.output_type = hwpwm                     # H/W pwm output settable with S parameter in the input_on_command

To find a PWM-capable pins, see Pinout

Power supply control

Power Supply Control

This page describes how to control your power supply’s ON/OFF signal from Smoothie using the Switch module.

This allows your board to automatically turn the power supply on or off when needed, such as at the start or end of a job.


Method 1: Direct Connection to ATX PS_ON

Here is how to control an ATX power supply’s ON/OFF signal from a bare pin connected to the PS_ON signal:

switch.psu.enable                            true             # turn atx on/off
switch.psu.input_on_command                  M80              # command to turn on
switch.psu.input_off_command                 M81              # command to turn off
switch.psu.output_pin                        0.25o!           # open drain, inverted
switch.psu.output_type                       digital          # on/off only
switch.psu.failsafe_set_to                   1                # so the ATX turns off on a system crash
#switch.psu.ignore_on_halt                    true             # so the ATX does not turn off on a HALT condition (like limit trigger)
                                                               # However leave commented or set to false if you want the ATX to turn off for an over heat fault condition
[switch]
psu.enable = true             # turn atx on/off
psu.input_on_command = M80    # command to turn on
psu.input_off_command = M81   # command to turn off
psu.output_pin = 0.25o!       # open drain, inverted
psu.output_type = digital     # on/off only
psu.failsafe_set_to = 1       # so the ATX turns off on a system crash
#psu.ignore_on_halt = true    # so the ATX does not turn off on a HALT condition (like limit trigger)
                              # However leave commented or set to false if you want the ATX to turn off for an over heat fault condition
Note: This uses the PSON pin on the power supply, which should be open-drain, thus the o in 0.25o!.

Method 2: Using a MOSFET or SSR

Here is how to control an ATX power supply’s ON/OFF signal from a small MOSFET connected to the PS_ON signal, or to an SSR which powers a non-ATX PSU:

switch.psu.enable                            true             # turn atx on/off
switch.psu.input_on_command                  M80              # command to turn on
switch.psu.input_off_command                 M81              # command to turn off
switch.psu.output_pin                        2.4              # small mosfet (NB not inverted)
switch.psu.output_type                       digital          # on/off only
#switch.psu.ignore_on_halt                    true             # so the PSU does not turn off on a HALT condition (like limit trigger)
                                                               # However leave commented or set to false if you want the PSU to turn off for an over heat fault condition
[switch]
psu.enable = true             # turn atx on/off
psu.input_on_command = M80    # command to turn on
psu.input_off_command = M81   # command to turn off
psu.output_pin = 2.4          # small mosfet (NB not inverted)
psu.output_type = digital     # on/off only
#psu.ignore_on_halt = true    # so the PSU does not turn off on a HALT condition (like limit trigger)
                              # However leave commented or set to false if you want the PSU to turn off for an over heat fault condition
Tip: When using a MOSFET, note that the pin is NOT inverted (no ! after the pin number), unlike the direct connection method.

G-code Commands

Once configured, you can control your power supply with these commands:

Command Function
M80 Turn power supply ON
M81 Turn power supply OFF

Safety Considerations

Failsafe Behavior

The failsafe_set_to parameter ensures that if Smoothie crashes, the power supply will turn off automatically.

This is a critical safety feature.

Halt Behavior

The ignore_on_halt parameter determines whether the power supply should turn off when Smoothie enters a HALT condition (such as when a limit switch is triggered).

Options:

  • Commented out or set to false - Power supply will turn off on HALT conditions, including overheat faults (recommended for safety)
  • Set to true - Power supply stays on during HALT conditions from limit switches, but this may prevent automatic shutdown during dangerous conditions

Further Reading

Pause when out of filament

This configuration allows you to use a pin to detect when the machine is out of filament. When the switch is hit by the filament not being present, the machine is put into pause.

Another switch is configured to allow you to resume the machine once the button is pressed.

Additional configuration allows you to specify commands that are executed when the machine suspends, and when it resumes.

switch.filamentout.enable                true                     # Enable this module
switch.filamentout.input_pin             1.30^                    # Pin where filament out button is connected
switch.filamentout.output_on_command     suspend                  # Suspend command

switch.resume.enable                     true                     # Enable this module
switch.resume.input_pin                  1.31^                    # Pin where resume button is connected
switch.resume.output_on_command          resume                   # Resume command

after_suspend_gcode                      G91_G0E-5_G0Z10_G90_G0X-50Y-50        # Gcode to run after suspend, retract then get head out of way
before_resume_gcode                      G91_G1E1_G90                          # Gcode to run after temp is reached but before resume - do a prime
[switch]
filamentout.enable = true                     # Enable this module
filamentout.input_pin = 1.30^                 # Pin where filament out button is connected
filamentout.output_on_command = suspend       # Suspend command

resume.enable = true                          # Enable this module
resume.input_pin = 1.31^                      # Pin where resume button is connected
resume.output_on_command = resume             # Resume command

after_suspend_gcode = G91_G0E-5_G0Z10_G90_G0X-50Y-50        # Gcode to run after suspend, retract then get head out of way
before_resume_gcode = G91_G1E1_G90                          # Gcode to run after temp is reached but before resume - do a prime

Note, there is a real filament detector module which works much better than this, see filament-detector.

Suspend and resume buttons

This configuration allows you to set a suspend button, and a resume button.

switch.suspend.enable                true                     # Enable this module
switch.suspend.input_pin             1.30^                    # Pin where pause button is connected
switch.suspend.output_on_command     suspend                  # Suspend command

switch.resume.enable                 true                     # Enable this module
switch.resume.input_pin              1.31^                    # Pin where resume button is connected
switch.resume.output_on_command      resume                   # Resume command

after_suspend_gcode                  G91_G0E-5_G0Z10_G90_G0X-50Y-50        # Gcode to run after suspend, retract then get head out of way
before_resume_gcode                  G91_G1E1_G90                          # Gcode to run after temp is reached but before resume - do a prime
[switch]
suspend.enable = true                         # Enable this module
suspend.input_pin = 1.30^                     # Pin where pause button is connected
suspend.output_on_command = suspend           # Suspend command

resume.enable = true                          # Enable this module
resume.input_pin = 1.31^                      # Pin where resume button is connected
resume.output_on_command = resume             # Resume command

after_suspend_gcode = G91_G0E-5_G0Z10_G90_G0X-50Y-50        # Gcode to run after suspend, retract then get head out of way
before_resume_gcode = G91_G1E1_G90                          # Gcode to run after temp is reached but before resume - do a prime

Stopping Smoothie

There are several different ways to stop Smoothie during operation, each with different behaviors and use cases.

Understanding these methods is important for safe operation and troubleshooting.


Stop Methods Comparison

Command G-code Movement Heaters File playing Recoverable Documentation
abort M26 Stops SDCARD print immediately Not affected Aborts Position maintained, file must be restarted Player
suspend M600 Stops once queue is empty Turned off (if option enabled) Paused, can be resumed Yes, with resume or M601 Player
Kill button M112 Stops instantly (if button), waits for buffer (if host) Turned off Aborted No, position lost, home required supported-g-codes
Control-X - Stops instantly, works during streaming Turned off Aborted No, position lost, home required -

Detailed Method Descriptions

Abort Command (abort / M26)

Stops the execution of a file being played from SDCARD.

Behavior:

  • Completes the current G-code
  • Stops immediately after that
  • Discards the rest of the queued commands
  • Attempts to maintain the correct position after the abort
  • Heaters remain at their current state

Use Case: Quick stop of a print job while preserving position and keeping heaters on.

Recovery: Position is maintained, but the file must be restarted from the beginning.

Documentation: Player module


Suspend Command (suspend / M600)

Suspends the execution of a file being played from SDCARD or being streamed from a host.

Behavior:

  • Stops once the movement queue is empty
  • All state is saved
  • Heaters turned off by default (configurable)
  • Jogging and extruding are allowed during suspension
  • Can be resumed with resume or M601

Use Case: Mid-print filament change or filament out detection.

Host Support: Requires upstream support. Currently Pronterface and OctoPrint support it. Other hosts need to be manually paused.

Recovery: Yes, fully recoverable with position maintained.

Documentation: Player module


Kill Button / M112

Emergency stop that instantly halts all operations.

Behavior:

  • If kill button pressed: Stops instantly
  • If M112 issued from host: Has to wait for the receive buffer to have room
  • All heaters turned off
  • File playing aborted
  • Position is lost
  • System enters Halt state until M999 is sent

Use Case: Emergency situations requiring immediate stop.

Recovery: No, position is lost. Homing will be required.

Documentation: Supported G-codes, Kill Button

Warning: Using the kill button or M112 will cause position loss. You must home all axes before continuing normal operation.

Control-X

Sends a control character to stop Smoothie instantly.

Behavior:

  • Works at any time, even when streaming
  • Same effect as the kill button
  • All heaters turned off
  • File playing aborted
  • Position is lost
  • System enters Halt state until M999 or $X is sent

Use Case: Emergency stop from terminal/console when streaming G-code.

Recovery: No, position is lost. Homing will be required.


Halt State

When the kill button is pressed (or there is a temperature fault, M112 is issued, a limit switch is hit, or other error), the system enters the Halt state.

Halt State Behavior

Halt State Indicators:
  • Play LED flashes
  • Any command issued from host gets a !! response (with a few exceptions)
  • PSU may be turned off if a PSU Switch is defined

Clearing Halt State

The Halt state can be cleared by:

  1. Issuing M999 from the host
  2. Holding the flashing kill button for 2 seconds
  3. Using the LCD panel (if equipped)

Using Buttons and Sensors

Tip: All stop commands can be triggered by a button or a sensor if a Switch module is configured to do so. This allows for physical emergency stop buttons or automatic stopping based on sensor conditions.

Best Practices

For Normal Operation

  • Use suspend/resume (M600/M601) for planned interruptions like filament changes
  • Use abort when you need to stop quickly but keep heaters on

For Emergencies

  • Use the kill button or Control-X for immediate emergency stops
  • Remember that position will be lost and homing will be required

Recovery After Emergency Stop

  1. Clear the Halt state with M999
  2. Home all axes before attempting further movement
  3. Check that heaters are at safe temperatures before proceeding
  4. Verify machine state before resuming work

Further Reading

Suspend/resume single button

This configuration allows you to set a single button to both pause and resume the machine

switch.pause.enable                true                     # Enable this module
switch.pause.input_pin             1.30^                    # Pin where pause button is connected
switch.pause.output_on_command     suspend                  # Suspend command
switch.pause.output_off_command    resume                   # Resume command
switch.pause.input_pin_behavior    toggle                   # This pin toggles between it's on and off states each time it is pressed and released

after_suspend_gcode                  G91_G0E-5_G0Z10_G90_G0X-50Y-50        # Gcode to run after suspend, retract then get head out of way
before_resume_gcode                  G91_G1E1_G90                          # Gcode to run after temp is reached but before resume - do a prime
[switch]
pause.enable = true                           # Enable this module
pause.input_pin = 1.30^                       # Pin where pause button is connected
pause.output_on_command = suspend             # Suspend command
pause.output_off_command = resume             # Resume command
pause.input_pin_behavior = toggle             # This pin toggles between it's on and off states each time it is pressed and released

after_suspend_gcode = G91_G0E-5_G0Z10_G90_G0X-50Y-50        # Gcode to run after suspend, retract then get head out of way
before_resume_gcode = G91_G1E1_G90                          # Gcode to run after temp is reached but before resume - do a prime

Spindle control button

This configuration allows you to set a single button to start and stop your spindle.

switch.spindle.enable                true                     # Enable this module
switch.spindle.input_pin             1.30^                    # Pin where pause button is connected
switch.spindle.output_on_command     M3                       # Command to turn the spindle ON eg M3 S1000
switch.spindle.output_off_command    M5                       # Command to turn the spindle OFF
switch.spindle.input_pin_behavior    toggle                   # This pin toggles between it's on and off states each time it is pressed and released
[switch]
spindle.enable = true                         # Enable this module
spindle.input_pin = 1.30^                     # Pin where pause button is connected
spindle.output_on_command = M3                # Command to turn the spindle ON eg M3 S1000
spindle.output_off_command = M5               # Command to turn the spindle OFF
spindle.input_pin_behavior = toggle           # This pin toggles between it's on and off states each time it is pressed and released

Laser power supply

For the enable ( TTL ) pin on a CO2 laser PSU, for power control use the Laser module.

# Switch module for laser TTL control
switch.laser.enable                            true             # Enable this module
switch.laser.input_on_command                  M106             # Turn ON when M106 is sent
switch.laser.input_off_command                 M107             # Turn OFF when M107 is sent
switch.laser.output_pin                        1.31             # Pin to control, to be connected to the laser power supply's TTL input
[switch]
# Switch module for laser TTL control
laser.enable = true                           # Enable this module
laser.input_on_command = M106                 # Turn ON when M106 is sent
laser.input_off_command = M107                # Turn OFF when M107 is sent
laser.output_pin = 1.31                       # Pin to control, to be connected to the laser power supply's TTL input

Note this is now supported by the laser module itself, where the pin is automatically toggled, using the laser_module_ttl_pin configuration option.

However, if you are not using that functionality, this allows you to turn the laser power supply using G-codes.

Setting up a reset button

Smoothie has a reset button, and you can wire an external button to that ( see Pinout ).

However, maybe you have an existing Panel, which has a button on it, and you want to turn that into a reset button.

If that’s the case, you can setup a switch module to read whatever pin you wired that button to, and make it trigger the reset command whenever it is pressed, like this:

switch.reset.enable                true                     # Enable this module
switch.reset.input_pin             1.30^                    # Pin where reset button is connected
switch.reset.output_on_command     reset                    # Command to reset the board
[switch]
reset.enable = true                           # Enable this module
reset.input_pin = 1.30^                       # Pin where reset button is connected
reset.output_on_command = reset               # Command to reset the board

Homing a multi-motor axis.

Let’s say your machine has a Y or Z axis that has not one, but two or more stepper motors.

If each of those has a separate stepper motor driver, and a separate endstop at the end, you can do something neat: multi-stage homing for auto-levelling/axis alignment.

The way this is accomplished is fairly simple:

  • Set up switch modules to control the enable pin of each motor
  • Enable and home each axis in turn

Here is how you would set up switch modules for two stepper motor drivers:

# Switch module for first Z stepper motor driver
switch.z-1.enable                            true             # Enable this module
switch.z-1.input_on_command                  M1001            # Turn ON
switch.z-1.input_off_command                 M1011            # Turn OFF
switch.z-1.output_pin                        1.31             # Pin to control enable pin of driver

# Switch module for second Z stepper motor driver
switch.z-2.enable                            true             # Enable this module
switch.z-2.input_on_command                  M1002            # Turn ON
switch.z-2.input_off_command                 M1012            # Turn OFF
switch.z-2.output_pin                        1.30             # Pin to control enable pin of driver
[switch]
# Switch module for first Z stepper motor driver
z-1.enable = true                             # Enable this module
z-1.input_on_command = M1001                  # Turn ON
z-1.input_off_command = M1011                 # Turn OFF
z-1.output_pin = 1.31                         # Pin to control enable pin of driver

# Switch module for second Z stepper motor driver
z-2.enable = true                             # Enable this module
z-2.input_on_command = M1002                  # Turn ON
z-2.input_off_command = M1012                 # Turn OFF
z-2.output_pin = 1.30                         # Pin to control enable pin of driver

For wiring, simply wire pin 1.31 to the enable pin of the first stepper driver and pin 1.30 to the enable pin of the second stepper driver.

Wiring the same way you’d wire step and direction signals in the [external drivers documentation](/general-appendixes#external-drivers). ( note that if you will be using Open-Drain wiring, you need to add “o!” to your pin numbers, same as for step and dir ).

You also need to wire the endstops so that a trigger is detected when either is triggered. This means if your endstops are wired as NC, you wire them in series, and if they are wiride as NO, you wire them in parralel.

And of course, both step and dir pins for the two stepper drivers must be wired in parralel to the same pins on the Smoothieboard.

Finally, when homing, you can’t simply issue G28, you have to issue a series of commands, which you can put at the beginning of your gcode files, or in your on_boot.gcode file ( which will be executed at boot time ).

Here is an example:

M1001        ; Activate both stepper drivers
M1002        ; Same
G1 Z10       ; Go up to make sure no endstop is hit
G28 Z0       ; Home the Z axis ( two motors together ) until one of the two endstops is hit
M1012        ; Desactivate the second stepper driver so we can home only the first one
G28 Z0       ; Home the first stepper motor/driver alone. First Z is now level
M1002        ; Re-activate second stepper driver so we can home only the second one
M1011        ; Desactivate the first stepper driver
G28 Z0       ; Home the second stepper motor driver. Second Z is now level.
M1001        ; Re-activate the first stepper driver, both stepper drivers are now active
             ; Z is now level relative to it's two endstops, and can be used normally as if it were a single axis.

Note if both your endstops are wired in parralel, you’ll need to retract off one endstop before you can use the next one. As long as you retract by the same length for each endstop you’ll be fine.

Alternative wiring

Note that with the first wiring, we rely on the enable pin to make sure that the drivers ignore step-dir instructions when we want to home the other axis.

However on some drivers, this will also turn off power to the motors

This is a wiki! If you'd like to improve this page, you can edit it on GitHub.