How magnetic switches work
This page explains, from the basics, how a magnetic-switch keyboard measures its keys, what the numbers in its console output mean, and how MAGDA turns them into key presses: the travel curve, actuation and hysteresis, and noise. It assumes entry-level electronics: voltage, a supply rail, a chip's pins. For using the keyboard see Magnetic Switches; for designing one, the maker guide.
How a magnetic-switch keyboard works
Each switch carries a small permanent magnet in its stem. A linear Hall-effect sensor sits on the PCB directly under each switch and outputs a voltage proportional to the magnetic field it sees. As the key travels down, the magnet approaches the sensor and the output voltage changes continuously. The keyboard therefore measures how far each key is pressed, not just whether it is pressed.
The signal chain is:
magnet → Hall sensor → analog multiplexer → MCU ADC → MAGDA → QMK matrix
MAGDA turns the per-key readings into ordinary key presses. Calibration learns each key's released and fully pressed levels, and actuation decides when a key counts as pressed: at a fixed point, or with rapid trigger.
MAGDA makes one assumption about the hardware: each key yields one reading that changes monotonically with key travel. The direction of change and the scale do not matter; both are learned per key.
Readings: from a magnet to a number
Everything in MAGDA is measured in raw counts. This section explains what they are, starting from the basics. If you already know how an ADC works, skip to Counts on the Praxis HE.
Voltage out of the sensor
A linear Hall sensor is a small chip with three pins: supply, ground and output. Its output pin carries a voltage that follows the magnetic field through the chip:
- with no field, the output sits at half the supply: with a 3.3 V supply, about 1.65 V;
- a field in one direction raises the output, a field in the other direction lowers it, by an amount proportional to the field's strength (the sensor's sensitivity, in millivolts per gauss);
- the output never goes below 0 V or above the supply.
When the key is pressed, the magnet in its stem comes closer, the field at the sensor gets stronger, and the output voltage moves away from the middle. The firmware's job is to read that voltage.
The ADC turns a voltage into a number
A microcontroller cannot use a voltage directly; it works with numbers. Its ADC (analog-to-digital converter) measures a voltage on one of its pins and returns a whole number:
- The ADC compares the input with a reference voltage (on the Praxis HE, the 3.3 V supply itself). 0 V gives 0; the reference gives the largest number.
- Its resolution sets how many different numbers it can return. A 12-bit ADC returns 2¹² = 4096 different values, 0 to 4095.
- One step of that number, one count, is therefore the reference divided by 4096: 3.3 V ÷ 4096 ≈ 0.81 mV. The ADC cannot see smaller changes.
| Voltage at the pin | ADC result (counts) |
|---|---|
| 0 V | 0 |
| 0.81 mV | 1 |
| 1.65 V (half the reference) | about 2048 |
| 3.3 V (the reference) | 4095 |
So a reading of 2230 means "2230 × 0.81 mV ≈ 1.80 V at the pin". That number, as it comes from the ADC, is a raw count or raw reading: nothing has been done to it yet.
A measurement is not instant: the ADC first connects the pin to a small internal capacitor for a sample time (so the capacitor charges to the pin's voltage), then converts. Longer sample times give the voltage more time to settle and read more accurately, but take longer; this is the MAG_ADC_SAMPLE_TIME setting (maker guide, step 7).
Why the reference matters
If the sensor's supply and the ADC's reference are the same voltage, a change in that voltage moves both together: the sensor's output is a fixed fraction of its supply, and the ADC measures that fraction. The count stays the same even if the 3.3 V rail sags a little. This is called ratiometric measurement, and it is why the maker guide asks for sensors and ADC reference on one rail. It is also why the zero-field reading is "half of full scale" (about 2048 counts), whatever the exact supply voltage is.
Many keys, one ADC
An MCU has a handful of ADC inputs, not one per key. An analog multiplexer is a switch with many inputs and one output: a few digital select lines choose which input is connected to the output. With one multiplexer per row, the firmware sets the select lines to a column, waits a moment for the output to settle (MAG_SETTLE_US), and reads all rows of that column with the ADC; then the next column. One pass over all columns is one scan, and its result, a raw count for every key, is one frame.
Counts on the Praxis HE
Typical numbers for one key (HAL4904 sensor, 1.4 mV per gauss, so about 1.7 counts per gauss):
| Situation | Raw count | Voltage | What it means |
|---|---|---|---|
| No magnet (bare sensor) | ≈ 2048 | ≈ 1.65 V | zero field: the middle of the range |
| Key at rest | ≈ 2230 | ≈ 1.80 V | the magnet already biases the sensor a little |
| Key fully pressed | ≈ 3050 | ≈ 2.46 V | the magnet close to the sensor |
| Unused multiplexer input (grounded) | 0–2 | ≈ 0 V | a check that the path works |
- Span: the difference between fully pressed and rest, here about 820 counts. The whole keystroke lives in those 820 steps. Each key has its own rest and bottom, which is why every key is calibrated separately.
- Noise: even with nobody touching the keyboard, a reading jumps around a little from scan to scan. On the Praxis HE a key's reading at rest varies by about 26 counts between its highest and lowest value (peak-to-peak), about 21 mV. MAGDA smooths the readings with a filter, which cuts that to roughly 10–13 counts.
- Counts are not millimetres. The field grows much faster as the magnet gets close, so most of the 820 counts are used in the last part of the keystroke; the first 10 % of the key's movement may be only 20–30 counts. MAGDA converts counts to physical travel with a model (maker guide, step 3).
Raw counts, filtered counts and travel
The firmware works with three kinds of number; the console output uses all three:
| Name | Range | Meaning | Where you see it |
|---|---|---|---|
| raw count | 0–4095 | the ADC result, untouched | raw lines of MAG_DUMP; calibration messages; rest and bottom in MAG_CAL_DUMP |
| filtered count | 0–4095 | the raw count smoothed over the last few scans | used internally for calibration and travel |
| travel | 0–1023 | how far the key is pressed: 0 at rest, 1023 fully pressed (MAG_TRAVEL_MAX) |
trv lines of MAG_DUMP; actuation and rapid-trigger settings (shown to users as percent) |
When the documentation says "a margin of 10 counts", it means raw (or filtered) counts: 10 × 0.81 mV ≈ 8 mV at the sensor.
From counts to travel: the travel curve
Why counts are not distance
A magnet's field grows faster and faster as the magnet approaches the sensor. So when a key goes down at a steady speed, its reading creeps at first and then shoots up near the bottom. Measured on a Praxis HE key (the top-left key, pressed down with a caliper; full data in maker guide, step 11):
| Key pressed down by | Reading (counts) | Change from rest |
|---|---|---|
| 0 mm (rest) | 2282 | 0 |
| 1.0 mm | 2318 | +36 |
| 2.0 mm | 2431 | +150 |
| 3.0 mm | 2615 | +334 |
| 3.5 mm | 2836 | +555 |
| 4.0 mm (bottom) | 3021 | +739 |
The first half of the keystroke moves the reading by only about a fifth of its span; the last millimetre moves it by more than half. If the firmware simply used "percent of the reading span" as "percent of the keypress", a 10 % actuation point would sit around mid-travel and 90 % would need an almost full press. This is what happened on the Praxis HE before MAGDA had a travel curve.
The model MAGDA uses
A travel curve converts a reading into physical travel. For a sensor sitting under the magnet, on its axis, as on the Praxis HE, MAGDA uses a power law: the field strength falls as the distance to the power n, so the distance can be worked back from the field. The field is the reading minus the sensor's zero-field output (its reading with no magnet at all, half the range: 2048 counts). For each key, MAGDA places the current reading between that key's rest and bottom on this distance scale, and reports the result as travel, 0 to 1023.
Only two numbers describe the curve, and both are the same for every key on a board:
- the zero field (
MAG_ZERO_FIELD), 2048 counts for a sensor that runs on the same rail as the ADC reference; - the exponent n (
MAG_FIELD_EXPONENT): 3 for an ideal magnet far from the sensor; on the Praxis HE, measured with the caliper sweep above, n = 1 fits best, and that is its factory value. It can be changed from the VIA menu (Field exponent, shown × 10).
Everything else (how strong each magnet is, each sensor's sensitivity, how long the keystroke is) cancels out, because every key is scaled by its own calibrated rest and bottom.
For a typical Praxis HE key (rest 2230, bottom 3050, n = 1), the model gives:
| Reading, % of the span | 5 | 10 | 20 | 30 | 50 | 70 | 90 |
|---|---|---|---|---|---|---|---|
| Travel, % of the keypress | 22 | 38 | 58 | 70 | 85 | 93 | 98 |
So the first tenth of the counts already covers more than a third of the keypress.
Limits worth knowing:
- The percentages are approximate. The exponent was fitted on one key; a percent is a fraction of the physical keypress only as far as the model holds.
- A key whose rest reading is within 16 counts of the zero field does not fit the model, because the result would depend on the exact zero-field value; that key uses the reading span directly. On the Praxis HE one key (R0C1) does.
The formula and how the curve is implemented: Architecture, section 3.2. Choosing and fitting a curve for a new board: maker guide, steps 3 and 11.
Actuation point and hysteresis
The actuation point is the travel at which a key counts as pressed, the same for all keys. On the Praxis HE it is 60 % by default (614 of 1023), adjustable in 5 % steps from 10 to 90 %.
A single threshold has a problem. Hold a key right at the actuation point and its travel wanders a little above and below the line, because the reading always carries some noise (next section). With one line, the key would press, release, press, release, as fast as the keyboard scans: chatter.
MAGDA therefore uses two lines. A key presses when its travel rises to the actuation point, and releases only when it falls to a lower release point, 64 travel units (about 6 % of the keypress) below it (MAG_HYSTERESIS_DEFAULT). This gap is the hysteresis. Between the two lines, the key keeps whatever state it had:
travel
100 % ┬
│
60 % ┼───────── going down: press here
│ between the lines: no change
54 % ┼───────── coming up: release here
│
0 % ┴
The hysteresis does the job that debouncing does on a mechanical keyboard, so a MAGDA board runs QMK with debounce set to 0.
How wide the gap is in counts depends on where it sits on the travel curve. Computed from the model for the typical Praxis HE key above:
| Actuation point | Press at (counts above rest) | Release at | Gap |
|---|---|---|---|
| 10 % | 16 | 6 | 10 |
| 20 % | 36 | 23 | 13 |
| 30 % | 59 | 44 | 15 |
| 60 % | 176 | 143 | 33 |
| 90 % | 509 | 396 | 112 |
Near the top of the keystroke, the whole gap is only about as wide as the filtered noise (10–13 counts, next section). That is why the lowest actuation points are the most sensitive to noise, and why they can feel twitchy. On the Praxis HE, these defaults passed the noise tests at 10, 15 and 20 % with an earlier exponent (3.5), which gives wider gaps at low levels; with the factory exponent 1 (the table above), those levels have not been tested again yet.
Rapid trigger uses the same release point as its full reset, but presses and releases in between by its own distance: see Rapid trigger.
Noise
Where it comes from
With nobody touching the keyboard, a key's reading still changes a little from scan to scan. Part of that comes from the sensor itself; the rest comes from the board: ripple on the supply, the ground, analog wiring running near switching or data lines, and the ADC.
Two ways of stating it:
- RMS ("root mean square"): the typical size of the wobble. The Praxis HE's sensor, the HAL4904, is specified at about 1.7 counts RMS; the board measured 5.8 counts RMS, about three times more. The grounded multiplexer inputs read a steady 0–2, so the extra noise enters on the sensor side, not in the multiplexers or the ADC.
- Peak-to-peak: the full spread between the highest and lowest reading over a while, several times the RMS figure. On the Praxis HE, at rest: 26 counts for a typical key, 32 or less for nine keys in ten, 46 at most.
Magnets and Hall sensors are very stable, so in practice noise is decided by the PCB design; the maker guide explains how to keep it low.
The filter
MAGDA smooths every reading with a simple filter: at each scan, the filtered value moves a quarter of the way toward the new raw reading (MAG_FILTER_SHIFT 2). Random ups and downs mostly cancel out, and the peak-to-peak noise drops from about 26 to 10–13 counts. The price is a small delay: the filter follows a real movement within a few scans, about 2 ms at the Praxis HE's roughly 2000 scans per second.
Noise seen as travel
The travel curve is steepest at the top of the keystroke, where a few counts are a large share of the travel. So even filtered noise shows up in the trv lines of MAG_DUMP with nobody touching the keyboard: on the Praxis HE, some keys at rest occasionally show 10 % of travel or more. This is harmless as long as the actuation point is well above it, and it is another way of seeing why the lowest actuation points are the delicate ones.
Slow changes: drift
Besides fast noise, a key's rest level can shift slowly, for example with temperature. MAGDA measures every key's rest level again at each power-up, and while the keyboard runs it follows slow changes, but only while the key is released and near rest, and only very slowly (a time constant of about half a minute). A finger resting lightly on a key changes the reading for seconds, not minutes, so it is not mistaken for drift. Because rest is measured at power-up, do not hold keys while plugging the keyboard in.
Noise during calibration
While calibration measures the keys at rest, it checks that each key's reading stays within 64 counts (about twice the Praxis HE's peak-to-peak noise) over the frames it averages. A touched key moves further than that, and its measurement starts over; this is why calibration asks you to keep your hands off during that part.
What this means in use
- If keys register by themselves or flicker, the actuation point is too close to the noise: raise it.
- The smallest useful rapid-trigger distance also depends on the noise; on the Praxis HE, tests stayed clean down to 1 %.
- For board makers: measuring noise and tuning the related settings is maker guide, steps 7 and 10.