Skip to content

Getting started

Walkthrough for a first measurement with a mock fixture, then real hardware.

Prerequisites

  • Rust 1.70+ (rustup update stable)
  • For hardware: NI-VISA or Keysight IO Libraries installed
  • .NET 8 SDK
  • For hardware: NI-VISA, Keysight IO Libraries, or another VISA that provides the VISA.NET shared components expected by IviFoundation.Visa

Step 1: Add the dependency

Mock / CI (no VISA):

[dependencies]
instrument-components = { version = "0.1", default-features = false }

Hardware (VISA default):

[dependencies]
instrument-components = "0.1"

Package publishing is deferred. From the repo:

cd dotnet
# Mock / CI
dotnet run --project examples/MockFixtureCi

# Hardware
dotnet run --project examples/Discover

Or project-reference InstrumentComponents (and InstrumentComponents.Visa for hardware).

use instrument::prelude::*;

fn main() -> Result<()> {
    let fixture = ScriptedFixture::builder()
        .idn("Keysight Technologies", "34401A", "SN1", "1.0")
        .kinds([InstrumentKind::Dmm])
        .on_query("*IDN?", "Keysight Technologies,34401A,SN1,1.0")
        .on_query(":MEAS:VOLT:DC?", "1.234")
        .build();

    let catalog = DeviceCatalog::from_fixture("mock://dmm-1", fixture)?;
    let volts = catalog.open_dmm("mock://dmm-1")?.measure_voltage_dc(None)?;
    println!("{volts} V");
    Ok(())
}

Run: cargo run (no extra features needed).

using InstrumentComponents.Catalog;
using InstrumentComponents.Kind;
using InstrumentComponents.Mock;

var fixture = ScriptedFixture.Builder()
    .Idn("Keysight Technologies", "34401A", "SN1", "1.0")
    .Kinds(InstrumentKind.Dmm)
    .OnQuery("*IDN?", "Keysight Technologies,34401A,SN1,1.0")
    .OnQuery(":MEAS:VOLT:DC?", "1.234")
    .Build();

var catalog = DeviceCatalog.FromFixture("mock://dmm-1", fixture);
var volts = catalog.OpenDmm("mock://dmm-1").MeasureVoltageDc();
Console.WriteLine($"{volts} V");

Or: dotnet run --project examples/MockFixtureCi

Step 3: Discover real instruments

use instrument::prelude::*;

fn main() -> Result<()> {
    let catalog = Discovery::visa()?.scan()?;
    for dev in catalog.devices() {
        println!(
            "{} @ {} — {:?}",
            dev.identity.model.as_deref().unwrap_or("?"),
            dev.address.raw,
            dev.supported_kinds,
        );
    }
    Ok(())
}

USB and GPIB are found automatically. Add TCPIP manually:

Discovery::visa()?
    .manual_address("TCPIP0::192.168.0.42::INSTR")
    .scan()?;
using InstrumentComponents.Visa;

var catalog = VisaDiscovery.Create().Scan();
catalog.PrintSummary();
dotnet run --project examples/Discover

Step 4: Open a typed class

let catalog = Discovery::visa()?.scan()?;
let dmms = catalog.devices_by_kind(InstrumentKind::Dmm);
if let Some(dev) = dmms.first() {
    let mut dmm = catalog.open_dmm(&dev.address.raw)?;
    let v = dmm.measure_voltage_dc(None)?;
    println!("{v} V");
}
using InstrumentComponents.Kind;
using InstrumentComponents.Visa;

var catalog = VisaDiscovery.Create().Scan();
var dmm = catalog.OpenDmm(
    catalog.DevicesByKind(InstrumentKind.Dmm)[0].Address.Raw);
Console.WriteLine(dmm.MeasureVoltageDc());

Step 5: Assign instruments in an app

Use stable DeviceId so replacing hardware does not break saved config:

let device_id = dev.device_id();
// persist device_id in your app config
let dmm = catalog.reconnect_by_identity(&device_id)?.open_dmm()?;
dotnet run --project examples/AssignInstruments

Persist DeviceId from discovery, then reconnect by identity after a rescan.

Optional: Async

Add features = ["tokio"] (and a tokio runtime). See Rust async.

[dependencies]
instrument-components = { version = "0.1", default-features = false, features = ["tokio"] }
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }

Core async APIs take CancellationToken and return Task / ValueTask. VISA async is currently a sync bridge — see C# async.

dotnet run --project examples/MockFixtureCiAsync

Environment variables (Rust VISA linking)

Variable Purpose
LIB_VISA_PATH Directory containing visa64.lib / visa.lib
LIB_VISA_NAME Library name (visa64, visa32, visa)

Next steps