# HP3478A Internal USB-GPIB Extension An internal extension board for the HP3478A Multimeter. USB-CDC-GPIB bridge (Prologix-style) and an internal feature controller. It enumerates as a standard serial device (e.g., /dev/ttyACM0 or COMx). PCB [here](https://git.ayau.me/mira/mhardware/src/branch/master/hp3478a-ch32-ext) ## 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). ## Extended Feature Modes These can be triggered via the Menu or the serial commands below. Although sub-menu features probably don't work through GPIB commands. 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. | Feature | Command | Description | | :-------------- | :-------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Continuity** | `++cont` | Fast, latched continuity beeper (2W Ohm, R0: 30 Ohm Range, N3: 3.5 Digits) | | **Temperature** | `++temp` | Supports **PT1000**, **Type K** (via shit CJC... because the AHT20 is near the transformer :)), and **Thermistors** (Generic 10k/50k/100k & YSI 44000 series) | | **Relative** | `++rel` | Set NULL/0 offset | | **dBm** | `++dbm` | Power measurement calculated against 50Ω reference | | **Diode** | `++diode` | Diode test with 2.5V open circuit voltage and audible latch | | **Ext Ohms** | `++xohm` | Measures high resistance (>30MΩ) by calculating against internal 10MΩ parallel resistance | | **Statistics** | `++math` | Cycles display between Live / Min / Max / Avg | | **Environment** | `++env` | Reads internal AHT20 sensor (Temp/Humidity) | | **Display** | `++disp` | write custom string to LCD | | **Normal** | `++norm` | Resets DMM to standard DC Volts state | ## USB-GPIB Command Reference Commands start with `++`. Any other text is sent directly to the GPIB bus. ### Controller Configuration | Command | Arguments | Description | | :--------------- | :-------- | :---------------------------------------------------- | | `++ver` | | Get Firmware Version | | `++help` / `++?` | | List available commands | | `++rst` | | Reset the controller | | `++addr` | `0-30` | Set target GPIB address (Default: 18) | | `++tmo` | `ms` | Set USB-to-GPIB read timeout (alias: `++read_tmo_ms`) | there's also `++savecfg` and `++mode` to fake prologix compliance ### Protocol & Formatting | Command | Arguments | Description | | :------------- | :-------- | :------------------------------------------------------------------- | | `++auto` | `0-2` | **0**: Off, **1**: Read-after-Write, **2**: Query-Only (ends in `?`) | | `++eoi` | `0`\|`1` | Assert hardware EOI line on write end | | `++eos` | `0-3` | Append to Write: 0:CRLF, 1:CR, 2:LF, 3:None | | `++eor` | `0-7` | Stop Read on: 0:CRLF ... 7:EOI-Only | | `++eot_enable` | `0`\|`1` | Append character to USB output stream? | | `++eot_char` | `dec` | The decimal char to append (e.g., 10 for `\n`) | ### Bus Management | Command | Description | | :-------- | :------------------------------------------------ | | `++read` | Read data from target immediately | | `++write` | Write data to target manually | | `++trg` | Issue Group Execute Trigger (GET) | | `++clr` | Selected Device Clear (SDC) | | `++dcl` | Universal Device Clear (resets entire bus) | | `++spoll` | Serial Poll target (returns Status Byte) | | `++srq` | Query SRQ Line status (0=Idle, 1=Active) | | `++stat` | Print controller internal status (Addr, Tmo, etc) | ### Lower Level Control | Command | Description | | :------ | :------------------------------------------ | | `++loc` | Go To Local (Release Remote Lock) | | `++gtl` | Send "Go To Local" GPIB message | | `++llo` | Local Lockout (Disable front panel buttons) | | `++ren` | Toggle Remote Enable line | | `++ifc` | Interface Clear (Hard Bus Reset) | ## 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