2 unstable releases
| new 0.1.1 | Feb 10, 2026 |
|---|---|
| 0.0.2 | Oct 2, 2025 |
#93 in Operating systems
500KB
10K
SLoC
rusty-tip
Rust library and tools for automated STM/AFM tip preparation on Nanonis SPM systems.
Overview
rusty-tip provides automated tip conditioning for Scanning Probe Microscopy (SPM) systems. It connects to Nanonis controllers via TCP and implements tip preparation algorithms with configurable pulse strategies and stability verification.
Features
- Automated Tip Preparation - State machine that detects tip quality and applies conditioning pulses
- Multiple Pulse Strategies - Fixed voltage, adaptive stepping, or linear mapping based on signal response
- Stability Verification - Optional bias sweep testing to confirm tip stability
- Real-time Monitoring - TCP data logging with signal history tracking
- CLI and GUI Applications - Both command-line and graphical interfaces
- Configurable - TOML configuration with environment variable overrides
Installation
Pre-built Binaries
Download from GitHub Releases:
- Linux:
rusty-tip-x86_64-unknown-linux-gnu.tar.xz - Windows:
rusty-tip-x86_64-pc-windows-msvc.zip
Each archive contains:
tip-prep/tip-prep.exe- Command-line tooltip-prep-gui/tip-prep-gui.exe- Graphical interface
From Source
# CLI only
cargo build --release
# With GUI
cargo build --release --features gui
As a Library
cargo add rusty-tip
Usage
CLI (tip-prep)
tip-prep --config path/to/config.toml
tip-prep --config config.toml --log-level debug
Options:
--config <FILE>- Path to TOML configuration file (required)--log-level <LEVEL>- Override log level: trace, debug, info, warn, error
GUI (tip-prep-gui)
Launch the application and load a configuration file via the file dialog. The interface provides:
- Control Tab - Start/stop preparation, live status display
- Configuration Tab - Edit all parameters before running
Configuration
Configuration uses TOML format. See configs/ for examples.
Minimal Example
[nanonis]
host_ip = "127.0.0.1"
control_ports = [6501, 6502, 6503, 6504]
[data_acquisition]
data_port = 6590
sample_rate = 2000
[tip_prep]
sharp_tip_bounds = [-1.5, 0.0] # Frequency shift range for "sharp" (Hz)
max_cycles = 10000
max_duration_secs = 12000
initial_bias_v = -0.5
initial_z_setpoint_a = 100e-12
[pulse_method]
type = "fixed"
voltage = 4.0
polarity = "positive"
Pulse Methods
Fixed - Constant voltage pulses:
[pulse_method]
type = "fixed"
voltage = 4.0
polarity = "positive" # or "negative"
Stepping - Increases voltage after repeated failures:
[pulse_method]
type = "stepping"
voltage_bounds = [2.0, 6.0]
voltage_steps = 4
cycles_before_step = 2
threshold_value = 0.1
Linear - Voltage scales with current signal:
[pulse_method]
type = "linear"
voltage_bounds = [2.0, 7.0]
linear_clamp = [-20.0, 0.0] # Map freq_shift range to voltage range
Stability Checking
Optional verification that the tip remains stable under bias sweeps:
[tip_prep.stability]
check_stability = true
stable_tip_allowed_change = 0.4 # Max allowed freq_shift change (Hz)
bias_range = [0.2, 2.0] # Sweep range (V)
bias_steps = 1000
step_period_ms = 200
polarity_mode = "both" # "positive", "negative", or "both"
Full Configuration Reference
[nanonis]
host_ip = "127.0.0.1"
control_ports = [6501, 6502, 6503, 6504]
layout_file = "./layout.lyt" # Optional
settings_file = "./settings.ini" # Optional
[data_acquisition]
data_port = 6590
sample_rate = 2000
[experiment_logging]
enabled = true
output_path = "./experiments"
[console]
verbosity = "info"
[tip_prep]
sharp_tip_bounds = [-1.5, 0.0]
max_cycles = 10000
max_duration_secs = 12000
initial_bias_v = -0.5
initial_z_setpoint_a = 100e-12
[tip_prep.stability]
check_stability = true
stable_tip_allowed_change = 0.4
bias_range = [0.2, 2.0]
bias_steps = 1000
step_period_ms = 200
max_duration_secs = 100
polarity_mode = "both"
[pulse_method]
# See pulse method examples above
Library Usage
use rusty_tip::{ActionDriver, Action, NanonisClient};
// Connect to Nanonis
let client = NanonisClient::new("127.0.0.1", 6501)?;
let mut driver = ActionDriver::new(client);
// Execute actions
driver.execute(Action::ReadBias)?;
driver.execute(Action::SetBias { voltage: -0.5 })?;
driver.execute(Action::AutoApproach { center_freq_shift: true })?;
driver.execute(Action::BiasPulse {
voltage: 4.0,
duration_ms: 10,
z_hold: true,
})?;
Available Actions
| Category | Actions |
|---|---|
| Signals | ReadSignal, ReadSignals, ReadSignalNames, ReadBias, SetBias |
| Positioning | ReadPiezoPosition, SetPiezoPosition, MovePiezoRelative, MoveMotor3D |
| High-level | AutoApproach, Withdraw, SafeReposition, BiasPulse, TipShaper |
| Analysis | CheckTipState, CheckTipStability, GetStableSignal |
| Scanning | ScanControl, ReadScanStatus |
| Oscilloscope | ReadOsci |
How It Works
The tip preparation follows a state machine:
-
Blunt - Tip quality below threshold
- Apply voltage pulse
- Reposition (withdraw, move, approach)
- Check if now sharp
-
Sharp - Tip quality within bounds
- Verify with multiple repositions
- If stability checking enabled: perform bias sweep
- If stable, mark complete; otherwise pulse and return to Blunt
-
Stable - Preparation complete
Requirements
- Nanonis SPM controller with TCP interface enabled
- Configured TCP data logging (typically port 6590)
- Control ports accessible (typically 6501-6504)
License
MIT
Dependencies
~13–43MB
~639K SLoC