pqass, you kind of beat me to it, but yes, that is the explanation!
I see in the console that the hp3478.exe program sends a "++eoi 0" command at startup, If I manually send "++eoi 1" after the program has started from another shell then a subsequent read of the cal setting succeeds.
hth David
Thank you for test that and the result is as I suspected. It confirms what the problem is.
In order to explain, it is necessary to consider the command sequence that is being sent to the meter in order to retrieve the cal data. To recap the command is:
W<addr>, where <addr> is a single byte containing the memory address of the nibble to be read. Mark that. This is binary data, not text. The data is then followed by CRLF as a "line terminator" because ++eos is set to its default setting.
Now here is the (now repeated) code from 0.49.14 which sends the data:
// Write the data string
for (int i = 0; i < dsize; i++) {
// If EOI asserting is on
if (AR488.eoi) {
// Send all characters
err = gpibWriteByte(data[i]);
} else {
// Otherwise ignore non-escaped CR, LF and ESC
if ((data[i] != CR) || (data[i] != LF) || (data[i] != ESC)) err = gpibWriteByte(data[i]);
}
if (err) break;
}
I have removed the debug bit for clarity. We have a loop processing the buffer called data which contains the characters to be sent. In this case, the buffer contains 2 bytes: 0x57 and the <addr> byte, the terminators having been removed at the parsing stage. Note that if ++eoi is set to 1 (EOI asserting is on), then all characters in the buffer are written to GPIB. This is followed by terminators being added on according to to ++eos setting with EOI being signaled on the last character sent.
However, if ++eoi is 0, then the 'else' clause comes into play. In this case, CR, LF and ESC characters are ignored. Why? Because if we are using CR, LF or CRLF as terminators without EOI, then we assume this to be a line of text which should not contain any additional terminator characters except those at its end. Nor should it contain an Escape (hex 0x27) character. However, if we take, for example address 10, we get the sequence: 0x57, 0x0A, then the 0x0A gets filtered but we still get the terminators added on according to the ++eos setting, so what actually gets sent is 0x57, 0x0D, 0x0A. The same would happen for address 13 and address 27.
The problem with the above line is that each condition had been or'ed by mistake. This means that only one of the three conditions needed to be met in order for the statement to evaluate to true. This would result in any unexpected terminators or escape character being sent regardless. The error was corrected in later code by and'ing the conditions and changing the line to:
if ((data[i] != CR) && (data[i] != LF) && (data[i] != ESC)) state = writeByte(data[i], NO_EOI);
Now, as intended, all three conditions must be met for the statement to evaluate to true and for the byte to be sent over GPIB. In short, the filtering now works as intended. The write command is slightly different in the restructured code but the effect is the same. Any unfiltered byte is written to the GPIB bus without using EOI and terminators are added at the end of the transmitted sequence.
The inadvertent consequence of fixing this error has resulted in the behavioral change that has been observed here. In 0.49.14, addresses 0x10, 0x13 and 0x27 will have been sent regardless so reading the cal data worked correctly. In later fixed versions, those characters are no longer sent in text mode so they are omitted and we get an erroneous reading for those addresses. Address 43 (corresponding to the + character) is not affected.
The question that now arises how to deal with this appropriately. On the one hand filtering could be removed so that all characters sent regardless. On the other hand, because we are dealing with bytes rather than ASCII text, ought we to be treating the data as binary and therefore having the HP3478A set to using EOI only as terminator and the AR488 set with ++eoi 1 and ++eos 3 (no terminator characters)? It looks like the meter ignores the trailing CRLF anyway, so perhaps ++eoi 1 and leaving the meter as is would be sufficient? I am open to suggestion and perhaps will also need to re-consider whether the filtering really is necessary or whether it is more of a hindrance and should be removed.