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:
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).
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).
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).
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 |
|---|---|---|
| uart0 txd | Not recommended (used for ISP programming of the bootloader and for debugging) | |
| uart0 rxd | Not recommended (used for ISP programming of the bootloader and for debugging) | |
| hotend.thermistor_pin | Not recommended (used for thermistors and has built-in 4.7 kΩ pull-up) | |
| bed.thermistor_pin | Not recommended (used for thermistors and has built-in 4.7 kΩ pull-up) | |
| thermistor2 | Not recommended (used for thermistors and has built-in 4.7 kΩ pull-up) | |
| thermistor3 | Not recommended (used for thermistors and has built-in 4.7 kΩ pull-up) | |
| spare | Recommended pin | |
| 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.
| Analog Pin | Assignment | Comments |
|---|---|---|
| Thermistor T1 | Not recommended (used for hotend thermistor) | |
| Thermistor T2 | Not recommended (used for bed thermistor) | |
| Thermistor T3 | Available if not using second hotend | |
| Expansion (GH) | Recommended - available on Gadgeteer header GH | |
| 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.
See Pinout for a diagram of the Smoothieboard with the pins labeled.
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 joystick module has an optional feature which automatically determines
For a short period of time (
This feature is useful for joysticks, where the
It would not make sense to enable for sliders or knobs, since the knob doesn’t have a known/default starting position.
| 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 |
|
| 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. |
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:
[joystick.name] headerskey value format to key = value format1.30) to STM32H745 format (e.g. ADC1_4)Important Hardware Differences:
endpoint and zero_offset values after migration due to these hardware differencesTo 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
# Jogger Configuration
jogger.enable true
jogger.data_source_alpha horizontal
jogger.data_source_beta vertical
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.
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
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
For information on how to write your own module which uses a joystick, see the joystick developer documentation.