Reverse Engineering Projekt für die National Instruments (NI) ENET/100 GPIB Adapter
  • C 98.2%
  • Python 1.8%
Find a file
2026-05-31 18:32:59 +02:00
captures Captures aufgenommen. 2026-05-30 11:07:00 +02:00
ghidra Update nach weiteren Untersuchungen, v.a. bzgl. mehreren Geräten am Bus. 2026-05-30 19:46:49 +02:00
hp_8753e_doc Update nach weiteren Untersuchungen, v.a. bzgl. mehreren Geräten am Bus. 2026-05-30 19:46:49 +02:00
notes Ergänzungen in protocol.md nach Umsetzung des pyvisa Adapters. 2026-05-31 18:32:59 +02:00
tools Tools aufgenommen, reference-Ordner aus Git ausgeklammert. 2026-05-30 11:09:41 +02:00
.gitignore Tools aufgenommen, reference-Ordner aus Git ausgeklammert. 2026-05-30 11:09:41 +02:00
.mcp.json Erste Dateien aufgenommen aus dem VS Code Workspace. 2026-05-30 11:05:21 +02:00
enet100_multipad_probe.py Update nach weiteren Untersuchungen, v.a. bzgl. mehreren Geräten am Bus. 2026-05-30 19:46:49 +02:00
enet100_port5015_probe.py Update nach weiteren Untersuchungen, v.a. bzgl. mehreren Geräten am Bus. 2026-05-30 19:46:49 +02:00
enet100_probe.py Erste Dateien aufgenommen aus dem VS Code Workspace. 2026-05-30 11:05:21 +02:00
enet100_smoketest.py Tippfehler in Dateiname korrigiert. 2026-05-30 11:20:55 +02:00
enet100_srq_probe.py Update nach weiteren Untersuchungen, v.a. bzgl. mehreren Geräten am Bus. 2026-05-30 19:46:49 +02:00
GPIB-ENET-100_Protocol.md Protokollzusammenfassung aufgenommen. 2026-05-31 08:37:47 +02:00
output.txt Update nach weiteren Untersuchungen, v.a. bzgl. mehreren Geräten am Bus. 2026-05-30 19:46:49 +02:00
output_multipad.txt Update nach weiteren Untersuchungen, v.a. bzgl. mehreren Geräten am Bus. 2026-05-30 19:46:49 +02:00
output_pushprobe.txt Update nach weiteren Untersuchungen, v.a. bzgl. mehreren Geräten am Bus. 2026-05-30 19:46:49 +02:00
README.md Erste Dateien aufgenommen aus dem VS Code Workspace. 2026-05-30 11:05:21 +02:00

NI GPIB-ENET/100 → pyvisa on Linux (driver-free)

Reverse-engineering project to control GPIB lab instruments (first target: HP 8753E vector network analyzer) through an NI GPIB-ENET/100 Ethernet↔GPIB adapter, natively on Linux, without NI's proprietary driver.


1. Goal & constraints

  • Keep the existing NI GPIB-ENET/100 (replacement adapters are expensive).
  • Linux-native operation (no permanent Windows dependency in the loop).
  • Control instruments via a pyvisa-style API.
  • First instrument: HP 8753E VNA.

2. Key finding — why there is no off-the-shelf path

pyvisa is only a frontend; it needs a backend that actually speaks the controller's protocol. Neither available backend can drive the ENET/100:

Backend ENET/100 support on Linux
NI-VISA / NI-488.2 (proprietary) No. NI dropped the /100; the Linux driver lists only the GPIB-ENET/1000. The /100 was removed around the time NI hardened against fake USB clones.
pyvisa-py (@py, pure Python) No. It speaks VXI-11 / HiSLIP / raw TCP socket over Ethernet, and GPIB via linux-gpib. The ENET/100 speaks none of these — it uses NI's proprietary protocol on TCP port 5000.

Confirmed symptoms from others: TCPIP::<ip>::INSTRconnection refused; ASRL<addr>::<ip>::5000::INSTR → fails. NI states plainly that you cannot talk to the ENET over plain TCP/IP without going through the driver.

Conclusion: of {keep the /100, stay on Linux, use pyvisa}, the only DIY way to satisfy all three is to reverse-engineer the port-5000 protocol and wrap it ourselves. That is the path this project takes.

3. The ENET protocol (reference shape)

The closest available reference is libnienet.py (Robert Jördens), which implements the protocol of the original GPIB-ENET. It is a thin RPC over TCP:5000 that serializes the classic NI-488 API.

  • Transport: TCP, port 5000, big-endian (!).
  • Command frame: 1-byte command ID + arguments, padded to 12 bytes.
  • Response header: !HH4xLstatus (u16), error (u16), 4 bytes pad, count (u32), followed by payload.
  • Payload fragments: each prefixed with !HHflags (u16), length (u16); read repeats while flags is set.
  • Command IDs (original ENET): 0x07 ibdev, 0x12 ibonl, 0x04 ibclr, 0x1f ibtmo, 0x20 ibtrg, 0x19 ibrsp, 0x23 ibwrt, 0x16 ibrd, …
  • Write sends the command (with length) then the raw bytes, then reads a response. Read sends the command then consumes the fragmented stream.

⚠️ Critical caveat: this is the original ENET protocol. The /100 is the successor and almost certainly uses a similar but not identical protocol (the Py3 port of libnienet is explicitly "not for /100 or /1000"). Treat the frame layout as a hypothesis to verify, not a finished spec.

4. Reverse-engineering plan

The ENET/100 is a network device, so a VM with bridged networking reaches it directly — no USB passthrough needed.

  1. Reference rig: Windows VM with bridged networking + NI-488.2 installed; ENET/100 configured and reachable on the same LAN.
  2. Generate traffic: send *IDN? to the HP 8753E from the VM (NI MAX / gpibintctrl, or a 3-line pyvisa script on the NI backend).
  3. Capture: Wireshark on the host, filter tcp.port == 5000.
  4. Decode: compare captured frames against enet100_probe.py. Adjust command IDs, field widths, and the "magic" address bytes in write()/read() until your generated frames byte-for-byte reproduce the NI driver's.

When your frames match the capture, you have a working Linux-native path.

5. Python integration strategy

  • Start minimal. Do not build a full pyvisa-py backend first — overkill. Use the EnetResource class (write/read/query/timeout/close) as a pyvisa-Resource look-alike. Write instrument code against that interface so a real backend can be slotted in later without touching measurement scripts.
  • Reference repos:
    • libnienet.py — original protocol implementation (Python 2).
    • vc12345679/NI_GPIB_ENET_Py3 — Python 3 port + query wrapper; structure is ~1:1 what we need (targets original ENET, not /100).

6. HP 8753E specifics (the easy part, once transport works)

  • GPIB address: set on the front panel (Local key → GPIB menu; commonly 16). Must match pad in the code.
  • IEEE 488.2: the E generation supports common commands → *IDN? and *OPC? work (the older 8753C does not). *IDN? is the ideal first test; expect HEWLETT PACKARD,8753E,....
  • Command set: HP-8753 mnemonics, not modern SCPI. Examples:
    • STAR / STOP — start / stop frequency
    • POIN — number of points
    • FORM4 — ASCII data format
    • OUTPFORM — read the formatted trace
  • Sweeps take time: use generous timeouts and synchronize with *OPC? (trigger sweep → wait for 1 → read data) instead of fixed delays.

7. Suggested workspace layout

enet100-pyvisa/
├── README.md                 # this file
├── enet100_probe.py          # transport + EnetResource starter (provided)
├── captures/                 # Wireshark .pcapng reference captures
│   └── idn_query.pcapng
├── notes/
│   └── protocol.md           # decoded command IDs / frame deltas vs. original
├── instruments/
│   └── hp8753e.py            # high-level VNA wrapper (built on EnetResource)
└── tests/
    └── test_idn.py

8. Next steps (checklist)

  • Stand up the Windows VM reference rig (bridged net + NI-488.2).
  • Confirm the ENET/100's IP and the 8753E's GPIB address.
  • Capture a clean *IDN? exchange on tcp.port == 5000.
  • Diff capture vs. enet100_probe.py; record deltas in notes/protocol.md.
  • Get *IDN? working end-to-end from Linux.
  • Add ibtmo / *OPC? handshaking for sweeps.
  • Build instruments/hp8753e.py (set freqs, points, read trace).
  • (Optional) wrap as a proper pyvisa-py backend for drop-in compatibility.

9. Fallback options (if RE stalls)

  • Windows/VM bridge: run pyvisa on the NI backend inside the VM (the /100 is supported on Windows) — keeps the hardware, loses Linux-native.
  • Replace the controller: a linux-gpib-supported adapter (e.g. Keysight 82357B USB-GPIB, or a genuine NI GPIB-USB-HS) works out-of-the-box with pyvisa-py — loses the /100, gains the least friction.

Status: scaffolding. The protocol frame layout in enet100_probe.py is a hypothesis derived from the original GPIB-ENET and must be verified against a real ENET/100 capture.