Add structured GPIB command reference (commands.json) and docs
Complete extraction of all 97 commands in HP 3457A Operating.pdf Chapter 4, expanded to 120 JSON entries (F10-F58 modeled as 24 independent commands rather than one parameterized command). Each entry includes description, syntax, structured parameters, important points, worked examples, and tier/rationale classification to guide which commands a Python control library actually needs. Documents several findings not obvious from the manual alone: the output buffer's single-reading data-loss behavior and the correct burst-acquisition pattern, the CR/LF bus-hold gotcha, the Front Panel checkbox's unreliability, the isolation-link mechanism behind F10-F58's speed, and memory/timing capacity math for burst captures. Updates README.md (was empty) and cmdformat.txt to document the schema and key findings.
This commit is contained in:
127
README.md
127
README.md
@@ -0,0 +1,127 @@
|
|||||||
|
# HP 3457A
|
||||||
|
|
||||||
|
Reverse-engineered GPIB command reference for the HP 3457A digital
|
||||||
|
multimeter, built toward a Python control library. The instrument
|
||||||
|
predates SCPI/IEEE-488.2, so it doesn't understand `*IDN?` and friends —
|
||||||
|
it has its own compact command language, documented only in the PDF
|
||||||
|
manuals below.
|
||||||
|
|
||||||
|
## Contents
|
||||||
|
|
||||||
|
- **`commands.json`** — the deliverable. A complete, hand-verified,
|
||||||
|
structured extraction of every command in Chapter 4 ("Command
|
||||||
|
Reference") of `HP 3457A Operating.pdf`: 97 documented commands,
|
||||||
|
expanded to 120 JSON entries (the `F10`–`F58` family is 24 independent
|
||||||
|
zero-parameter commands crammed onto one manual page — modeled here as
|
||||||
|
24 separate entries, not one command with 24 parameter choices). Each
|
||||||
|
entry has description, syntax, structured parameters (typed value
|
||||||
|
tables with power-on/default flags where the manual provides them),
|
||||||
|
important points, and worked examples, plus two classification fields
|
||||||
|
not in the manual (see below). Read the `_meta` block at the top of the
|
||||||
|
file first — it documents the schema and a dozen cross-cutting findings
|
||||||
|
that took real digging to establish, not just page-by-page
|
||||||
|
transcription.
|
||||||
|
- **`cmdformat.txt`** — the schema outline `commands.json` follows.
|
||||||
|
- **`HP 3457A Operating.pdf`** — the real command/operating reference.
|
||||||
|
Chapter 4 is the source for `commands.json`; Chapter 1 has the
|
||||||
|
abbreviated specifications (accuracy, reading rates, memory); Chapter 3
|
||||||
|
has the conceptual explanations (triggering, math operations, buffers)
|
||||||
|
Chapter 4 assumes you've already read.
|
||||||
|
- **`HP 3457A Service.pdf`** — board-level theory of operation and
|
||||||
|
schematics. Poor OCR/scan quality throughout (don't expect a clean
|
||||||
|
full-text read), but worth a targeted search when a specific mechanism
|
||||||
|
needs explaining — e.g. it's what revealed the opto-isolated
|
||||||
|
master/slave-processor link that explains why `F10`–`F58` execute
|
||||||
|
faster than `DCV`/`OHM`/`OHMF`.
|
||||||
|
- **`GPIBProgrammingReferenceManual.pdf`** — despite the filename, this is
|
||||||
|
a *generic* Advantech GPIB interface-card primer (bus concepts,
|
||||||
|
IEEE-488 basics), not HP 3457A-specific. Useful for general GPIB
|
||||||
|
background, not command syntax.
|
||||||
|
|
||||||
|
## `commands.json` at a glance
|
||||||
|
|
||||||
|
Every entry carries two classification fields beyond what the manual
|
||||||
|
documents, meant to guide what a Python library should actually expose:
|
||||||
|
|
||||||
|
- **`tier`** — does a typical automated measurement workflow need this?
|
||||||
|
`core` (40 — measurement functions plus the setup/trigger/timing/status
|
||||||
|
commands a controller genuinely can't replicate host-side), `protocol`
|
||||||
|
(3 — `ADDRESS`/`END`/`INBUF`, bus/transport housekeeping), `extended`
|
||||||
|
(77 — real and documented, but not needed for typical use: plug-in-card
|
||||||
|
commands, on-instrument program/state storage a host script replaces,
|
||||||
|
calibration/diagnostics/service, front-panel UI, legacy speed-optimized
|
||||||
|
aliases).
|
||||||
|
- **`rationale`** — *why* does this exist / why is it fast? Distinguishes
|
||||||
|
genuine hardware advantages that remain relevant today
|
||||||
|
(`measurement_hardware`, `acquisition_timing`) from things that only
|
||||||
|
mattered because 1980s host controllers were slow or limited
|
||||||
|
(`era_computer_workaround`), plus a few narrower buckets
|
||||||
|
(`wire_efficiency`, `plugin_card_dependent`, `diagnostic_calibration`,
|
||||||
|
`status_error_readback`, `ui_frontpanel_only`, `bus_protocol`).
|
||||||
|
|
||||||
|
`tier` and `rationale` are independent axes and are allowed to disagree —
|
||||||
|
e.g. the `MEM` reading-memory family is `extended` tier (most workflows
|
||||||
|
don't need it) but `acquisition_timing` rationale (genuinely valuable
|
||||||
|
*if* burst throughput matters).
|
||||||
|
|
||||||
|
### Notable findings baked into `_meta`
|
||||||
|
|
||||||
|
- **Only `ADDRESS` is Remote-unchecked** across all 120 entries — you
|
||||||
|
can't remotely reassign the instrument's own bus address. Everything
|
||||||
|
else is fully GPIB-controllable. `POWER` isn't a documented command at
|
||||||
|
all (pure physical switch).
|
||||||
|
- **The Front Panel checkbox is unreliable** as a "what's physically
|
||||||
|
possible" signal — `DCV`/`ACV`/`ACI`/`ACDCV`/`DCI` are all marked
|
||||||
|
unchecked despite having real dedicated/shifted panel keys; `ACDCI` is
|
||||||
|
checked despite Chapter 3 describing it in word-for-word parallel terms
|
||||||
|
to its siblings (almost certainly a manual erratum on the `ACDCI` page).
|
||||||
|
- **The output buffer holds exactly one reading** and silently overwrites
|
||||||
|
it if not drained in time — there is no GPIB streaming mode. The
|
||||||
|
documented high-throughput pattern is `NRDGS <count>` + a single
|
||||||
|
`TRIG SGL`, which runs the whole burst to completion *inside* the
|
||||||
|
instrument (bus held throughout) before you pay any transfer cost.
|
||||||
|
`MATH STAT`/`PFAIL` are the two math operations that don't alter the
|
||||||
|
reading, so they accumulate accurate aggregates across a burst even
|
||||||
|
when individual readings never make it off the bus — genuinely useful
|
||||||
|
for a burst that outruns the transfer channel, not a 1980s-era
|
||||||
|
workaround.
|
||||||
|
- **CR/LF bus-hold gotcha**: with the input buffer off (its power-on
|
||||||
|
default), the instrument holds the HP-IB bus until a command finishes
|
||||||
|
executing, because it processes `<CR>` immediately but not `<LF>` until
|
||||||
|
done. Explains earlier confusing "dropped command" symptoms seen live
|
||||||
|
on this project's hardware.
|
||||||
|
- **Memory/timing math**: 2208 bytes total (reading/subprogram/state,
|
||||||
|
via `MSIZE`); reading-memory format (`MFORMAT`) determines bytes/sample
|
||||||
|
(2–16); the empirical reading-rate table tops out at 1350 readings/sec
|
||||||
|
(`DCV`, 3.5 digits, autozero off) — filling the ~1053-sample max buffer
|
||||||
|
at that rate takes ~0.78s. `ACV`/`ACI` cap out ~140x slower (~9.5
|
||||||
|
rdg/s) since AC measurement is internally-aggregated, not instantaneous
|
||||||
|
sampling — so `DCV` burst mode is the only realistic way to approximate
|
||||||
|
an oscilloscope-style capture with this instrument.
|
||||||
|
|
||||||
|
Full detail, sourcing, and page references for all of the above are in
|
||||||
|
`commands.json`'s `_meta` block.
|
||||||
|
|
||||||
|
## Related work reviewed
|
||||||
|
|
||||||
|
- [sigrok's `hp-3457a` driver](https://github.com/sigrokproject/libsigrok/tree/master/src/hardware/hp-3457a) —
|
||||||
|
thin coverage: measurement-mode selection, NPLC, terminal switching,
|
||||||
|
autorange query, `RMATH HIRES`, rear-card scan-list plumbing. No
|
||||||
|
`PER`, no explicit range/resolution, no `FSOURCE` (flagged `TODO` in
|
||||||
|
their own code), nothing for math/calibration/display/subprograms.
|
||||||
|
- [MikeDombo/HP3457A-GPIB](https://github.com/MikeDombo/HP3457A-GPIB) —
|
||||||
|
a wxPython measurement GUI. Confirmed real-world use of the `F10`-`F58`
|
||||||
|
shorthand family and the `TERM 1`/`TERM 2` numeric equivalents.
|
||||||
|
|
||||||
|
## Status / next steps
|
||||||
|
|
||||||
|
`commands.json` is complete and is the ground-truth spec for the planned
|
||||||
|
Python control library, which hasn't been started yet. The transport
|
||||||
|
layer (Prologix GPIB-ETHERNET controller) already exists in the sibling
|
||||||
|
repo `progpib` — the plan is to build HP 3457A-specific command wrappers
|
||||||
|
on top of that rather than reimplementing GPIB transport here. One
|
||||||
|
documented gap remains: the separate "HP-IB Commands" section (manual
|
||||||
|
pages 4-167–4-174, generic IEEE-488 bus messages like `CLEAR`/`LOCAL`/
|
||||||
|
`REMOTE`) hasn't been extracted into `commands.json` yet, since it likely
|
||||||
|
maps to functionality `progpib` already exposes at the transport layer
|
||||||
|
rather than needing instrument-specific wrappers.
|
||||||
|
|||||||
@@ -1,15 +1,53 @@
|
|||||||
command name
|
Schema for entries in commands.json (the "commands" array).
|
||||||
local y/n
|
Read commands.json's own "_meta" block for the full rationale behind each
|
||||||
remote y/n
|
field below and for cross-cutting findings that don't belong to any one
|
||||||
description
|
command.
|
||||||
syntax
|
|
||||||
parameters
|
|
||||||
>> parameter name
|
|
||||||
>> parameter description
|
|
||||||
>> parameter values
|
|
||||||
>>>> value description
|
|
||||||
>>>> power-on value y/n
|
|
||||||
>>>> default value y/n
|
|
||||||
Important points
|
|
||||||
example
|
|
||||||
|
|
||||||
|
command name -> "name"
|
||||||
|
manual page(s) -> "manual_pages" (array of printed page numbers, e.g. ["4-7","4-8"])
|
||||||
|
local y/n -> "local" (Front Panel checkbox; see _meta.front_panel_caveat before trusting this)
|
||||||
|
remote y/n -> "remote" (Remote checkbox; only ADDRESS is false)
|
||||||
|
description -> "description"
|
||||||
|
syntax -> "syntax" (null for the four service-only commands)
|
||||||
|
parameters -> "parameters" (array, empty [] if the command takes none)
|
||||||
|
>> parameter name -> parameters[i].name
|
||||||
|
>> parameter description -> parameters[i].description
|
||||||
|
>> parameter values -> parameters[i].values (array of choice/range rows; empty [] for free-form numeric parameters)
|
||||||
|
>>>> value description -> values[j].description
|
||||||
|
>>>> power-on value y/n -> values[j].power_on (bool, only present for discrete enumerated choices)
|
||||||
|
>>>> default value y/n -> values[j].default (bool, only present for discrete enumerated choices)
|
||||||
|
>> (free-form parameters instead carry parameters[i].power_on_raw / .default_raw as plain text)
|
||||||
|
Important points -> "important_points" (array of strings)
|
||||||
|
example -> "examples" (array of {code, comment, note?})
|
||||||
|
|
||||||
|
Fields added beyond the original sketch, once the actual manual data made
|
||||||
|
clear they were needed:
|
||||||
|
|
||||||
|
tier -> "core" | "protocol" | "extended" -- does a typical
|
||||||
|
automated workflow need this command? See
|
||||||
|
_meta.tiering.
|
||||||
|
tier_reason -> free text explaining the tier call for this
|
||||||
|
specific command.
|
||||||
|
rationale -> "measurement_hardware" | "acquisition_timing" |
|
||||||
|
"wire_efficiency" | "era_computer_workaround" |
|
||||||
|
"plugin_card_dependent" | "diagnostic_calibration" |
|
||||||
|
"status_error_readback" | "ui_frontpanel_only" |
|
||||||
|
"bus_protocol" -- WHY the command exists / is fast,
|
||||||
|
independent of whether a library needs it. See
|
||||||
|
_meta.rationale_taxonomy.
|
||||||
|
service_command -> true for the 4 commands (CAL, DIAGNOSTIC, SECURE,
|
||||||
|
REV?) the manual defers entirely to the Service
|
||||||
|
manual, with no documented syntax here.
|
||||||
|
see_also -> present on R and T, the bare-syntax aliases of
|
||||||
|
RANGE and TRIG -- points to the real command
|
||||||
|
instead of duplicating its content.
|
||||||
|
family -> "F10-F58" on each of that family's 24 entries,
|
||||||
|
linking them together (see _meta.f10_f58_split
|
||||||
|
for why they're split into 24 entries instead of
|
||||||
|
one parameterized command).
|
||||||
|
selects_function / selects_range -> present only on the F10-F58 family entries;
|
||||||
|
what that specific zero-parameter command
|
||||||
|
configures.
|
||||||
|
prerequisites -> present only on "?" (the standalone trigger
|
||||||
|
shorthand); the TARM/NRDGS/TRIG state it requires
|
||||||
|
before it will work.
|
||||||
|
|||||||
6084
commands.json
Normal file
6084
commands.json
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user