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