In [1]:
from datetime import date, datetime, timedelta
import sys, time
import visa
import math
# if not using IPython leave out the next line.
%matplotlib inline      
import matplotlib.pyplot as plt
import numpy as np
In [2]:
def init_instr(dmm):
    dmm.write('*CLS')
    dmm.write('*RST')
    dmm.write('INP:IMP:AUTO ON')
    dmm.write('DISP:STAT ON')
    temp = round(float(dmm.query('SYST:TEMP?')), 2)
    print('\nStart temperature: {0:.2f} deg C.\n'.format(temp))
    
def meas(dmm, ran, nplc, samples): 
    dmm.write('CONF:VOLT:DC {0}'.format(ran))
    dmm.write('VOLT:DC:NPLC {0}'.format(nplc))    
    dmm.write('TRIG:SOUR BUS')
    dmm.write('SAMP:COUN {0}'.format(str(samples)))
    dmm.write(':INIT')
    dmm.write('*TRG')
    dmm.write('*WAI')
    values = dmm.query('FETC?').split(',') 
    list_of_floats = list(map(float, values))
    return np.array(list_of_floats, dtype = 'float')
 
def reset_instr(dmm):
    temp = round(float(dmm.query('SYST:TEMP?')), 2)
    print('\nEnd temperature: {0:.2f} deg C.\n'.format(temp))
    dmm.write('*CLS')
    dmm.write('*RST')
    dmm.write('SYST:LOC')
    
def meas_loop(dmm, count_in_plc):  
    print(75*'=')
    print(' Range    NPLC   Mean [uV]  Std. dev. [uV]  Samples   PPM of R')     
    ppm_of_range = [] 
    
    for r in (0.1, 1, 10, 100, 1000):    
        por = []
        ppm_of_range.append(por)
        print(75*'-')
        
        for nplc in (0.02, 0.06, 0.2, 1, 10, 100):  
            samples=int(count_in_plc/nplc)
            data = meas(dmm, ran=str(r), nplc=str(nplc), samples=samples)
                                    
            mean = np.mean(data)*1e6
            std = np.std(data)*1e6
        
            ppm_range = std/r
            por.append(ppm_range)
            print('{0:6.1f} {1:7.2f} {2:11.2f} {3:15.2f} {4:8} {5:10.3f}'.format(r, nplc, mean, std, samples, ppm_range))
   
    print(75*'=')  
    return ppm_of_range     
In [3]:
def plot(data, count_in_plc):
    n = (0.02, 0.06, 0.2, 1, 10, 100)
    fig, ax = plt.subplots(1, 1, figsize=(14, 7))  
    ax.grid(True)
    for i in range(5):
        ax.loglog(n, data[i], linewidth=0.5)  
    ax.grid(True, which="both")   # ls="-"
    ax.set_title('Keysight 34470A - Noise floor, zero volts input, auto zero on, num_of_plc={0}'.format(count_in_plc))
    ax.set_xlabel('NPLC')
    ax.set_ylabel('Noise Std. dev. [ppm of range]')
    
def main(count_in_plc):        
    try:
        rm = visa.ResourceManager()     
        resources = rm.list_resources()  
        print(resources)   
        dmm = rm.open_resource('TCPIP0::K-000000-00000::inst0::INSTR')
        dmm.timeout = 10000000       
        
        try: 
            with dmm.ignore_warning(visa.constants.VI_SUCCESS_MAX_CNT):
                init_instr(dmm)  
                data = meas_loop(dmm, count_in_plc)   
                reset_instr(dmm)
                plot(data, count_in_plc)
        except Exception as err:
            print(err)
        finally:
            dmm.close()
         
    except Exception as err:
        print('Visa error: '+str(err))
In [4]:
main(count_in_plc=500)
('TCPIP0::192.168.2.120::inst0::INSTR', 'TCPIP0::K-000000-00000::hislip0::INSTR', 'TCPIP0::K-000000-00000::inst0::INSTR', 'ASRL4::INSTR', 'ASRL8::INSTR')

Start temperature: 27.19 deg C.

===========================================================================
 Range    NPLC   Mean [uV]  Std. dev. [uV]  Samples   PPM of R
---------------------------------------------------------------------------
   0.1    0.02       -0.46            1.71    25000     17.139
   0.1    0.06       -0.34            1.41     8333     14.108
   0.1    0.20       -0.27            1.21     2500     12.096
   0.1    1.00       -0.17            0.24      500      2.364
   0.1   10.00       -0.06            0.07       50      0.700
   0.1  100.00       -0.07            0.06        5      0.604
---------------------------------------------------------------------------
   1.0    0.02       -0.23            2.80    25000      2.803
   1.0    0.06       -0.15            1.67     8333      1.673
   1.0    0.20       -0.10            1.29     2500      1.290
   1.0    1.00       -0.22            0.35      500      0.354
   1.0   10.00       -0.19            0.12       50      0.120
   1.0  100.00       -0.14            0.06        5      0.057
---------------------------------------------------------------------------
  10.0    0.02       -0.06           19.34    25000      1.934
  10.0    0.06       -0.17            6.82     8333      0.682
  10.0    0.20       -0.37            3.48     2500      0.348
  10.0    1.00       -0.26            1.26      500      0.126
  10.0   10.00       -0.25            0.40       50      0.040
  10.0  100.00       -0.31            0.10        5      0.010
---------------------------------------------------------------------------
 100.0    0.02      -26.59          363.06    25000      3.631
 100.0    0.06      -23.85          242.32     8333      2.423
 100.0    0.20      -27.59          205.33     2500      2.053
 100.0    1.00      -24.91           42.55      500      0.425
 100.0   10.00      -28.62           12.32       50      0.123
 100.0  100.00      -20.68            3.74        5      0.037
---------------------------------------------------------------------------
1000.0    0.02      -15.10         1991.97    25000      1.992
1000.0    0.06       -4.11          700.86     8333      0.701
1000.0    0.20      -12.24          371.05     2500      0.371
1000.0    1.00       -2.07          124.08      500      0.124
1000.0   10.00      -14.56           40.31       50      0.040
1000.0  100.00      -18.32           17.09        5      0.017
===========================================================================

End temperature: 27.09 deg C.

In [ ]:
# this loop takes a lot of time to complete ;-)
for plc in (100, 200, 500, 1000, 2000, 5000, 10000, 50000, 100000):
    main(plc)