46
|
1 #!/usr/bin/env python
|
|
2
|
|
3 # Copyright (c) 2012
|
|
4 # Daniel O'Connor <darius@dons.net.au>. All rights reserved.
|
|
5 #
|
|
6 # Redistribution and use in source and binary forms, with or without
|
|
7 # modification, are permitted provided that the following conditions
|
|
8 # are met:
|
|
9 # 1. Redistributions of source code must retain the above copyright
|
|
10 # notice, this list of conditions and the following disclaimer.
|
|
11 # 2. Redistributions in binary form must reproduce the above copyright
|
|
12 # notice, this list of conditions and the following disclaimer in the
|
|
13 # documentation and/or other materials provided with the distribution.
|
|
14 #
|
|
15 # THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
16 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
17 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
18 # ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
19 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
20 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
21 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
22 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
23 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
24 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
25 # SUCH DAMAGE.
|
|
26 #
|
|
27
|
|
28 import math
|
|
29 import rsib
|
|
30 import scpi
|
|
31 import sys
|
|
32
|
|
33 def setup(r):
|
|
34 # Reset to defaults
|
|
35 r.write("*RST")
|
|
36
|
|
37 # Set to single sweep mode
|
|
38 r.write("INIT:CONT OFF")
|
|
39
|
|
40 # Enable display updates
|
|
41 r.write("SYST:DISP:UPD ON")
|
|
42
|
|
43 # Set frequency range
|
|
44 r.write("FREQ:CEN 10.7MHz;SPAN 1MHz")
|
|
45
|
|
46 # Switch marker 1 on in screen A
|
|
47 r.write("CALC:MARK1 ON")
|
|
48
|
|
49 # Enable noise measurement
|
|
50 r.write("CALC:MARK1:FUNC:NOIS ON")
|
|
51
|
|
52 # Set number of sweeps
|
|
53 r.write("SWE:COUN 20")
|
|
54
|
|
55 # Set resolution bandwidth
|
|
56 r.write("SENS1:BAND:RES 10kHz")
|
|
57
|
|
58 # Set video bandwidth (10x res BW)
|
|
59 r.write("SENS1:BAND:VID 100kHz")
|
|
60
|
|
61 def getnoise(r):
|
|
62 # Trigger the sweep
|
|
63 r.write("INIT;*WAI")
|
|
64
|
|
65 # Wait for it to be done
|
|
66 r.write("*OPC?")
|
|
67 opc = scpi.getdata(r.read(60), int)
|
|
68 #print "OPC - %d" % (opc)
|
|
69 assert(opc == 1)
|
|
70
|
|
71 # Set data format
|
|
72 r.write("FORM:DATA ASC")
|
|
73
|
|
74 # Read noise value
|
|
75 r.write("CALC:MARK1:FUNC:NOIS:RES?")
|
|
76 data = r.read(10)
|
|
77 #print "Data - " + data
|
|
78
|
|
79 return float(data)
|
|
80
|
|
81 def setnoise(r, en):
|
|
82 if en:
|
|
83 val = "ON"
|
|
84 else:
|
|
85 val = "OFF"
|
|
86 r.write("DIAG:SERV:NSO " + val)
|
|
87
|
|
88 def calcnf(enrdb, offdb, ondb):
|
|
89 # Not possible but weak results may give it
|
|
90 if ondb <= offdb:
|
|
91 return 0
|
|
92 ydb = ondb - offdb
|
|
93 y = 10 ** (ydb / 10)
|
|
94 enr = 10 ** (enrdb / 10)
|
|
95 nf = 10 * math.log10(enr / (y - 1))
|
|
96 return nf
|
|
97
|
|
98 def donoisetest(r, enr):
|
|
99 print "Acquiring with noise off.."
|
|
100 setnoise(r, False)
|
|
101 off = getnoise(r)
|
|
102 print "Acquiring with noise on.."
|
|
103 setnoise(r, True)
|
|
104 on = getnoise(r)
|
|
105 return off, on, calcnf(enr, off, on)
|
|
106
|
|
107 if __name__ == '__main__':
|
|
108 enr = 15.55 # From back of noise source
|
|
109 r = rsib.RSIBDevice('analyzer')
|
|
110
|
|
111 # ID instrument
|
|
112 r.write('*IDN?')
|
|
113 print "ID is " + r.read(5)
|
|
114
|
|
115 #setup(r)
|
|
116 r.write("INIT:CONT OFF")
|
|
117
|
|
118 while True:
|
|
119 off, on, nf = donoisetest(r, enr)
|
|
120 print "Off %.3f dB, on %.3f dB, NF %.2f" % (off, on, nf)
|
|
121 print "Press enter to perform a new measurement"
|
|
122 sys.stdin.readline()
|
|
123
|