philpem.me.uk electronics :: testgear :: hameg hm8130-3  

Hameg HM8130-3 binary protocol observations

The Hameg HM8130-3 is a fairly advanced arbitrary function generator. Its maximum output frequency is around 20MHz, with an output voltage of +/- 20V, and a programmable offset. Of course, there is a catch.

It doesn't work on Linux.

More specifically, it uses a weird binary command set that Hameg either can't or won't document. There is an ASCII-ish command set documented in the manual, but this doesn't provide any way to change the arbitrary waveform data without powering down the HM8130, flipping a DIP switch, then powering it back up again.

I decided this transgression had to be resolved in the Linux Way (tm)... That is to say, I reverse engineered it.

It turns out the comms protocol isn't that difficult to figure out -- it seems to rely on sending BCD data back and forth to set the various parameters. What is difficult to figure out is how the 'set' commands work... Anyway, without further ado, this is a quick guide to what I've figured out thus far:


Communications parameters: 9600 Baud, 8 data bits, no parity, one stop bit

Data is sent in packets -- these seem to consist of a single command byte, a variable number of data bytes, and a 0xFF byte (a terminator?) Responses seem to be 8 bytes in a similar format, i.e. 6 bytes of actual data.

Initialise -- 0x40 0xFF

Response data
10 FF 20 ww dd dd nn FF
30 ff ff fa aa mm 81 FF
30 01 00 0a aa 20 81 FF
30 25 00 0a aa 20 81 FF
30 ff ff fa aa mm 81 FF

Initialises the instrument, locks the front panel and returns a data block containing the current instrument status.

Data parameters

Data symbol Assumed function
dd dd Display mode -- first byte seems to be input mode, second
seems to be display mode. Known values are:
First byte -- input mode
* 0x08: Frequency entry
* 0x04: Pulse Width entry
* 0x02: Offset entry
* 0x01: Amplitude entry
Second byte -- display mode (left, right)
* 0x09: Frequency, Amplitude
* 0x05: Pulse Width, Amplitude
* 0x0A: Frequency, Offset
Combinations that have been seen in this block are:
* 0x08 0x09
* 0x04 0x05
* 0x02 0x0A
* 0x01 0x09
ff ff f Frequency, digits. Encoded in BCD form, i.e.
98 76 5 = 98765. Possibly 1 extra digit present?
mm Frequency multiplier / exponent. It looks like the most
significant nibble is the decimal point position, and the
least significant nibble is the exponent. That is to say:
freq_hertz = (freq_digits * (10^exponent)) / 100
So you don't really need the DP select bits for frequency
mode. Pulse mode is a little weirder and needs more
investigation.
Frequency mode
* 0x20 123.45 Hz
* 0x81 1.2345 kHz
* 0x42 12.345 kHz
* 0x23 123.45 kHz
* 0x84 1.2345 MHz
* 0x45 12.345 MHz
Pulse width mode
* 0x11 nn.n microseconds
* 0x13 n.n microseconds
ww Output waveform type and flags
The LSN stores the waveform type and one flag:
* 0x0 Arbitrary
* 0x1 Pulse
* 0x2 Rectangular
* 0x3 Sine
* 0x4 Triangular
* 0x5 Sawtooth
* 0x8 Inverted output (OR with waveform type)
The MSN stores the output mode and flags:
* 0x0 Continuous
* 0x1 Gated
* 0x2 Triggered (by external trigger input)
* 0x4 Offset enabled (OR with output mode)
* 0x8 Output enabled (OR with output mode)
nn Arbitrary waveform bank/bin number
* 0x00 P-0
* 0x01 P-1
* ...
* 0x06 P-6
* 0x07 P-7
a aa Waveform amplitude -- aa.a format (MS nibble of byte is
units, LS nibble is tenths of units). If the generator is
in Offset Entry mode, this is the Voltage Offset in aa.a
format.
Note that there appears to be no way to tell if an offset
voltage is negative or positive!