Skip to main content

Support This Project

All projects made with passion 💙

Sponsor me

Instrumation

PyPI version License Python Versions Stars Downloads

Example

A high-level Hardware Abstraction Layer (HAL) for RF test stations. Stop wrestling with PyVISA boilerplate — write test logic, not connection code.


Why Instrumation?

RF test bench automation is painful. Every instrument brand has its own quirks, SCPI dialects vary, and testing your scripts requires physical hardware on your desk. Instrumation fixes all three:

  • One API for everything — same code works on Keysight, Rigol, and any other supported brand
  • Digital Twin mode — develop and debug offline with simulated instruments that emit realistic Gaussian noise
  • Smart auto-detection — scans connected devices and loads the right driver automatically, no manual config

Real Hardware Validation

Instrumation has been validated against real lab hardware. See our experiment reports:


PyVISA vs Instrumation: See the Difference

Programming a signal generator the traditional way vs. with Instrumation:

Aspect PyVISA (raw SCPI) Instrumation
Discovery Manual — find the resource string, manage ResourceManager Auto — just pass "AUTO" and the HAL scans USB + LAN for you
Connection rm.open_resource("TCPIP0::192.168.1.100::...") — hardcoded address connect_instrument("AUTO", "SG") — type-aware routing
Configuration sg.write(":FREQ:CW 2.4e9") — raw SCPI strings, no validation sg.set_frequency(2.4e9) — typed method with bounds checking
Cleanup Manual sg.close() — easy to forget Context manager — automatic with block cleanup
Offline Dev Requires real hardware connected Digital Twin — set INSTRUMATION_MODE=SIM and develop anywhere
Portability Vendor-specific SCPI — rewrite for each brand One API — works on Keysight, Rigol, Tektronix, Siglent, R&S, Anritsu

Side-by-Side Code

# ─── PyVISA: 8 lines of boilerplate ───
import pyvisa
rm = pyvisa.ResourceManager()
# Manually find the right resource...
sg = rm.open_resource("TCPIP0::192.168.1.100::inst0::INSTR")
sg.write("*RST")
sg.write(":FREQ:CW 2.4e9")
sg.write(":POW:AMPL -10")
sg.write(":OUTP ON")
sg.close()

# ─── Instrumation: 5 lines, zero config ───
from instrumation import connect_instrument

with connect_instrument("AUTO", "SG") as sg:
    sg.set_frequency(2.4e9)
    sg.set_amplitude(-10)
    sg.set_output(True)

No resource manager. No SCPI strings. No hardcoded addresses. Just your test logic.


Live Data Streaming

Instrumation includes a built-in DataBroadcaster for streaming live readings over UDP. This allows you to build real-time dashboards or loggers with zero external dependencies.

  • Zero-lag — UDP delivery doesn't block your test flow.
  • Zero-config — Broadcast to any host/port as JSON packets.
  • Zero-dep — Built-in with Python standard library.

See examples/broadcast_demo.py and examples/dashboard.py for usage.

Features

  • Auto-Discovery — scans VISA and Serial buses, identifies what's connected
  • Smart Factory — detects instrument brand and loads the correct driver
  • Digital Twin — full simulation mode for offline development and CI pipelines
  • Unified API — write once, run on any supported hardware
  • Built-in CSV logging — test results logged out of the box

Installation

pip install instrumation

Or install from source:

git clone https://github.com/abduznik/instrumation.git
cd instrumation
pip install .

Windows users: You may need NI-VISA or Keysight IO Libraries Suite for physical hardware access.


Quick Start

Real hardware

import instrumation

sa = instrumation.connect_instrument("USB0::0x2A8D::...")

peak_power = sa.get_peak_value()
print(f"Peak Power: {peak_power} dBm")

Digital Twin (no hardware needed)

# Linux/macOS
export INSTRUMATION_MODE=SIM

# Windows PowerShell
$env:INSTRUMATION_MODE="SIM"
from instrumation.factory import get_instrument

# Safer usage with context manager
with get_instrument("DUMMY_ADDRESS", "DMM") as dmm:
    print(dmm.get_id())
    result = dmm.measure_voltage()
    print(f"Voltage: {result}")

Station Manager (TOML)

Manage complex test stations with multiple instruments using a station.toml file.

[instruments.sa_main]
driver = "SA"
address = "USB0::0x2A8D::0x0101::MY12345678::0::INSTR"

[instruments.psu_dut]
driver = "PSU"
address = "TCPIP0::192.168.1.100::inst0::INSTR"

Use it in your code:

from instrumation import Station

station = Station("station.toml")
station.connect()

# Access instruments via dot notation
res = station.instr.sa_main.get_peak_value()
print(f"Peak: {res}")

station.disconnect()

Command Line Interface

Instrumation comes with a powerful CLI for quick interaction and diagnostics.

# Scan for connected hardware
instrumation scan

# Take a quick measurement
instrumation measure USB0::... DMM measure_voltage

# List instruments in your station.toml
instrumation station list

# Measure using a named instrument from your station
instrumation station measure sa_main get_peak_value

API Reference

Command Description
scan() Lists all connected Serial and VISA devices
connect() Auto-connects to a generic Test Station (Box + Instrument)
connect_instrument(addr) Connects to a specific instrument with auto driver detection

Platform Support

Platform Status
Windows Supported
Linux Supported
Termux (Android) Supported
macOS Supported

Development

# Install in editable mode (required for tests to pick up local changes)
pip install -e .
# This project uses pyproject.toml (PEP 517/518). No setup.py is required.


# Install test dependencies
pip install pytest flake8

# Run tests (simulation mode)
export INSTRUMATION_MODE=SIM  # Linux/macOS
pytest

Related Projects

instrumation-report

A lightweight Python library for generating structured UUT (Unit Under Test) test reports from measurement data. Works standalone or alongside Instrumation.

Features:

  • HTML, Excel, and PDF report output
  • Automatic pass/fail evaluation with configurable conditions
  • Structured sections and test tables
  • Easy integration with Instrumation measurements
pip install instrumation-report
from instrumation_report import Report, Section, TestTable, Measurement

report = Report(header=ReportHeader(
    title="RF Subsystem Validation",
    engineer="Yan",
    uut_serial="SN-2024-001",
))

section = Section(number="1", title="Voltage Tests")
table = TestTable(title="Power Supply Checks", sub_number="1.1")
table.add(Measurement("3.3V Rail", 3.31, "V", condition=(3.2, 3.4)))
section.add_table(table)
report.add_section(section)

report.generate_html("report.html")
report.generate_excel("report.xlsx")

Tech Stack

  • Language: Python 3.7+
  • Libraries: PyVISA, PySerial
  • Architecture: Smart Factory Pattern, Polymorphism
  • Standards: SCPI (Standard Commands for Programmable Instruments)

Support the Project

Instrumation is maintained in my spare time alongside a full-time RF technician job. If it's saved you hours of boilerplate or made your test bench easier to automate, consider supporting:

GitHub Sponsors

Commercial support or custom driver development? Reach out via GitHub Issues or Discussions.


Contributing

PRs and driver contributions are welcome. Open an issue first to discuss larger changes.

License

See LICENSE for details.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

instrumation-0.5.0.tar.gz (76.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

instrumation-0.5.0-py3-none-any.whl (61.8 kB view details)

Uploaded Python 3

File details

Details for the file instrumation-0.5.0.tar.gz.

File metadata

  • Download URL: instrumation-0.5.0.tar.gz
  • Upload date:
  • Size: 76.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for instrumation-0.5.0.tar.gz
Algorithm Hash digest
SHA256 ff8e613c4c973b31fe554f208ed6043457ff600a6381f460b197a857358d3d2b
MD5 606d17aa8a8298e458e378ee5be1dc81
BLAKE2b-256 954f4bad911231e1fabf9068357d9cb99f1de19d39f55c44c85ed7670f3d3149

See more details on using hashes here.

File details

Details for the file instrumation-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: instrumation-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 61.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for instrumation-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9f8b50d008f99a91597e5f0b9023d7869318d4106f0523d82fdeda6292e7ffaa
MD5 e151d72f51b4d7916a55a7c01be4e795
BLAKE2b-256 c67aa0b674a7181992cc53424e3c4c2bb4e563aaae2754b2a411aea1a546eda0

See more details on using hashes here.

Release history Release notifications | RSS feed

0.7.1

2 files

0.7.0

2 files

0.6.0

2 files

0.5.1

2 files

This release

0.5.0 This release

2 files

0.4.2

2 files

0.4.1

2 files

0.4.0

2 files

0.3.2

2 files

0.3.1

2 files

0.3.0

2 files

0.2.1

2 files

0.2.0

2 files

0.1.6

2 files

0.1.5

2 files

0.1.4

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page