Saturday, December 16, 2017

Save and Restore HP 3478A Calibration Data with Matlab

The HP 3478A is a very nice 5½ digit auto-ranging digital multimeter, first marketed by Hewlett-Packard in the 1980's.

A few years ago I purchased one to log voltages to a computer for some experiments I was performing -- the 3478A has a GPIB interface that allows a computer to control the instrument (I use a National Instruments GPIB-USB-B dongle to connect the 3478A to my laptop's USB port).

I recently found a second one at a swapmeet for a very inexpensive price, and I discovered one reason why it was so cheap when I returned home -- when I powered it up, the first message it displayed was "UNCALIBRATED".  (I also discovered that the DC and AC amp functions were broken, too, which might have been the better reason for its low price).

The broken Amps functions I decided to leave for another time, and instead I decided to tackle the calibration problem.

The cal procedure is straightforward (read the manual before attempting), as long as you have appropriate equipment.  But first I needed to answer the question -- which functions and ranges were out of calibration?  I wanted to avoid recalibrating the entire instrument.

Discovering which ranges are out of cal is quite simple -- if the "CAL" annunciator on the LCD is visible and blinking, that range (for the function selected) is out of calibration.  If no "CAL" is seen, then that range is in calibration.

 (Click on image to enlarge)

Stepping through all ranges of all functions, I discovered that the CAL annunciator was present for the 30 mV and 300 mV DCV ranges and for the 3 Meg Ohm Resistance range.

Using an old Power Designs 5020 Precision DC Source and my HP 34401A as references, I performed the calibration procedure (per the manual) for the 30 mV and 300 mV DCV ranges.

I calibrated the 3 Mohm range with a GenRad Decade Resistor box set to 1.000000 Meg ohms.

After finishing these calibration steps I cycled power on the 3478A -- hurray! the "UNCALIBRATED" message had disappeared and in its place I saw the "SELF TEST OK" message.

This exercise in calibration got me wondering -- how might a 3478A lose its calibration?

The obvious way is if a user attempts a calibration without knowing what they are doing.  For this reason, most cal labs will place a sticker over the front panel's CAL ENABLE switch (see the sticker on the panel in first image of this blog post, above) to keep knob-twisters and button-pushers from inadvertently initiating a calibration cycle.

But there's another way for it to lose its calibration data...

The HP 3478A stores its calibration data in SRAM.  And if power to this memory is lost, its contents (and thus the calibration data) is lost.

To keep this SRAM powered when AC power has been turned off, the 3478A contains an internal 3.0 volt battery whose sole purpose is to keep power applied to this SRAM when the instrument is powered off.  (The SRAM is powered by the diode-or'd combination of this battery and the instrument's 5V DC supply (the latter only there when the instrument is on)).

So, if this internal battery goes dead (while the unit is OFF), a 3478A will lose its calibration data.  Both of my units were manufactured over 30 years ago.  Both of their batteries are original, and both still read 3.0 volts.  But how much longer will they last?  I have no idea.

If one would like to proactively replace this battery, remember that the SRAM must always be powered while the battery is being replaced.  If the SRAM loses power for any reason during this operation, you've lost your calibration data.

That's a sobering thought!

Wouldn't it be nice to somehow first back-up that calibration data to a computer and then, if for whatever reason the meter loses this data, restore it from that backed up file?

The manual does not mention any such GPIB commands, but they exist.  They are just undocumented.  The 'W' command reads the SRAM via the GPIB interface, and 'X' command writes to the SRAM via GPIB.  (A great investigation and discussion of these two commands is here).

I mentioned this to Dick Benson, W1QG, who is a Matlab guru and who had just written a Matlab logging program for the 3478A, and he took a cut at the Matlab code to read the SRAM.

Using his 'SRAM-read' code, I wrote Matlab code to write data back into the SRAM.

Both of these Matlab code-blocks are below...

Below is the Matlab code to save an HP 3478A's calibration data to a file on a computer.

(Note: to better view the code, copy and paste it into an app with a wider page size, e.g. Word, Notepad, or...Matlab).

% Authors: W1QG/K6JCA

% *** Read 3478a Cal Data ***
% This Matlab script downloads the calibration data from the
% HP 3478A's SRAM and writes it to a file.
% Note: this script also requires the "Instrument Control" toolbox.

% To run, first 'uncomment' the appropriate gpib() routine, below,
% based upon GPIB dongle that connects PC to the HP 3478A.

  %HP_3478a = gpib('AGILENT', 7, 23);  % Use if Agilent dongle
   HP_3478a = gpib('ni', 0, 23);       % Use if NI GPIB-USB-B dongle


   for k=1:256 
      cmd=uint8(['W',k-1,'\n']); % W, address, newline
      fwrite(HP_3478a,cmd);      % fwrite writes 8 bit unsigned integers.
      value(k)=fscanf(HP_3478a); % read the value addressed.

% Select the appropriate file into which to save the data by
% "uncommenting" the appropriate save command, below.
 % save('HP_3478a_Cal_Data_SN_2301A','value');
 % save('HP_3478a_Cal_Data_SN_2520A','value');

% reshape and transpose for easy reading

   val_table = reshape(value,[256/16,16])'   % transpose = '

And here is the Matlab code to write calibration data from a file back into an HP 3478A:

% Authors: W1QG/K6JCA

% *** Write 3478a Cal Data ***
% (Note, this script also requires the "Instrument Control" toolbox.)

%                  !!! DANGER  DANGER  DANGER !!! 
% This Matlab script overwrites the HP 3478A's calibration data stored
% in the meter's SRAM.  Be VERY CAREFUL when using it, or you might 
% forever lose your meter's calibration data!!!
% In fact, I would recommend: DO NOT USE IT unless the SRAM contents are
% already screwed up.

% NOTE:  Before running, turn the front panel's CAL ENABLED Switch so that
%        its slot is vertical.  This enables the SRAM write signal.
%        And don't forget, when finished, to turn the switch so that its
%        slot has been returned back to a horizontal orientation.

% To run, first 'uncomment' the appropriate gpib() routine, 
% based upon GPIB dongle that connects PC to the HP 3478A.
  %HP_3478a = gpib('AGILENT', 7, 23);  % Use if Agilent dongle
   HP_3478a = gpib('ni', 0, 23);       % Use if NI GPIB-USB-B dongle

% Now, select which file containing calibration data (created previously
% using the Read_Cal_Data script) will be loaded into the 3478A's SRAM by 
% *uncommenting* the appropriate statement, below.
%   load('HP_3478a_Cal_Data_SN_2520A','value');
%   load('HP_3478a_Cal_Data_SN_2301A','value');
% ********************************************

% Display the data from the just-loaded file...
   input_val_table = reshape(value,[256/16,16])' % no ending ';' will print
                                                 % the table in the Command
                                                 % Window

% Now, write this data into the instrument, one SRAM address at a time,
% by sequential writing the following triplet of bytes for each SRAM
% address:
%    0x58    -- 'X'  (The "write" command)
%    Address -- 0x00 to 0xFF
%    Data    -- any value between 0x40 and 0x4F.
   for k=1:256
      cmd=uint8(['X',k-1,value(k)]); % X, address, value (3 unsigned ints).
      fwrite(HP_3478a,cmd);        % fwrite writes 8 bit unsigned integers.

% And, to verify the write operation, read back the SRAM's contents.

   for k=1:256
      cmd=uint8(['W',k-1,'\n']); % W, address, newline
      fwrite(HP_3478a,cmd);      % fwrite writes 8 bit unsigned integers.
   % reshape for easy reading 
   val_table = reshape(value,[256/16,16])' % note that ' transposes the
                                           % matrix


Note:  be very careful using this code.  Before launching it, make sure you have backed up the calibration data from the 3478A to your computer so that, if you accidentally nuke the SRAM, you can recover!

And I will add -- I have only tested this code on one 3478A (and that was the meter that gave me the "uncalibrated" error message).  Given this code's potential to wreak havoc with the calibration SRAM, I would recommend running it only when your meter's SRAM calibration data has been lost or corrupted.  (Make sure you back up this data, though, before loss or corruption occurs!)

Note:  to write data into the 3478A's calibration SRAM, the CAL ENABLE switch must be rotated so that its slot is oriented vertically.  (It is shown in its horizontal, cal disabled, position, below).

This switch enables or disables writing to the calibration data SRAM.  But it is not read by the processor.  The processor indirectly verifies if calibration is enabled or disabled by alternating writes of 0x0 and 0xF to Address 0 of this SRAM.  If the data does not change, then the processor infers that the CAL ENABLE switch is disabled.  Otherwise, if the data changes, the processor infers that the calibration is enabled.

Note, when calibration is finished, be sure to rotate the CAL ENABLE switch back to its disabled position.

Here's the schematic.  Note that the CAL ENABLE switch only gates the write signal to the SRAM.  It is not read by the processor.


First, I had already read the data from my recently-calibrated 3478A and stored it in a file (using the Matlab "Read" routine, above).  This first test would be to write this file to the 3478A's SRAM (making sure first that the CAL ENABLE switch is in its "enabled" vertical orientation).

With the exception of the first data byte (which can toggle between 0x40 and 0x4F if CAL is ENABLED and the 3478A is alternatively writing 0x0 and 0xF to it (see explanation above)), the data is identical.  (Note, it would be identical, too, if I ran the same Write code but forgot to turn the CAL ENABLE switch to its enabled position).

Next, I read the data from my second 3478A and stored it in a file (using the Read code, above).  I then reconnected my GPIB dongle to my recently-calibrated 3478A, made sure its CAL ENABLE switch was in the disabled position, and attempted to write  my second 3478A's data file into the recently-calibrated 3478A using the Write routine.

Here are the results:

The SRAM data did not update!  Good -- because the meter's CAL ENABLE switch was disabled.

For my third test, I rotated the CAL ENABLE switch on this same 3478A to its enabled position and reran the test above.  This time, the SRAM's data changed to be that of my second 3478A:

After this write I checked a few of the DC voltage ranges and verified that the 3478A still worked (although its readings were, not surprisingly, off -- after all, it now was using a different unit's CAL data).

And finally, I rewrote the 3478's original CAL data into its SRAM and finished by turning the CAL ENABLE switch to its disabled (horizontal) position:

This was not an extensive verification test, but it did verify, for me, that I could both read and write the 3478A's calibration SRAM, and that the meter still operated properly after performing the write.


1.  The Matlab code (listed above) requires the "Instrument Control" toolbox to run (to access the  gpib() function).

2.  The 3478A's calibration SRAM is 4 bits wide, but the data readouts above imply that there are five bits (or more).  E.g. the ASCII character '@' is 0x40, and ASCII 'O' is 0x4F.  The SRAM actually contains, in these two cases, 0x0 and 0xF, and the DMM's software OR's this least-significant nybble with 0x40 to create an 8-bit data byte for transmission via the GPIB interface.

3.  HP 3468A/B DMM's also have internal "keep-alive" batteries for their calibration SRAM.  Unfortunately, their instrument-control interfaces are not GPIB (also known as HP-IB), but instead they are the much less common HP-IL interface.  It might be possible to interface them to GPIB controllers with an HP 82169A HP-IL/HP-IB Interface module, should someone like to attempt it.  (Otherwise, if you have an HP 3468A/B, you might want to leave it on!)

4.  PDFs of 3478 Operation and Service manuals can be found on the Keysight site:

Standard Caveat:

I might have made a mistake in my code, designs, equations, schematics, models, etc.  If anything looks confusing or wrong to you, please feel free to comment below or send me an email.

Also, I will note:

This information is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

No comments: