Commit 471562ec551e097a15fba641a50ead95743c9b39

Authored by jah
0 parents
Exists in master

first commit

Showing 1 changed file with 212 additions and 0 deletions Side-by-side Diff

AG53230A_freq_acq.py
... ... @@ -0,0 +1,212 @@
  1 +#!/usr/bin/env python
  2 +"""
  3 +Created on Mon Aug 19 15:52:23 2013
  4 +53230a_freq_acq.py
  5 +This program is made to communicate with the counter
  6 +Agilent 53230A.
  7 +@author: Serge Grop
  8 +"""
  9 +
  10 +import sys
  11 +import argparse
  12 +import socket
  13 +import time
  14 +import os
  15 +
  16 +DEVICE_IP = '192.168.0.74'
  17 +DEVICE_PORT = 5025 # Agilent have standardized on using port 5025 for SCPI
  18 +#socket services.
  19 +GATE_TIME = 1 # Gate time for one measurement
  20 +OFILENAME = '' #File header
  21 +IN_COUP = 'AC' # Input coupling
  22 +IN_IMP = '50' # Input impedance
  23 +IN_CH = '1' # Input channel
  24 +
  25 +#==============================================================================
  26 +def parse():
  27 + """ Specific parsing procedure for transfering data from 53230a
  28 + counter.
  29 + Return parsed arguments."""
  30 + parser = argparse.ArgumentParser( \
  31 + description='Acquire data from 53230a counter connected '\
  32 + 'through Ethernet.',
  33 + epilog='Example: \'53230a_acq_freq -o toto -c DC -i 1M \' configure ' \
  34 + '53230a_acq_freq with output file toto-"date".dat, input coupling DC '\
  35 + 'and input impedance 1 MOhms.')
  36 + parser.add_argument('-o', action='store', dest='ofile', \
  37 + default=OFILENAME,\
  38 + help='Output data filename (default '+OFILENAME+')')
  39 + parser.add_argument('-c', action='store', dest='input_coupling', \
  40 + default=IN_COUP,\
  41 + help='Input coupling AC or DC (default '+IN_COUP+')')
  42 + parser.add_argument('-i', action='store', dest='input_impedance', \
  43 + default=IN_IMP,\
  44 + help='Input impedance 50 or 1M (default '+IN_IMP+')')
  45 + parser.add_argument('-t', action='store', dest='gatetime', \
  46 + default=GATE_TIME,\
  47 + help='Gate time for one measurement'\
  48 + ' (default '+str(GATE_TIME)+' second)')
  49 + parser.add_argument('-ip', action='store', dest='ip', \
  50 + default=DEVICE_IP, help='IP address of the counter'\
  51 + ' (default '+str(DEVICE_IP)+')')
  52 + parser.add_argument('-p', action='store', dest='port', \
  53 + default=DEVICE_PORT, help='Port of the counter'\
  54 + ' (default '+str(DEVICE_PORT)+')')
  55 + parser.add_argument('-ch', action='store', dest='input_channel', \
  56 + default=IN_CH,\
  57 + help='Input channel (default '+IN_CH+')')
  58 + args = parser.parse_args()
  59 + return args
  60 +
  61 +#==============================================================================
  62 +def connect(ip,port):
  63 + """Creation of a socket to establish the communication
  64 + with 53230a counter"""
  65 + try:
  66 + print '53230a connection state at "%s" ?' % ip
  67 + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, \
  68 + socket.IPPROTO_TCP)
  69 + sock.settimeout(5) # Don't hang around forever
  70 + sock.connect((ip, port)) # Start the connection
  71 + print ' --> Connected'
  72 + return sock
  73 + except socket.error as ex: # Debugging
  74 + if 'Connection refused' in ex:
  75 + print 'Wrong PORT (Default PORT : 5025)\n', ex
  76 + print '\n --> Not connected'
  77 + elif 'No route to host' in ex:
  78 + print 'Wrong address (Default address : 169.254.2.30)\n', ex
  79 + print '\n --> Not connected'
  80 + else:
  81 + print ex+'\n'+' --> Not connected'
  82 + sys.exit()
  83 +
  84 +#==============================================================================
  85 +def init_53230a(sock, coupling, impedance, gatetime, channel):
  86 + """Initialization of the counter"""
  87 + g_time = 'SENS:FREQ:GATE:TIME '+str(gatetime)+'\n' # Definition of
  88 + #the string to initialize the gate time
  89 + sock.send("*RST\n") #Main reset
  90 + sock.send("DISP:DIG:MASK:AUTO OFF\n") # Disable display autodigits
  91 + if impedance == '50':
  92 + sock.send("INP"+channel+":IMP 50\n") # Input 1 impedance : 50 Ohms
  93 + else:
  94 + sock.send("INP"+channel+":IMP 1.0E6\n") # Input 1 impedance : 1 MOhms
  95 + if coupling == 'AC':
  96 + sock.send("INP"+channel+":COUP AC\n") # Input 1 coupling mode AC
  97 + else:
  98 + sock.send("INP"+channel+":COUP DC\n") # Input 1 coupling mode DC
  99 + sock.send("SYST:TIM INF\n") # Timeout infiny to avoid problem if the gate
  100 + #is too long
  101 + sock.send("CONF:FREQ (@"+channel+")\n") # Signal on input 1
  102 + sock.send("SAMP:COUN 1E6\n") # Number of samples : 1 million (max)
  103 + # the number of samples in continous mode is limited
  104 + # by the size of the memory
  105 + sock.send("SENS:FREQ:MODE CONT\n") # Continuous mode (gap free) enable
  106 + sock.send("SENS:FREQ:GATE:SOUR TIME\n") # The gate source is TIME
  107 + sock.send(g_time) # Gate time : 1 second
  108 + sock.send("TRIG:SOUR IMM\n") # Because of the continuous mode
  109 +
  110 +#==============================================================================
  111 +def check_error(sock):
  112 + """Used for debugging during the development of the program,
  113 + not used anymore"""
  114 + sock.send('SYST:ERR?\n')
  115 + error = None
  116 + try:
  117 + error = sock.recv(128)
  118 + except socket.timeout:
  119 + error = ""
  120 + print error
  121 +
  122 +#==============================================================================
  123 +def read_buffer(sock):
  124 + """Read the data returned by the counter 53230a until the '\n'"""
  125 + ans = ''
  126 + nb_data_list = []
  127 + nb_data = ''
  128 + while ans != '\n':
  129 + ans = sock.recv(1)
  130 + nb_data_list.append(ans) # Return the number of data
  131 + list_size = len(nb_data_list)
  132 + for j in range (0, list_size):
  133 + nb_data = nb_data+nb_data_list[j]
  134 + return(nb_data) # Return the number of data in the memory
  135 +
  136 +
  137 +#==============================================================================
  138 +def acqu_53230a(i, sock, data_file, gatetime):
  139 + """Frequency acquisition and stockage in a file"""
  140 + sock.send("INIT:IMM\n") # Start the acquisition immediatly
  141 + print "Waiting for the first acquisition"
  142 + while True:
  143 + try:
  144 + sock.send("DATA:POIN?\n") # Ask the number of data in the memory
  145 + nb_data = read_buffer(sock) # Number of data available (string)
  146 + #nb_data_int = int(nb_data) # Convert in integer
  147 + #epoch time
  148 + epoch = time.time()
  149 + #MJD time
  150 + mjd = epoch / 86400.0 + 40587
  151 + if nb_data != '+0\n': # There is a minimum of one data to read
  152 + try:
  153 + sock.send("DATA:REM? 1\n") # Put the data in the buffer and
  154 + # clear the memory
  155 + freq = sock.recv(24) # Read the buffer
  156 + freq = freq[:22] # Remove \n from the string
  157 + freq = freq.replace("+", "")
  158 + freq = freq.replace("E", "e")
  159 + freq = freq.replace("\t", "")
  160 + sample = "%f\t%f\t%s\n" % (epoch, mjd, freq)
  161 + data_file.write(sample) # Write in a file
  162 + print sample
  163 + except Exception as ex:
  164 + print "Exception during counter data reading: " + str(ex)
  165 + else:
  166 + #print "Waiting for the next acquisition"
  167 + #pass
  168 + time.sleep(int(gatetime)*0.1) # Wait the time of the gate time
  169 + #to avoid too much check of the memory
  170 + except KeyboardInterrupt:
  171 + break # To stop the loop in a clean way
  172 +
  173 +#==============================================================================
  174 +def main():
  175 + """Main program"""
  176 + args = parse() # Parse command line
  177 + ofile = args.ofile # Data output file
  178 + ip = args.ip
  179 + coup = args.input_coupling
  180 + imp = args.input_impedance
  181 + gate_time = args.gatetime
  182 + port = args.port
  183 + ch = args.input_channel
  184 + i = 0 #Init the number of sample
  185 + sock = connect(ip, port)
  186 + filename = time.strftime("%Y%m%d-%H%M%S", \
  187 + time.gmtime(time.time()))+'-AG53230A_cont.dat' # Define the name of the file :
  188 + # "experiment"+"date and hour".dat
  189 + data_file = open(filename, 'wr', 0) # Create the file in write and read
  190 + # mode, the file is updated at each sample
  191 + #data_file.write('#Number of the sample-frequency in Hz-'\
  192 + #'date when the data is computed\n')
  193 + init_53230a(sock, coup, imp, gate_time, ch)
  194 + acqu_53230a(i, sock, data_file, gate_time)
  195 + sock.close()
  196 + print '\n --> Disconnected'
  197 + data_file.close()
  198 + try:
  199 + ans = raw_input('Would you like to keep this datafile'\
  200 + '(y/n : default y)?\t')
  201 + if ans == 'n':
  202 + os.remove(filename)
  203 + print '\n', filename, 'removed\n'
  204 + else:
  205 + print '\n', filename, 'saved\n'
  206 + except Exception as ex:
  207 + print 'Oups '+str(ex)
  208 + print 'Program ending\n'
  209 +
  210 +#==============================================================================
  211 +if __name__ == "__main__":
  212 + main()