Commit 471562ec551e097a15fba641a50ead95743c9b39

Authored by jah
0 parents
Exists in master

first commit

Showing 1 changed file with 212 additions and 0 deletions Inline Diff

AG53230A_freq_acq.py
File was created 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':