Joystick Module

Joystick Module

What is Joystick?

Joystick is a module for SmoothieBoard which adds the ability to use joysticks with your machine.

It is much like the Switch module, but can read from things which output an analog voltage (things like joysticks, sliders, knobs, force sensitive resistors, etc).

Some possible uses for the Joystick module:

  • Moving your machine to set up the part origin (see jogging)
  • Retracting an extruder on a 3D-printer
  • Focusing a laser cutter
  • Manually overriding your machine’s speed with a knob/slider (see feed rate override)
  • Controlling spindle speed with a knob on a mill

Getting Started

Work in Progress: Note this page is a work in progress and the joystick functionality is not yet released in smoothieware. To test it you need to use pull request Smoothieware#1122, and instructions on how to test a Pull request are here Checking out pull requests

Hardware Requirements

Joystick Sparkfun Joystick Sparkfun Slider

To begin, you will need a device that you want to read. Some example devices are shown here, but really any variable resistor (potentiometer) or device that outputs 0-3.3 V should work.

For more information on how potentiometers work, see SparkFun’s tutorial.

For the rest of the document, the examples will be for a 2-axis joystick like in the right-most picture. This joystick has two separate potentiometers for each axis, and has springs inside to return the knob to the center when released (think PlayStation controller knob).

Connections

If you have a potentiometer, you will need to connect one side to 3.3 V, the other side to ground, and the wiper to a pin on the SmoothieBoard which supports analog reading (see table below).

Potentiometer Schematic

The above image shows a basic schematic of a potentiometer.

Pins 1 and 3 are the ends of the potentiometer, and Pin 2 is the wiper.

Vin should be 3.3 V for the SmoothieBoard, and Pin 2 will be connected to a compatible pin on the SmoothieBoard (see table below).

Caution: Use caution when connecting a potentiometer to your SmoothieBoard. If Vin is a higher voltage than the SmoothieBoard's pins can handle (-0.5 to 5.1 V for > 10 ms), you might ruin your board. Use Vin = 3.3 V unless you know what you are doing.

The analog pins on the Smoothieboard which can be connected to a wiper (Pin 2 in above schematic) are shown in the table below:

Analog Pin Smoothie Assignment Comments
0.2 uart0 txd Not recommended (used for ISP programming of the bootloader and for debugging)
0.3 uart0 rxd Not recommended (used for ISP programming of the bootloader and for debugging)
0.23 hotend.thermistor_pin Not recommended (used for thermistors and has built-in 4.7 kΩ pull-up)
0.24 bed.thermistor_pin Not recommended (used for thermistors and has built-in 4.7 kΩ pull-up)
0.25 thermistor2 Not recommended (used for thermistors and has built-in 4.7 kΩ pull-up)
0.26 thermistor3 Not recommended (used for thermistors and has built-in 4.7 kΩ pull-up)
1.30 spare Recommended pin
1.31 spare Recommended pin

For a joystick, you will need to connect each wiper (the left/right and up/down) to different analog pins (e.g. 1.30 and 1.31).

Analog Pin Assignment Comments
ADC1_1 (PF11) Thermistor T1 Not recommended (used for hotend thermistor)
ADC1_2 (PF12) Thermistor T2 Not recommended (used for bed thermistor)
ADC1_3 (PB0) Thermistor T3 Available if not using second hotend
ADC1_4 (PC2) Expansion (GH) Recommended - available on Gadgeteer header GH
ADC1_5 (PC3) Expansion (GH) Recommended - available on Gadgeteer header GH

For a joystick, you will need to connect each wiper (the left/right and up/down) to different analog pins (e.g. ADC1_4 and ADC1_5 on the Gadgeteer GH header).

See Pinout for a diagram of the Smoothieboard with the pins labeled.

Configuration

Mapping Voltage to Position

The configuration file, at its most basic level, must tell the SmoothieBoard how to convert the 0 to 3.3 V that it reads into a more useful range of numbers. The range that the Joystick module uses is -1 to 1. It is also possible to use a 0 to 1 range if negative values don’t make sense for your application.

The way the Joystick module performs this conversion is to first measure the voltage coming in. The module then subtracts off an offset, called . The module then scales the voltage reading so that the voltage becomes 0, and the voltage becomes 1 or -1 (depends on if is greater or less than ). Any values which end up outside the -1 to 1 range are fixed to be at +/- 1.

Joystick Mapping Example Mapping from joystick position to output with = 1.5 V and = 0 V

Auto-Zeroing

The joystick module has an optional feature which automatically determines .

For a short period of time () after the SmoothieBoard is powered on / reset, the joystick module averages the joystick readings. The average value at the end of the startup time is used as the .

This feature is useful for joysticks, where the is somewhat unknown (it is usually around 1.65 V but different devices have slightly different center values).

It would not make sense to enable for sliders or knobs, since the knob doesn’t have a known/default starting position.

Important: Be careful not to move the joystick during the startup time (set by ), otherwise the will be wrong and the joystick will have undesirable behavior.

All Configuration Options

V1 Setting V2 Setting Description
Not available in v2 If true, create and enable a new Joystick module with the specified name. The joystick module allows you to read analog input from joystick devices and use them to control machine movement via the Jogger module or other control systems. Each joystick instance requires a unique name.
Not available in v2 Specifies which SmoothieBoard pin should be used to read the analog joystick value. The pin must be one of the analog-capable pins (typically 0.2, 0.3, 0.23-0.26, 1.30, 1.31). Connect the joystick wiper (output) to this pin, with the potentiometer ends connected to 3.3V and ground.
Not available in v2 Sets how many times per second to update the joystick reading. Higher values provide more responsive control but use more CPU time. Typical values are 10-100 Hz. Default is 10 Hz if not specified.
Not available in v2 Sets what voltage will map to zero output. This is typically the center position of the joystick, usually around 1.65V (half of 3.3V). The joystick module subtracts this offset from the measured voltage before scaling. Can be automatically determined using the auto_zero feature.
Not available in v2 Sets what voltage will map to +1 or -1 output. If endpoint is greater than zero_offset, it specifies what voltage maps to +1. If endpoint is less than zero_offset, it specifies what voltage maps to -1. This defines the full range of motion for the joystick. Typical value is 3.3V (or close to it, like 3.2V) for maximum range.
Not available in v2 If true, enables the auto-zeroing feature, which automatically determines the zero_offset value at startup by averaging readings during the startup_time period. This is useful for joysticks where the center position voltage may vary slightly between devices. Do not move the joystick during startup when this is enabled.
Not available in v2 Sets how long (in milliseconds) after SmoothieBoard resets to obtain readings to average for the auto-zero offset calculation. Must be at least 1000 / refresh_rate to ensure sufficient samples, but should not be too long to avoid the joystick being moved during measurement. Typical value is 1000ms (1 second).
Not available in v2 Sets the default value of the joystick output during the startup_time period when auto-zeroing is active. This value should be between -1 and 1, and is typically 0 to indicate no movement during calibration. This prevents unwanted motion while the auto-zero feature is determining the center position.

Migration from V1 to V2

When migrating your joystick configuration from Smoothieware v1 to v2, use this checklist:

V1 Configuration Format:

joystick.horizontal.enable                     true
joystick.horizontal.pin                        1.30
joystick.horizontal.endpoint                   3.20
joystick.horizontal.auto_zero                  true
joystick.horizontal.startup_time               1000
joystick.horizontal.refresh_rate               100
joystick.horizontal.start_value                0

V2 Configuration Format:

[joystick.horizontal]
enable = true
pin = ADC1_4              # See pin mapping table above
endpoint = 3.20
auto_zero = true
startup_time = 1000
refresh_rate = 100
start_value = 0

Migration Checklist:

  • Convert flat config format to INI sections with [joystick.name] headers
  • Change key value format to key = value format
  • Update pin assignments from LPC1769 format (e.g. 1.30) to STM32H745 format (e.g. ADC1_4)
  • Verify analog pin availability (check thermistor usage on your board)
  • Update physical wiring to match new pin assignments (see pin mapping table)
  • Adjust voltage calibration values if needed (see note below on ADC differences)
  • Test auto-zeroing behavior after migration (startup timing may differ)
  • Update any related jogger or feed override configurations to INI format

Important Hardware Differences:

ADC Behavior Differences: The STM32H745 (v2) has different analog-to-digital converter characteristics compared to the LPC1769 (v1):
  • Resolution: STM32H745 supports 16-bit ADC vs LPC1769's 12-bit, providing finer position resolution
  • Sampling speed: STM32H745 has faster ADC conversion times, may affect noise filtering
  • Reference voltage: Both use 3.3V reference, but internal voltage regulators may differ slightly
  • Input impedance: STM32H745 has higher input impedance, reducing load on potentiometer
  • Calibration: You may need to recalibrate endpoint and zero_offset values after migration due to these hardware differences
It is recommended to re-test and re-calibrate your joystick settings after migrating from v1 to v2.

Usage

Jogging

To use the joystick for jogging, configure two different modules with two different names. For example, one module will be called “horizontal” and the other “vertical”. An example config file for the joystick is shown below:

# joystick-2D.config
joystick.horizontal.enable                     true              # enable the horizontal axis joystick
joystick.horizontal.pin                        1.30              # use pin 1.30 connected to potentiometer wiper
joystick.horizontal.endpoint                   3.20              # 3.2 V maps to +1 in joystick reading
joystick.horizontal.auto_zero                  true              # automatically determine the zero point
joystick.horizontal.startup_time               1000              # take readings for 1 second at startup to get auto-zero point
joystick.horizontal.refresh_rate               100               # update the joystick position 100 times per second
joystick.horizontal.start_value                0                 # when auto-zeroing, force joystick output to be 0

joystick.vertical.enable                       true              # enable the vertical axis joystick
joystick.vertical.pin                          1.31
joystick.vertical.endpoint                     3.20
joystick.vertical.auto_zero                    true
joystick.vertical.startup_time                 1000
joystick.vertical.refresh_rate                 100
joystick.vertical.start_value                  0

With the joystick configuration done, you will simply need to configure the Jogger. The only pertinent config for the joystick/jogger connection is setting the data_source configs for the Jogger (like ). An example of those options is shown below:

# Jogger Configuration
jogger.enable                                  true
jogger.data_source_alpha                       horizontal
jogger.data_source_beta                        vertical
Note: The Joystick module has not yet been ported to Smoothieware v2. This functionality may be added in a future release. Check the SmoothieV2 repository for updates.

When available, the v2 configuration would likely follow this format:

# joystick-2D.ini
[joystick.horizontal]
enable = true              # enable the horizontal axis joystick
pin = 1.30                 # use pin 1.30 connected to potentiometer wiper
endpoint = 3.20            # 3.2 V maps to +1 in joystick reading
auto_zero = true           # automatically determine the zero point
startup_time = 1000        # take readings for 1 second at startup to get auto-zero point
refresh_rate = 100         # update the joystick position 100 times per second
start_value = 0            # when auto-zeroing, force joystick output to be 0

[joystick.vertical]
enable = true
pin = 1.31
endpoint = 3.20
auto_zero = true
startup_time = 1000
refresh_rate = 100
start_value = 0

# Jogger Configuration
[jogger]
enable = true
data_source_alpha = horizontal
data_source_beta = vertical

These options tell the jogger the names of the joystick modules to read when jogging.

You're all set! For more jogging configuration options, see Jogger.

Feed Rate Override

Note: No feed rate override has been implemented in smoothie yet. The following example is purely hypothetical.

To use the joystick to override your machine’s feed rate (to go faster or slower while cutting/printing), set up a single joystick axis. An example snippet of the configuration file is shown below:

# feedrate-override.config
joystick.fro.enable                            true              # enable the feed-rate override joystick
joystick.fro.pin                               1.30              # use pin 1.30 connected to potentiometer wiper
joystick.fro.endpoint                          3.20              # 3.2 V maps to +1 in joystick reading
joystick.fro.zero_offset                       0                 # 0 V maps to 0 in joystick reading
joystick.fro.refresh_rate                      100               # update the joystick position 100 times per second

With the joystick properly configured, you will simply need to tell the Feed Rate Override module (doesn’t exist yet) which joystick to read:

# Feed Rate Override Configuration
feedoverride.data_source                       fro
You're all set! For more feed-rate override configuration options, see Feed Rate Override.
Note: The Joystick module and Feed Rate Override functionality have not yet been ported to Smoothieware v2.

When available, the v2 configuration would likely follow this format:

# feedrate-override.ini
[joystick.fro]
enable = true              # enable the feed-rate override joystick
pin = 1.30                 # use pin 1.30 connected to potentiometer wiper
endpoint = 3.20            # 3.2 V maps to +1 in joystick reading
zero_offset = 0            # 0 V maps to 0 in joystick reading
refresh_rate = 100         # update the joystick position 100 times per second

# Feed Rate Override Configuration
[feedoverride]
data_source = fro

Developer Documentation

For information on how to write your own module which uses a joystick, see the joystick developer documentation.

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