Joysticks
1. You need to use a debug probe to find your parameters now.
2. Only Nrf is supported now.
TODO:
-
a more intuitive way to configure the joystick via
rmk-gui
- more functions besides mouse
toml
configuration
[[input_device.joystick]]
name = "default"
pin_x = "P0_31"
pin_y = "P0_29"
pin_z = "_"
transform = [[80, 0], [0, 80]]
bias = [29130, 29365]
resolution = 6
# func = "mouse | n-direction key" # TODO: only mouse is supported now
Parameters:
name
: the unique name of the joystick. If you have multiple joysticks, you should give them different namespin_x
: the pin of the x-axispin_y
: the pin of the y-axispin_z
: the pin of the z-axistransform
: the transformation matrix of the joystickbias
: the bias of each axisresolution
: the resolution of each axis
Axis:
The
_
stands for the axis is not existed.
_
is only allowed for:
- both y and z axis
- only z axis.
e.g.
pin_x = "_"
pin_y = "P0_29"
pin_z = "P0_30"
is not allowed
How it works
the transform might work not so intuitively,
please read the document below for more information.
-
The device read axes
-
Add
bias
on each axis to make them into0
when the joystick is released because the number returned by the ADC device isu16
. -
About the
transform
- new
x-axis
's value = (axis_x
+ bias[0]) / transform[0][0] + (axis_y
+ bias[1]) / transform[0][1] + (axis_z
+ bias[2]) / transform[0][2] - new
y-axis
's value = (axis_x
+ bias[0]) / transform[1][0] + (axis_y
+ bias[1]) / transform[1][1] + (axis_z
+ bias[2]) / transform[1][2] - new
z-axis
's value = (axis_x
+ bias[0]) / transform[2][0] + (axis_y
+ bias[1]) / transform[2][1] + (axis_z
+ bias[2]) / transform[2][2]
If
transform[new axis][old axis]
is0
, the old axis value will be ignored.For most situation the value boundary read by the ADC device is far larger than
-256~255
which is the range of the mouse report, that is why thetransform
is designed to be the divisor. - new
-
Each axis will be changed into the maximum integer multiples of
resolution
smaller than its original value.Because the values read by the ADC device may have noises.
How to find configuration for your circuit quickly
-
Firstly, set the
bias
to0
,resolution
to1
andtransform
to[[1, 0, 0], [0, 1, 0], [0, 0, 1]]
(the identity 2-d array's dimension depends on how many axes the joystick has). -
Find the best
bias
,Using the debug probe, in the debug information, there is the output
JoystickProcessor::generate_report: record = [axis_x, axis_y, axis_z]
Observe the value, and you can get thebias
which make each axis as close to0
as possible. -
Try to use the joystick, if you notice the mouse moves too fast, you can adjust the
transform
larger till you fond. -
If your mouse is jitter, you should adjust the
resolution
larger till you fond.
rust
configuration
Because the joystick
and battery
use the same ADC peripheral, they actually use the same NrfAdc
input_device
.
If the light_sleep
is not None
, the NrfAdc
will enter light sleep mode when no event is generated after 1200ms, and the polling interval will be reduced to the value assigned.
#![allow(unused)] fn main() { let saadc_config = saadc::Config::default(); let adc = saadc::SAADC::new(p.SAADC, Irqs, saadc_config, [ saadc::ChannelConfig::SingleEnded(saadc::VddhDiv5Input.degrade_saadc()), saadc::ChannelConfig::SingleEnded(p.P0_31.degrade_saadc()), saadc::ChannelConfig::SingleEnded(p.P0_29.degrade_saadc()) ], ); saadc.calibrate().await; let mut adc_dev = NrfAdc::new(adc, [AnalogEventType::Battery, AnalogEventType::Joystick(2)], 20 /* polling interval */, Some(350)/* light sleep interval */); let mut batt_proc = BatteryProcessor::new(1, 5, &keymap); let mut joy_proc = JoystickProcessor::new([[80, 0], [0, 80]], [29130, 29365], 6, &keymap); ... run_devices! ( (matrix, adc_dev) => EVENT_CHANNEL, ), run_processor_chain! { EVENT_CHANNEL => [joy_proc, batt_proc], } ... }