Blame view

AG53230A_freq_acq.py 8.6 KB
471562ec5   jah   first commit
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
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
  #!/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)
  ', ex
              print '
    --> Not connected'
          elif 'No route to host' in ex:
              print 'Wrong address (Default address : 169.254.2.30)
  ', ex
              print '
    --> Not connected'
          else:
              print ex+'
  '+'  --> Not connected'
          sys.exit()
  
  #==============================================================================
  def init_53230a(sock, coupling, impedance, gatetime, channel):
      """Initialization of the counter"""
      g_time = 'SENS:FREQ:GATE:TIME '+str(gatetime)+'
  ' # Definition of
      #the string to initialize the gate time
      sock.send("*RST
  ") #Main reset
      sock.send("DISP:DIG:MASK:AUTO OFF
  ") # Disable display autodigits
      if impedance == '50':
          sock.send("INP"+channel+":IMP 50
  ") # Input 1 impedance : 50 Ohms
      else:
          sock.send("INP"+channel+":IMP 1.0E6
  ") # Input 1 impedance : 1 MOhms
      if coupling == 'AC':
          sock.send("INP"+channel+":COUP AC
  ") # Input 1 coupling mode AC
      else:
          sock.send("INP"+channel+":COUP DC
  ") # Input 1 coupling mode DC
      sock.send("SYST:TIM INF
  ") # Timeout infiny to avoid problem if the gate
      #is too long
      sock.send("CONF:FREQ (@"+channel+")
  ") # Signal on input 1
      sock.send("SAMP:COUN 1E6
  ") # 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
  ") # Continuous mode (gap free) enable
      sock.send("SENS:FREQ:GATE:SOUR TIME
  ") # The gate source is TIME
      sock.send(g_time) # Gate time : 1 second
      sock.send("TRIG:SOUR IMM
  ") # 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?
  ')
      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 '
  '"""
      ans = ''
      nb_data_list = []
      nb_data = ''
      while ans != '
  ':
          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
  ") # Start the acquisition immediatly
      print "Waiting for the first acquisition"
      while True:
          try:
              sock.send("DATA:POIN?
  ") # 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
  ': # There is a minimum of one data to read
                  try:
                      sock.send("DATA:REM? 1
  ") # Put the data in the buffer and
                      # clear the memory
                      freq = sock.recv(24) # Read the buffer
                      freq = freq[:22] # Remove 
   from the string
                      freq = freq.replace("+", "")
                      freq = freq.replace("E", "e")
                      freq = freq.replace("\t", "")
                      sample = "%f\t%f\t%s
  " % (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
  ')
      init_53230a(sock, coup, imp, gate_time, ch)
      acqu_53230a(i, sock, data_file, gate_time)
      sock.close()
      print '
    --> 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 '
  ', filename, 'removed
  '
          else:
              print '
  ', filename, 'saved
  '
      except Exception as ex:
          print 'Oups '+str(ex)
      print 'Program ending
  '
  
  #==============================================================================
  if __name__ == "__main__":
      main()