Commit 471562ec551e097a15fba641a50ead95743c9b39
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': |