In a different topic, I developed a replacement board for a Keithley 197A Voltmeter (see
https://www.eevblog.com/forum/projects/replacement-display-board-for-keithley-197a/) adding some new features such as bluetooth logging. Some users suggested that I should use the internal IEEE interface which allows some additional measure of control.
Armed with a AR488 USB till IEEE-488 converter and a Keithley Model 1972 IEEE-488 interface card (which rikkitikkitavi kindly loaned to me - many thanks!), I setup to reverse engineer the protocol used to comunicate with the card and create an Arduino library to control the voltmeter.
If you are in a rush to try it out, you can download the library from here:
https://github.com/alx2009/K197ControlA more detailed protocol specification is also included with the library.
In this topic instead I will document how I reverse engineer the protocol.
First I had a look at how the card connects to the voltmeter. I have the schematic of the K197 so that part is simple. The IEEE connector (J1008) has 6 pins. Four of them are power pins, two are connected to the K197 PIA IC. I could not find the schematic of the 1972 card but following the copper traces shows that pin 3 of the IEEE connector is an output and pin 4 is an input (from the perspective of the IEEE card, see also schematic below).

The next step was to connect a logic analyzer. I was kind of expecting a well known serial protocol, but what I found was more interesting.
The first thing I noticed is that when the card is present, the voltmeter send a short burst of data every 0.3s. Since this is also the measurement rate, I guessed the voltmeter was sending the measurement results to the card. See first row in the picture below.

Looking at one burst (see middle row), I then guessed that the short pulses represented 0 bits, while the long pulses represented 1 bits. Luckily both of my initial guesses turned out to be right.
I now fed a stable source to the voltmeter and started to change one parameter at a time (range, sign, relative, etc.). It turns out the measurement result is always sent inside a fixed data structure. Comparing the traces it was easy to identify the bits corresponding to the range, sign, unit, etc. Decoding the way the value of the measurement is encoded required a bit more work. It was clear that the rightmost bits of the data burst were proportional to the absolute value of the measurement. However I was a bit puzzled that the last bits were changing all the times, even as the display value was stable.
It turns out that the voltmeter is sending data with a higher resolution compared to what is displayed. It is sending a 21 bit binary value, which must correspond to an internal counter (see here
https://github.com/alx2009/K197Control/blob/main/K197control_protocol_specification.mdfor details ).
The above can be deduced simply looking at the signal in the direction from the voltmeter to the card. In the other direction the card was sending a short pulse for every bit received. Those looked like acknowledgement pulses to me, and indeed they are (see bottom row of the trace, how the card wait until the acknowledge before sending another bit?).
So far I didn't really use any IEE488 commands. I then started to issue commands on the IEEE bus via the AR488 while I was tracing the internal interface. I was expecting to see the same protocol used in the other direction, and this is what happens.
However, I was expecting a half duplex communication, but I was surprised that the communication is in fact full duplex. This is achieved because when the IEEE card acknowledges the first bit, it will also encode a bit in the other direction (short pulse for a zero, long pulse for a one). Then the second data bit from the voltmeter also acknowledge the first bit from the card, and so on...

The way the data values and acknowledgments are intertwinned really fascinated me, so in the protocol specification I called the protocol gemini (latin for twins, like the Gemini constellation).
Analyzing the data structre more in detail, it was clear that there is a framing structure used in both direction to synchronize the two peers. I don't go into details here because everything is documented in the specification.
At this point it was time to write some code to see if my assumptions were enough to implement the protocol. And it turns out that it does. Here is the test setup:

The library is a proof of concept. The example program can retrieve measurement data and control the voltmeter more or less in the same way as via IEEE-488, including for example:
- Set the range (supported only in volt and Ohm, same as the IEE-488 card)
- toggle from Volt to Db
- toggle from absolute to relative measurement
Now, is it useful? I think the best use for this library would be to connect the voltmeter to a PC via bluetooth serial. The example provided can already do that (simply adding a bluetooth module and using e.g. an Arduino micro).
I do not think however that it is useful as a display intrface (e.g. to replace the display, as my other project does). The reason is that the IEEE 488 interface lacks some of the annunciators that are present in the display interface.
On the other end, the IEEE interface does provide more resolution. I intend to do a few more tests to see if this additional resolution could lead to some advantages (I am aware of course that the precision is not going to increase, as that is set by the voltage reference).