Documentation/GNURadio: usrp_siggen_multiple_sine.py

File usrp_siggen_multiple_sine.py, 10.0 kB (added by wenyuan, 2 years ago)
Line 
1#!/usr/bin/env python
2
3from gnuradio import gr, gru
4from gnuradio import usrp
5from gnuradio.eng_option import eng_option
6from gnuradio import eng_notation
7from optparse import OptionParser
8import sys
9
10
11class my_graph(gr.flow_graph):
12    def __init__ (self,options):
13        gr.flow_graph.__init__(self)
14       
15        # controllable values
16        self.interp = options.interp #64
17        self.waveform_type = options.type #gr.GR_SIN_WAVE
18        self.waveform_ampl = options.amplitude #16000
19        self.waveform_freq = options.waveform_freq #1e3
20        self.waveform_offset = 0
21        self.siggap = options.siggap
22        self._instantiate_blocks ()
23        self.set_waveform_type (self.waveform_type,options.multiple,options.tofile)
24
25    def usb_freq (self):
26        return self.u.dac_freq() / self.interp
27
28    def usb_throughput (self):
29        return self.usb_freq () * 4
30       
31    def set_waveform_type (self, type,multiple,tofile):
32        '''
33        valid waveform types are: gr.GR_SIN_WAVE, gr.GR_CONST_WAVE,
34        gr.GR_UNIFORM and gr.GR_GAUSSIAN and gr.GR_IMPULSE
35        '''
36        self._configure_graph (type,multiple,tofile)
37        self.waveform_type = type
38
39    def set_waveform_ampl (self, ampl):
40        self.waveform_ampl = ampl
41        self.siggen.set_amplitude (ampl)
42        self.siggen1.set_amplitude (ampl)
43        self.siggen2.set_amplitude (ampl)
44        self.siggen3.set_amplitude (ampl)
45        self.noisegen.set_amplitude (ampl)
46
47    def set_waveform_freq (self, freq):
48        self.waveform_freq = freq
49        self.siggen.set_frequency (freq)
50        self.siggen1.set_frequency (freq+self.siggap*1)
51        self.siggen2.set_frequency (freq+self.siggap*2)
52        self.siggen3.set_frequency (freq+self.siggap*3)
53       
54    def set_waveform_offset (self, offset):
55        self.waveform_offset = offset
56        self.siggen.set_offset (offset)
57        self.siggen1.set_offset (offset)
58        self.siggen2.set_offset (offset)
59        self.siggen3.set_offset (offset)
60
61    def set_interpolator (self, interp):
62        self.interp = interp
63        self.siggen.set_sampling_freq (self.usb_freq ())
64        self.siggen1.set_sampling_freq (self.usb_freq ())
65        self.siggen2.set_sampling_freq (self.usb_freq ())
66        self.siggen3.set_sampling_freq (self.usb_freq ())
67        self.u.set_interp_rate (interp)
68        print "sampling freq:",self.usb_freq()/1e6,"M"
69        print "dac_freq:",eng_notation.num_to_str(self.u.dac_freq())
70        print "interp rate:", self.interp
71
72    def _instantiate_blocks (self):
73        self.src = None
74        self.u = usrp.sink_c (which=0, interp_rate=self.interp)
75
76        #self.siggap = 100e3
77       
78        self.siggen = gr.sig_source_c (self.usb_freq (),
79                                       gr.GR_SIN_WAVE,
80                                       self.waveform_freq,
81                                       self.waveform_ampl,
82                                       self.waveform_offset)
83
84        self.siggen1 = gr.sig_source_c(self.usb_freq(),
85                                        gr.GR_SIN_WAVE,
86                                        self.waveform_freq+self.siggap,
87                                        self.waveform_ampl,
88                                        self.waveform_offset)
89
90        self.siggen2 = gr.sig_source_c(self.usb_freq(),
91                                        gr.GR_SIN_WAVE,
92                                        self.waveform_freq+self.siggap*2,
93                                        self.waveform_ampl,
94                                        self.waveform_offset)
95
96        self.siggen3 = gr.sig_source_c(self.usb_freq(),
97                                        gr.GR_SIN_WAVE,
98                                        self.waveform_freq+self.siggap*3,
99                                        self.waveform_ampl,
100                                        self.waveform_offset)
101
102        self.noisegen = gr.noise_source_c (gr.GR_UNIFORM,
103                                           self.waveform_ampl)
104        re = 8000
105        im = 8000j
106        tt = 8000+8000j
107        self.src_data = (re,re,re,re,re,re,re,re,re,re,re,re,re,re,re,re,re,re,re,re,re,re,re,re,re,re,re,re,re,re,re,re,-re,-re,-re,-re,-re,-re,-re,-re,-re,-re,-re,-re,-re,-re,-re,-re) #(32*re, 16*)
108        self.vectgen = gr.vector_source_c(self.src_data, 1)
109        # self.file_sink = gr.file_sink (gr.sizeof_gr_complex, "siggen.dat")
110
111    def _configure_graph (self, type,multiple,tofile):
112        was_running = self.is_running ()
113        if was_running:
114            self.stop ()
115        self.disconnect_all ()
116        if type == gr.GR_SIN_WAVE or type == gr.GR_CONST_WAVE:
117            adder= gr.add_cc ()
118            if multiple == 2: 
119                self.connect (self.siggen, (adder,0))
120                self.connect (self.siggen1,(adder,1))
121            elif multiple == 3:
122                self.connect (self.siggen, (adder,0))
123                self.connect (self.siggen1,(adder,1))
124                self.connect (self.siggen2,(adder,2))
125            elif multiple == 4:
126                self.connect (self.siggen, (adder,0))
127                self.connect (self.siggen1,(adder,1))
128                self.connect (self.siggen2,(adder,2))
129                self.connect (self.siggen3,(adder,3))
130            else:
131                self.connect (self.siggen, (adder,0))
132               
133            #self.connect (adder, self.u)
134            # self.connect (self.siggen, self.file_sink)
135            self.siggen.set_waveform (type)
136            self.siggen1.set_waveform(type)
137            self.siggen2.set_waveform(type)
138            self.siggen3.set_waveform(type)
139            self.src = adder
140            if tofile==0:
141                self.connect (adder, self.u)
142                print "sending out ",multiple, "sine waves to usrp "
143            else:
144                self.file_sink = gr.file_sink (gr.sizeof_gr_complex, "siggen.dat")
145                self.head = gr.head(gr.sizeof_gr_complex, 20000)
146                self.connect(self.src, self.head, self.file_sink)
147                print "sending out ",multiple, "sine waves to file "
148
149        elif type == gr.GR_UNIFORM or type == gr.GR_GAUSSIAN:
150            self.connect (self.noisegen, self.u)
151            self.noisegen.set_type (type)
152            self.src = self.noisegen
153        elif type == gr.GR_IMPULSE:
154            self.connect (self.vectgen,self.u)
155            self.src = self.vectgen
156        else:
157            raise ValueError, type
158        if was_running:
159            self.start ()
160
161    def set_freq(self, target_freq):
162        """
163        Set the center frequency we're interested in.
164
165        @param target_freq: frequency in Hz
166        @rypte: bool
167
168        Tuning is a two step process.  First we ask the front-end to
169        tune as close to the desired frequency as it can.  Then we use
170        the result of that operation and our target_frequency to
171        determine the value for the digital up converter.
172        """
173        r = self.u.tune(self.subdev._which, self.subdev, target_freq)
174        if r:
175            print "r.baseband_freq =", eng_notation.num_to_str(r.baseband_freq)
176            print "r.dxc_freq      =", eng_notation.num_to_str(r.dxc_freq)
177            print "r.residual_freq =", eng_notation.num_to_str(r.residual_freq)
178            print "r.inverted      =", r.inverted
179            return True
180
181        return False
182
183
184
185def main ():
186    parser = OptionParser (option_class=eng_option)
187    parser.add_option ("-T", "--tx-subdev-spec", type="subdev", default=(0, 0),
188                       help="select USRP Tx side A or B")
189    parser.add_option ("-f", "--rf-freq", type="eng_float", default=None,
190                       help="set RF center frequency to FREQ")
191    parser.add_option ("-i", "--interp", type="int", default=64,
192                       help="set fgpa interpolation rate to INTERP")
193
194    parser.add_option ("-m", "--multiple", type="int", default=1,
195                       help="set the number of sine wave to add on")
196    parser.add_option ("--sine", dest="type", action="store_const", const=gr.GR_SIN_WAVE,
197                       help="generate a complex sinusoid [default]", default=gr.GR_SIN_WAVE)
198    parser.add_option ("--const", dest="type", action="store_const", const=gr.GR_CONST_WAVE, 
199                       help="generate a constant output")
200    parser.add_option ("--gaussian", dest="type", action="store_const", const=gr.GR_GAUSSIAN,
201                       help="generate Gaussian random output")
202    parser.add_option ("--uniform", dest="type", action="store_const", const=gr.GR_UNIFORM,
203                       help="generate Uniform random output")
204
205    parser.add_option ("--impulse", dest="type", action="store_const", const=gr.GR_IMPULSE,
206                       help="generate a impulse signal", default=gr.GR_IMPULSE)
207    parser.add_option ("-w", "--waveform-freq", type="eng_float", default=100e3,
208                       help="set waveform frequency to FREQ")
209    parser.add_option ("-l", "--tofile", type="int", default=0,
210                       help="set whether dump the data to a file 1 true 0 false")
211    parser.add_option ("-a", "--amplitude", type="eng_float", default=16e3,
212                       help="set waveform amplitude to AMPLITUDE", metavar="AMPL")
213    parser.add_option ("-o", "--offset", type="eng_float", default=0,
214                       help="set waveform offset to OFFSET")
215    parser.add_option ("-g", "--siggap", type="eng_float", default=100e3,
216                       help="set the gap between two waveforms")
217    (options, args) = parser.parse_args ()
218
219    if len(args) != 0:
220        parser.print_help()
221        raise SystemExit
222
223    if options.rf_freq is None:
224        sys.stderr.write("usrp_siggen: must specify RF center frequency with -f RF_FREQ\n")
225        parser.print_help()
226        raise SystemExit
227
228    fg = my_graph(options)
229    fg.set_interpolator (options.interp)
230    #fg.set_waveform_type (options.type,options.multiple)
231    #fg.set_waveform_freq (options.waveform_freq)
232    #fg.set_waveform_ampl (options.amplitude)
233    #fg.set_waveform_offset (options.offset)
234
235    # determine the daughterboard subdevice we're using
236    if options.tx_subdev_spec is None:
237        options.tx_subdev_spec = usrp.pick_tx_subdevice(fg.u)
238
239    m = usrp.determine_tx_mux_value(fg.u, options.tx_subdev_spec)
240    print "mux = %#04x" % (m,)
241    fg.u.set_mux(m)
242    #fg.u.set_mux(0x98)
243    fg.subdev = usrp.selected_subdev(fg.u, options.tx_subdev_spec)
244    print "Using TX d'board %s" % (fg.subdev.side_and_name(),)
245   
246    fg.subdev.set_gain(fg.subdev.gain_range()[1])    # set max Tx gain
247
248    if not fg.set_freq(options.rf_freq):
249        sys.stderr.write('Failed to set RF frequency\n')
250        raise SystemExit
251   
252    fg.subdev.set_enable(True)                       # enable transmitter
253
254    try:
255        #fg.run()
256        fg.start()
257        raw_input ('Press Enter to quit: ')
258        fg.stop ()
259    except KeyboardInterrupt:
260        pass
261
262if __name__ == '__main__':
263    main ()