9
9
from scipy .fftpack import fft
10
10
import math
11
11
import util
12
- from datetime import datetime
13
- import csv
14
12
15
13
IP = 'rp-f0c04a.local'
16
14
rp_s = scpi .scpi (IP )
17
15
print ('Connected to ' + IP )
18
16
19
- store_data = False # whether or not to save data to CSV
20
-
21
- ##### Create Waveform #####
22
-
23
- N = 16384 # Number of samples in buffer
24
- SMPL_RATE_DEC1 = 125e6 # sample rate for decimation=1 in Samples/s (Hz)
25
- decimation = 8192
26
- smpl_rate = SMPL_RATE_DEC1 // decimation
27
- burst_time = N / smpl_rate
28
-
29
- wave_form = 'ARBITRARY'
30
- freq = 1 / burst_time
31
- ampl = 0.3 # good range 0-0.6V
32
-
33
- # t, y from exampled RP arbitrary wavegen:
34
- # t = np.linspace(0, 1, N)*2*math.pi
35
- # y = np.sin(t) + 1/3*np.sin(3*t) # same overall period as regular sin wave
36
- t , y = util .bounded_frequency_waveform (50 , 55 , length = N , sample_rate = smpl_rate )
37
- y = util .linear_convert (y ) # convert range of waveform to [-1, 1] to properly set ampl
38
- plt .plot (t , y )
39
- plt .show ()
40
-
41
- ##### Reset Generation and Acquisition ######
42
- rp_s .tx_txt ('GEN:RST' )
43
- rp_s .tx_txt ('ACQ:RST' )
44
-
45
- ##### Generation #####
46
- # Function for configuring Source
47
- rp_s .sour_set (1 , wave_form , ampl , freq , data = y )
48
-
49
- # Enable output
50
- rp_s .tx_txt ('OUTPUT1:STATE ON' )
51
- rp_s .tx_txt ('SOUR1:TRig:INT' )
52
-
53
- ##### Acqusition #####
54
- # Function for configuring Acquisition
55
- rp_s .acq_set (dec = decimation , trig_delay = 0 )
56
- rp_s .tx_txt ('ACQ:START' )
57
- time .sleep (1 )
58
- rp_s .tx_txt ('ACQ:TRig NOW' )
59
- time .sleep (1 )
60
-
61
- # Wait for trigger
62
- while 1 :
63
- rp_s .tx_txt ('ACQ:TRig:STAT?' ) # Get Trigger Status
64
- print ('got status' )
65
- if rp_s .rx_txt () == 'TD' : # Triggered?
66
- break
67
- print ('triggered' )
68
- ## ! OS 2.00 or higher only ! ##
69
- while 1 :
70
- rp_s .tx_txt ('ACQ:TRig:FILL?' )
71
- if rp_s .rx_txt () == '1' :
72
- break
73
-
74
- ##### Analaysis #####
75
- # Read data and plot function for Data Acquisition
76
- pd_data = rp_s .acq_data (chan = 1 , convert = True ) # Volts
77
- speaker_data = rp_s .acq_data (chan = 2 , convert = True ) # Volts
78
- displacement_data , converted_signal , freq = util .displacement_waveform (np .array (speaker_data ), smpl_rate , ampl )
79
- y_displ , _ , _ = util .displacement_waveform (ampl * y , smpl_rate , ampl )
80
-
81
- fig , ax = plt .subplots (nrows = 3 )
82
-
83
- time_data = np .linspace (0 , N - 1 , num = N ) / smpl_rate
84
- ax [0 ].plot (time_data , pd_data , color = 'blue' , label = 'PD' )
85
- ax [0 ].plot (time_data , speaker_data , color = 'black' , label = 'Speaker' )
86
- ax [0 ].plot (time_data , ampl * y , label = 'Original signal' )
87
- ax [0 ].legend ()
88
- ax [0 ].set_ylabel ('Amplitude (V)' )
89
- ax [0 ].set_xlabel ('Time (s)' )
90
-
91
- ax [1 ].plot (freq , np .abs (fft (speaker_data )), color = 'black' , label = 'Speaker' )
92
- ax [1 ].plot (freq , np .abs (converted_signal ), color = 'green' , label = 'Displacement' )
93
- ax [1 ].loglog ()
94
- ax [1 ].set_xlabel ('Frequency (Hz)' )
95
- ax [1 ].set_ylabel ('$|\^{V}|$' )
96
- ax [1 ].legend ()
97
-
98
- ax [2 ].plot (time_data , displacement_data , color = 'black' , label = 'Speaker' )
99
- ax [2 ].plot (time_data , y_displ , label = 'Original signal' )
100
- ax [2 ].set_ylabel ('Expected Displacement (Microns)' )
101
- ax [2 ].set_xlabel ('Time (s)' )
102
- ax [2 ].legend ()
103
- plt .tight_layout ()
104
- plt .show ()
105
-
106
- if store_data :
107
- # Store data in csv file
108
- path = "/Users/angelajia/Code/College/SMI/data/"
109
- filename = f"{ datetime .now ()} .csv"
110
- file_path = os .path .join (path , filename )
111
-
112
- with open (file_path , 'w' , newline = '' ) as f :
113
- writer = csv .writer (f )
114
- writer .writerow (['Time (s)' , 'Speaker (V)' , 'Speaker (Microns)' , 'PD (V)' ])
115
- all_data = np .vstack ((time_data , speaker_data , displacement_data , pd_data )).T
116
- for row in all_data :
117
- writer .writerow (row )
118
-
119
- ##### Reset when closing program #####
120
- rp_s .tx_txt ('GEN:RST' )
121
- rp_s .tx_txt ('ACQ:RST' )
17
+ '''
18
+ Runs one shot of driving the speaker with a waveform and collecting the relevant data.
19
+
20
+ @param store_data: whether to save time, measured speaker & PD voltage,
21
+ and expected speaker velocity data to h5py
22
+ @param plot_data: whether to plot data after acquisition
23
+ '''
24
+ def run_one_shot (start_freq = 1 , end_freq = 1000 , decimation = 8192 , store_data = False , plot_data = False ):
25
+ ##### Create Waveform #####
26
+
27
+ N = 16384 # Number of samples in buffer
28
+ SMPL_RATE_DEC1 = 125e6 # sample rate for decimation=1 in Samples/s (Hz)
29
+ smpl_rate = SMPL_RATE_DEC1 // decimation
30
+ burst_time = N / smpl_rate
31
+
32
+ wave_form = 'ARBITRARY'
33
+ freq = 1 / burst_time
34
+ ampl = 0.1 # good range 0-0.6V
35
+
36
+ t , y = util .bounded_frequency_waveform (start_freq , end_freq , length = N , sample_rate = smpl_rate )
37
+ y = util .linear_convert (y ) # convert range of waveform to [-1, 1] to properly set ampl
38
+ if plot_data :
39
+ plt .plot (t , y )
40
+ plt .show ()
41
+
42
+ ##### Reset Generation and Acquisition ######
43
+ rp_s .tx_txt ('GEN:RST' )
44
+ rp_s .tx_txt ('ACQ:RST' )
45
+
46
+ ##### Generation #####
47
+ # Function for configuring Source
48
+ rp_s .sour_set (1 , wave_form , ampl , freq , data = y )
49
+
50
+ # Enable output
51
+ rp_s .tx_txt ('OUTPUT1:STATE ON' )
52
+ rp_s .tx_txt ('SOUR1:TRig:INT' )
53
+
54
+ ##### Acqusition #####
55
+ # Function for configuring Acquisition
56
+ rp_s .acq_set (dec = decimation , trig_delay = 0 )
57
+ rp_s .tx_txt ('ACQ:START' )
58
+ time .sleep (1 )
59
+ rp_s .tx_txt ('ACQ:TRig CH2_PE' )
60
+ time .sleep (1 )
61
+
62
+ # Wait for trigger
63
+ while 1 :
64
+ rp_s .tx_txt ('ACQ:TRig:STAT?' ) # Get Trigger Status
65
+ print ('got status' )
66
+ if rp_s .rx_txt () == 'TD' : # Triggered?
67
+ break
68
+ print ('triggered' )
69
+ ## ! OS 2.00 or higher only ! ##
70
+ while 1 :
71
+ rp_s .tx_txt ('ACQ:TRig:FILL?' )
72
+ if rp_s .rx_txt () == '1' :
73
+ break
74
+
75
+ ##### Analaysis #####
76
+ # Read data and plot function for Data Acquisition
77
+ pd_data = np .array (rp_s .acq_data (chan = 1 , convert = True )) # Volts
78
+ speaker_data = np .array (rp_s .acq_data (chan = 2 , convert = True )) # Volts
79
+ velocity_data , converted_signal , freq = util .velocity_waveform (speaker_data , smpl_rate )
80
+ y_vel , _ , _ = util .velocity_waveform (ampl * y , smpl_rate )
81
+ time_data = np .linspace (0 , N - 1 , num = N ) / smpl_rate
82
+
83
+ if plot_data :
84
+ fig , ax = plt .subplots (nrows = 3 )
85
+
86
+ ax [0 ].plot (time_data , pd_data , color = 'blue' , label = 'Observed PD' )
87
+ ax [0 ].plot (time_data , speaker_data , color = 'black' , label = 'Observed Drive' )
88
+ ax [0 ].plot (time_data , ampl * y , label = 'Drive Output' )
89
+ ax [0 ].legend ()
90
+ ax [0 ].set_ylabel ('Amplitude (V)' )
91
+ ax [0 ].set_xlabel ('Time (s)' )
92
+
93
+ ax [1 ].plot (freq , np .abs (fft (speaker_data )), color = 'black' , label = 'Observed Drive' )
94
+ ax [1 ].plot (freq , np .abs (converted_signal ), color = 'green' , label = 'Expected Observed Vel' )
95
+ ax [1 ].loglog ()
96
+ ax [1 ].set_xlabel ('Frequency (Hz)' )
97
+ ax [1 ].set_ylabel ('$|\^{V}|$' )
98
+ ax [1 ].legend ()
99
+
100
+ ax [2 ].plot (time_data , velocity_data , color = 'black' , label = 'Observed Drive' )
101
+ ax [2 ].plot (time_data , y_vel , label = 'Drive Output' )
102
+ ax [2 ].set_ylabel ('Expected Velocity (Microns/s)' )
103
+ ax [2 ].set_xlabel ('Time (s)' )
104
+ ax [2 ].legend ()
105
+ plt .tight_layout ()
106
+ plt .show ()
107
+
108
+ if store_data :
109
+ # Store data in h5py file
110
+ path = "/Users/angelajia/Code/College/SMI/data/"
111
+ filename = "data.h5py"
112
+ file_path = os .path .join (path , filename )
113
+
114
+ entries = {
115
+ 'Time (s)' : time_data ,
116
+ 'Speaker (V)' : speaker_data ,
117
+ 'Speaker (Microns/s)' : velocity_data ,
118
+ 'PD (V)' : pd_data
119
+ }
120
+
121
+ util .write_data (file_path , entries )
122
+
123
+ ##### Reset when closing program #####
124
+ rp_s .tx_txt ('GEN:RST' )
125
+ rp_s .tx_txt ('ACQ:RST' )
126
+
127
+
128
+ num_shots = 1
129
+ for i in range (num_shots ):
130
+ run_one_shot (5 , 6 , plot_data = True )
0 commit comments