Commit 471562ec551e097a15fba641a50ead95743c9b39
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() |