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! |