Crystal Focus X — Tangible Font Selection & Blade Detection Guide
This guide explains how the Tangible font selection system works on the Crystal Focus X, how it enables automatic font switching and blade detection via resistors, and the current state of Blade ID detection.
Table of Contents
- What Is Tangible?
- Hardware Setup
- How Voltage Maps to Slots
- Configuration — specials.txt
- Attribute Characters
- Font Switching vs. Blade Detection
- Practical Examples
1. What Is Tangible?
Tangible is a resistor-based font and blade detection system. By placing different resistors (or a resistor ladder) inside a blade connector, pommel piece, or chassis module, the CFX reads an analog voltage when the component is inserted. Based on that voltage, it automatically selects a sound font and determines whether the saber is allowed to ignite.
This enables:
- Automatic font switching when swapping blades or pommels with different resistors
- Blade-in / blade-out detection — the saber knows when a blade is physically present
- No-start prevention — the saber refuses to ignite when no blade is inserted
- Up to 16 different configurations from a single analog pin
2. Hardware Setup
The Tangible Pin
- Pin:
TANGIBLE_FONT_PIN= PIN_A1 (analog input) - ADC: 12-bit resolution (0–4095 counts = 0V–3.3V)
- Reference: 3.3V (
AR_DEFAULT)
At boot, the pin is briefly set as OUTPUT LOW to discharge any residual voltage, then switched to analog input mode for reading.
How the Resistor Works
A resistor in the blade connector forms a voltage divider with the board's internal circuitry. Different resistor values produce different voltages on PIN_A1, which the firmware reads to determine which slot (0–15) is active.
- No resistor / open circuit: The pin reads a specific default voltage (typically high or low depending on the board's pull configuration)
- Different resistor values: Each produces a distinct voltage, mapping to a different slot
Important: Ledstrip Power Dependency
Practical note: the blade or accessory can influence the tangible reading as soon as it is electrically connected. In practice, this means the saber needs the strip connection to be in its normal powered state before the tangible system can read the slot reliably.
3. How Voltage Maps to Slots
The tangible system reads the resistor value as a voltage and places it into one of 16 slots. Each slot represents one possible tangible position or accessory state.
The table below shows how the voltage range is split across the 16 slots, from the lowest reading to the highest.
| Slot | ADC Range | Approx Voltage |
|---|---|---|
| 0 | 0–255 | 0V – 0.206V |
| 1 | 256–511 | 0.206V – 0.412V |
| 2 | 512–767 | 0.412V – 0.618V |
| 3 | 768–1023 | 0.618V – 0.824V |
| 4 | 1024–1279 | 0.824V – 1.030V |
| 5 | 1280–1535 | 1.030V – 1.236V |
| 6 | 1536–1791 | 1.236V – 1.442V |
| 7 | 1792–2047 | 1.442V – 1.648V |
| 8 | 2048–2303 | 1.648V – 1.855V |
| 9 | 2304–2559 | 1.855V – 2.061V |
| 10 | 2560–2815 | 2.061V – 2.267V |
| 11 | 2816–3071 | 2.267V – 2.473V |
| 12 | 3072–3327 | 2.473V – 2.679V |
| 13 | 3328–3583 | 2.679V – 2.885V |
| 14 | 3584–3839 | 2.885V – 3.091V |
| 15 | 3840–4095 | 3.091V – 3.3V |
The slot index is clamped to 0–15.
4. Configuration — specials.txt
Tangible is configured in specials.txt on the SD card (root level, or inside a theme folder) using the tangible= key.
Format
tangible=VALUE0,VALUE1,VALUE2,VALUE3,VALUE4,VALUE5,VALUE6,VALUE7,VALUE8,VALUE9,VALUE10,VALUE11,VALUE12,VALUE13,VALUE14,VALUE15
16 comma-separated values, one per slot (0–15). Each value is either:
- A font number (integer, e.g.
0,1,5) — switches to that sound font when the slot is detected - An attribute character (single letter) — triggers a special behavior (see Section 5)
Enabling Tangible
Tangible is automatically enabled when specials.txt contains a tangible= line with at least one font number or one of the enabling attribute characters (X, x, Z, z, o, O, r, L). The neutral character - does NOT enable tangible by itself.
If specials.txt is missing or has no tangible= line, tangible is disabled and the saber can always ignite.
5. Attribute Characters
Each slot in the tangible= line can hold either a font number or a special action character. These action characters are especially useful for blade detection and accessory-based behavior.
| Char | Meaning | What it does |
|---|---|---|
- | Neutral | Nothing happens in this slot. Useful for unused slots or for creating gaps between active positions. |
x | No ignition | Prevents the saber from igniting. Good for a “blade missing” or “crystal missing” state. |
X | No ignition + retract if removed while on | Prevents ignition, and if the blade is removed while the saber is already on, it triggers a blade retraction. |
z | No ignition + boot warning | Same as x, but also gives a missing blade or missing crystal warning at boot. |
Z | No ignition + retract + boot warning | Same as X, but also gives a missing blade or missing crystal warning at boot. |
o | Blade present / start allowed | Indicates that the blade is inserted and the saber is allowed to ignite normally. |
O | Blade present with protected insert notification | Also indicates blade present, but only plays the blade insertion UI files if the saber was previously in another state. This helps avoid repeated insert sounds caused by voltage glitches during ramping or heavy battery load. |
r | Blade removed notification only | Indicates blade removal with sound and BMP, but does not prevent the saber from being used. |
L | Recall latest selected font | Returns to the latest font you selected from the menu. This is useful when an accessory temporarily overrides the font and you want the saber to go back to your last manually selected font when that accessory is removed. |
Simple way to think about it:
x/X/z/Zare mainly for “do not start” states.o/Oare mainly for “blade is present and ignition is allowed” states.ris for a blade-out notification without blocking saber use.Lis for restoring the last font you chose yourself from the menu.
6. Font Switching vs. Blade Detection
Tangible serves a dual purpose — it's both a font selector and a blade detector. These two functions are unified through the slot system:
As a Font Selector
Assign different font numbers to different slots. Place corresponding resistors in different blade connectors or chassis modules. When a blade is inserted, the voltage changes, a new slot is detected, and the font switches automatically.
As a Blade Detector
Reserve one slot (typically slot 0, the lowest voltage) for a no-start attribute (X, x, Z, or z). When no blade is present, the pin reads a low voltage, mapping to the no-start slot — preventing ignition. When a blade with a resistor is inserted, the voltage rises to a font slot — enabling ignition and selecting the correct font.
Combined Example
tangible=X,0,1,2,3,4,5,X,X,X,X,X,X,X,X,X
- Slot 0 (no blade): No-start
- Slots 1–6: Fonts 0 through 5 (six different blade resistors)
- Slots 7–15: No-start (unused voltage ranges, safety catch)
7. Practical Examples
Example A: Basic Blade Detection Only
Goal: Prevent the saber from igniting when no blade is inserted, but don't switch fonts.
tangible=X,o,-,-,-,-,-,-,-,-,-,-,-,-,-,-
- Slot 0 (no blade):
X= no-start, plays blade-out, powers off if ON - Slot 1 (blade present):
o= start, plays blade-in, allows ignition - Slots 2–15:
-= neutral (no action)
Place a resistor in the blade that maps to slot 1. No blade = slot 0 = can't start.
Example B: Four Blades, Four Fonts
Goal: Four different blades each with a unique sound font, plus blade detection.
tangible=X,0,1,2,3,-,-,-,-,-,-,-,-,-,-,-
- Slot 0: No blade — no-start
- Slot 1: Blade A — font 0
- Slot 2: Blade B — font 1
- Slot 3: Blade C — font 2
- Slot 4: Blade D — font 3
Select four resistor values that place each blade clearly in one of slots 1–4.
Example C: Silent Blade Removal
Goal: Blade detection that doesn't make sounds when the blade is removed while the saber is off.
tangible=x,O,-,-,-,-,-,-,-,-,-,-,-,-,-,-
- Slot 0:
x= NO_START2 — prevents starting, only plays blade-out sound if saber is OFF (non-blocking), does NOT force power off - Slot 1:
O= START2 — allows starting, suppresses repeated blade-in sounds during voltage settling
Example D: Full 15-Font Setup
Goal: Maximum font variety with one blade-out slot.
tangible=X,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14
- Slot 0: No blade — no-start
- Slots 1–15: Fonts 0 through 14
This requires 15 different resistor values, each producing a voltage clearly within its target slot.
Example E: Restore Last Font
Goal: A "default" blade that always returns to whatever font was last used via the menu.
tangible=X,L,0,1,2,3,-,-,-,-,-,-,-,-,-,-
- Slot 0: No blade
- Slot 1:
L= restores the font that was active before tangible started changing things - Slots 2–5: Specific fonts
A "plain" blade with a slot-1 resistor always plays the last manually-selected font. Specialized blades with higher resistors force specific fonts.
Guide generated from Crystal Focus X firmware source code analysis (Saber.cpp tangible state machine, Textfile.cpp specials.txt parsing, Ledstrip.cpp blade ID, main.h constants, Routines.cpp ADC reading).