kuwoyuki fb6c3cbb7b feat: add ++dmm_loop cmd
++dmm_loop <0|1> to disable the HP3478A DMM loop, if for some reason the
DMM app loop is interfering with the GPIB bus when used as a USB-GPIB
controller
2025-12-04 18:26:02 +06:00
pic
2025-12-02 03:59:40 +06:00
2025-12-04 18:26:02 +06:00
2025-11-30 04:47:14 +06:00
2025-11-30 04:47:14 +06:00
2025-11-30 04:47:14 +06:00
2025-12-04 18:26:02 +06:00
2025-11-30 04:47:14 +06:00

HP3478A Internal USB-GPIB Extension

An internal extension board for the HP3478A Multimeter. USB-CDC-GPIB bridge (Prologix-style) and an internal feature controller.

Uses WCH CH32V203 (RISC-V) MCU.

It enumerates as a standard serial device (e.g., /dev/ttyACM0 or COMx).

PCB here

PCB

Menu System

Extended features (Continuity, Temp, etc.) can be accessed using the SRQ button of HP3478A without a PC

  1. Enter Menu: Press the Front Panel SRQ.
  2. Nav: Press the button again to cycle through modes (M: REL -> M: TEMP -> M: DBM...).
  3. Selection (Hover): Stop pressing the button.
    • The display will animate dots (...) after 500ms.
    • After ~2.5 seconds of inactivity, the selected mode is activated.
  4. Sub-Menus: Some modes (like Temp) have sub-menus for sensor type and 2W/4W mode. Same cycle logic to select these.
  5. Exit: Press the SRQ button to exit back to initial mode (one we entered menu from).

Features

These can be triggered via the Menu or the serial commands below.

Relative and Statistics depend on the mode you enter the menu from, i.e. if you enter relative from DCV it saves your state and you get relative voltage, from 2W relative 2W etc.

++help

HP3478A Internal USB-GPIB 1.2.0

[GPIB Setup]
  ++addr <0-30>     Target Address
  ++auto <0-2>      0:Off, 1:Read-After-Write, 2:Query-Only
  ++read_tmo_ms <t> Timeout in ms
  ++eoi <0|1>       Assert hardware EOI on write end
  ++eos <0-3>       Write Term: 0:CRLF, 1:CR, 2:LF, 3:None
  ++eor <0-7>       Read Stop:  0:CRLF ... 7:EOI-Only
  ++eot_enable <B>  Append extra char to read output
  ++eot_char <dec>  The char to append

[System Configuration]
  ++config          List all configurable parameters
  ++get <name>      Get parameter value
  ++set <name> <v>  Set parameter value
  ++savecfg         Save config to flash
  ++ver             Firmware Version
  ++rst             System Reset

[GPIB Bus Operations]
  ++read            Read from target
  ++write <data>    Write to target
  ++trg             Device Trigger (GET)
  ++clr             Device Clear (SDC)
  ++dcl             Universal Device Clear (DCL)
  ++ifc             Interface Clear (Bus Reset)
  ++spoll [addr]    Serial Poll
  ++srq             Query SRQ Line (0=High/Idle, 1=Low/Active)
  ++loc             Local (Drop REN)
  ++llo             Local Lockout

[Internal HP3478A Features]
  ++cont, ++hold, ++rel, ++xohm
  ++dbm, ++diode, ++math, ++norm
  ++temp <l1> <l2>  Temperature sensor mode
  ++env [temp|hum]  Internal AHT20 Sensor
  ++disp <text>     Write text to LCD

There's also a configuration which can be saved using ++savecfg if you want to make it persist (it's saved to v203's "undocumented" flash).
Also see inc/config.h.

++config
my_addr: 0
dmm_addr: 18
target_addr: 18
eot_char: 0
eot_enable: 0
eoi_assert: 1
eos_mode: 0
eor_mode: 0
auto_read: 0
gpib_timeout_ms: 1200
poll_interval_ms: 100
env_sensor_read_interval_ms: 1000
dmm_recovery_delay_ms: 1000
usb_debounce_connect_ms: 50
usb_debounce_disconnect_ms: 200
usb_timeout_target_ms: 5
menu_dot_interval_ms: 500
menu_commit_delay_ms: 2400
menu_sublayer_delay_ms: 500
menu_debounce_ms: 100
menu_lockout_ms: 1000
stats_cycle_time_ms: 3000
cont_disp_update_ms: 150
diode_stable_ms: 20
buzzer_chirp_hz: 3000
buzzer_chirp_ms: 75
buzzer_cont_hz: 2500
rtd_a: 0.003908
rtd_b: -0.000001
rtd_r0: 1000.000000
cjc_fallback_temp: 22.000000
cjc_self_heating_offset: 4.000000
type_k_scale: 24390.240000
dbm_ref_z: 50.000000
diode_th_short: 0.050000
diode_th_open: 2.500000
autohold_threshold: 1.000000
autohold_change_req: 2.000000
autohold_min_val: 0.050000
cont_threshold_ohms: 10.000000
autohold_stable_count: 3
rel_stable_count: 3

i.e.

++set dbm_ref_z 60
++savecfg

Now your dBm feature will use 600 ohm ref instead of 50.

Known Issues

  1. I did NOT use the brain when routing the USBLC6. Either have to DNP the IC and jumper the data lines, or rely on the software hack to check USB SUSPEND to guess if the host is connected. I do the latter, works but meh.
  2. The buzzer is not on a hardware TIM pin. It's on a generic GPIO... This means it can't be hardware/timer PWMed. Instead, the firmware is firing a TIM IRQ thousands of times a second just to manually toggle the pin in the ISR..
  3. There is a microSD card footprint on the board. The fw does absolutely nothing with it. Data logging?
  4. The feature logic is a massive switch.. no VTable, no function pointer structs, it's quite messy
Description
HP3478A extension + USB-GPIB
Readme 11 MiB
Languages
C 99.5%
Makefile 0.5%