Hi all, I am trying to use two e320's to collect data at the same time derived from some examples. I would like to perform this repeatedly, however it only succeeds on the 1st attempt, subsequently I get mysterious 'LL..." and no data with an ERROR_CODE_LATE_COMMAND. The modified example is below the output. Any suggestions are appreciated! -Mike
[INFO] [UHD] linux; GNU C++ version 9.4.0; Boost_107100; UHD_4.1.0.5-0-g6bd0be9c [INFO] [MPMD] Initializing 2 device(s) in parallel with args: mgmt_addr0=192.168.50.201,type0=e3xx,product0=e320,serial0=31DFBB8,fpga0=1G,claimed0=False,mgmt_addr1=192.168.50.202,type1=e3xx,product1=e320,serial1=31DE2CC,fpga1=1G,claimed1=False,addr0=192.168.50.201,addr1=192.168.50.202 [WARNING] [MPM.RPCServer] A timeout event occured! [WARNING] [MPM.RPCServer] A timeout event occured! [INFO] [MPM.PeriphManager] init() called with device args `fpga=1G,mgmt_addr=192.168.50.201,product=e320'. [INFO] [MPM.PeriphManager] init() called with device args `fpga=1G,mgmt_addr=192.168.50.202,product=e320'. [INFO] [0/Radio#0] Performing CODEC loopback test on channel 0 ... [INFO] [0/Radio#0] CODEC loopback test passed [INFO] [0/Radio#0] Performing CODEC loopback test on channel 1 ... [INFO] [0/Radio#0] CODEC loopback test passed [INFO] [0/DmaFIFO#0] BIST passed (Estimated Minimum Throughput: 1361 MB/s) [INFO] [0/DmaFIFO#0] BIST passed (Estimated Minimum Throughput: 1361 MB/s) [INFO] [1/Radio#0] Performing CODEC loopback test on channel 0 ... [INFO] [1/Radio#0] CODEC loopback test passed [INFO] [1/Radio#0] Performing CODEC loopback test on channel 1 ... [INFO] [1/Radio#0] CODEC loopback test passed [INFO] [1/DmaFIFO#0] BIST passed (Estimated Minimum Throughput: 1361 MB/s) [INFO] [1/DmaFIFO#0] BIST passed (Estimated Minimum Throughput: 1361 MB/s) [WARNING] [0/Radio#0] Attempting to set tick rate to 0. Skipping. [WARNING] [1/Radio#0] Attempting to set tick rate to 0. Skipping. Has timespec: No Time of first sample: 0 Fragmented: No Fragmentation offset: 0 Start of burst: No End of burst: No Error Code: ERROR_CODE_TIMEOUT Out of sequence: No 500000 Backend TkAgg is interactive backend. Turning interactive mode on. LLHas timespec: No Time of first sample: 0 Fragmented: No Fragmentation offset: 0 Start of burst: No End of burst: No Error Code: ERROR_CODE_LATE_COMMAND Out of sequence: No 0 Done! ---------------------------------------------------------------------- code #!/usr/bin/env python3 # # Copyright 2017-2018 Ettus Research, a National Instruments Company # # SPDX-License-Identifier: GPL-3.0-or-later # """ RX samples to file using Python API """ import argparse from xml.etree.ElementTree import tostring import numpy as np import uhd import matplotlib.pyplot as plt import time #./rx_to_file.py -f 80.0e6 -o ./test1.dat -d 1.0 -r 1.0e6 -a addr=192.168.50.201 def parse_args(): """Parse the command line arguments""" parser = argparse.ArgumentParser() parser.add_argument("-a", "--args", default="addr=192.168.50.201", type=str) parser.add_argument("-o", "--output-file", default="./test.bin",type=str, required=False) parser.add_argument("-f", "--freq", default=80e6, type=float, required=False) parser.add_argument("-r", "--rate", default=5e5, type=float) parser.add_argument("-d", "--duration", default=1.0, type=float) parser.add_argument("-c", "--channels", default=0, nargs="+", type=int) parser.add_argument("-g", "--gain", type=int, default=1) # range is int supposedly 0 - 76db range, parser.add_argument("-n", "--numpy", default=False, action="store_true", help="Save output file in NumPy format (default: No)") return parser.parse_args() timeStep = 10.0 class multiRcvr: def __init__(self, addr, args) : self.usrp = uhd.usrp.MultiUSRP(addr) self.usrp.set_clock_source("gpsdo",0) self.usrp.set_time_source("gpsdo",0) self.usrp.set_clock_source("gpsdo",1) self.usrp.set_time_source("gpsdo",1) for mboard in range(2): t0 = time.time() while self.usrp.get_mboard_sensor("gps_locked",mboard).value == 'false': time.sleep(1.0) if time.time() - t0 > 30.0: print("COULD NOT GET GPS LOCK on " + str(mboard) + " ********************************") break # https://kb.ettus.com/Synchronizing_USRP_Events_Using_Timed_Commands_in_UHD # https://files.ettus.com/manual/page_sync.html self.num_samps = int(np.ceil(args.duration*args.rate)) if not isinstance(args.channels, list): args.channels = [args.channels] self.channels = [0, 1] # time_at_last_pps = usrp.get_time_last_pps().get_real_secs() # print(time_at_last_pps) # usrp.set_time_next_pps(uhd.libpyuhd.types.time_spec(0.0)) # time.sleep(1) # To = usrp.get_time_now() # print( To.get_real_secs() ) # https://files.ettus.com/manual/page_multiple.html#multiple_setup self.usrp.set_rx_subdev_spec(uhd.usrp.SubdevSpec("A:0"),0) # disable other channels on 1st usrp self.usrp.set_rx_subdev_spec(uhd.usrp.SubdevSpec("A:0"),1) # disable other channels on 2nd usrp # https://pysdr.org/content/usrp.html # second arg is channel (int); if not present channels defaults to 0 # gain can vary 0 - 76 self.usrp.set_rx_rate(args.rate,0) self.usrp.set_rx_freq(uhd.libpyuhd.types.tune_request(args.freq),0) self.usrp.set_rx_gain(10,0) self.usrp.set_rx_rate(args.rate,1) self.usrp.set_rx_freq(uhd.libpyuhd.types.tune_request(args.freq), 1) self.usrp.set_rx_gain(args.gain, 1) # Set up the stream and receive buffer self.st_args = uhd.usrp.StreamArgs("fc32", "sc16") self.st_args.channels = self.channels self.metadata = uhd.types.RXMetadata() self.recv_buffer = np.zeros((len(self.channels), 1000), dtype=np.complex64) self.stream_cmd = uhd.types.StreamCMD(uhd.types.StreamMode.num_more) # num_done self.stream_cmd.num_samps = self.num_samps self.stream_cmd.stream_now = False self.stream_cmd.time_spec = uhd.libpyuhd.types.time_spec(timeStep) # set start time (try tweaking this) self.streamer = self.usrp.get_rx_stream(self.st_args) def printMultiUsrpInfo(self): print('rx channels in multi usrp : ' + str(self.usrp.get_rx_num_channels())) for chan in self.channels: mboard = chan print('clock_source ' + str(mboard) + ' : ' + self.usrp.get_clock_source(mboard)) # really mboard print('time_source ' + str(mboard) + ' : ' + self.usrp.get_time_source(mboard)) # this isn't really channel , it is mboard print('rx_info ' + str(chan) + ' : ' + str(self.usrp.get_usrp_rx_info(chan))) rxfiltername = self.usrp.get_rx_filter_names(chan) print('rxfiltername ' + str(chan) + ' : ' + str(rxfiltername)) # why doesn't this work? #print(self.usrp.get_rx_filter(rxfiltername,chan)) print('rx_gain_range ' + str(chan) + ' : ' + str(self.usrp.get_rx_gain_range(chan))) print('rx_gain ' + str(chan) + ' : ' + str(self.usrp.get_rx_gain(chan))) print('rx_freq ' + str(chan) + ' : ' + str(self.usrp.get_rx_freq(chan))) rx_sensors = self.usrp.get_rx_sensor_names(chan) for rx_sensor in rx_sensors: print("\t" + rx_sensor + " : " + self.usrp.get_rx_sensor(rx_sensor,mboard).value) mboard_sensors = self.usrp.get_mboard_sensor_names(mboard) for mboard_sensor in mboard_sensors: print("\t" + mboard_sensor + " : " + self.usrp.get_mboard_sensor(mboard_sensor,mboard).value) def wait4pps(self): # Wait for 1 PPS to happen, then set the time at next PPS to 0.0 time_at_last_pps = self.usrp.get_time_last_pps().get_real_secs() while time_at_last_pps == self.usrp.get_time_last_pps().get_real_secs(): time.sleep(0.05) # keep waiting till it happens- if this while loop never finishes then the PPS signal isn't there time.sleep(.01) # make sure all devices are into the next second self.usrp.set_time_next_pps(uhd.libpyuhd.types.time_spec(0.0)) # defaults to all devices # Schedule Rx of num_samps samples exactly N seconds from last PPS self.streamer.issue_stream_cmd(self.stream_cmd) def capture(self): # Receive Samples. recv() will return zeros, then our samples, then more zeros, letting us know it's done waiting_to_start = True # keep track of where we are in the cycle (see above comment) nsamps = 0 i = 0 # re-initialize samples every time so we don't see old data self.samples = np.zeros([len(self.channels),self.num_samps], dtype=np.complex64) #while nsamps != 0 or waiting_to_start: t0 = time.time() metadataLast = uhd.types.RXMetadata() while i < self.num_samps: nsamps = self.streamer.recv(self.recv_buffer, self.metadata, timeout=timeStep) if self.metadata != metadataLast: print(self.metadata) metadataLast = self.metadata # if nsamps and waiting_to_start: # waiting_to_start = False # elif nsamps: if nsamps: self.samples[:,i:i+nsamps] = self.recv_buffer[:,0:nsamps] i += nsamps if time.time() - t0 > 16.0: break print(i) def main(): """RX samples and write to file""" args = parse_args() usrp = multiRcvr ("addr0=192.168.50.201,addr1=192.168.50.202",args) for _ in range(2): usrp.wait4pps() usrp.capture() timeIdx = np.arange(usrp.num_samps)/args.rate fig, ax = plt.subplots() l1 = ax.plot(usrp.samples[0,:].real,label='201 R') l2 = ax.plot(usrp.samples[0,:].imag,label='201 I') l3 = ax.plot(usrp.samples[1,:].real,label='202 R') l4 = ax.plot(usrp.samples[1,:].imag,label='202 I') ax.legend( loc='upper right', shadow=True) ax.grid() plt.show(block=False) time.sleep(10.0) print('Done!') # with open(args.output_file, 'wb') as out_file: # if args.numpy: # np.save(out_file, samps, allow_pickle=False, fix_imports=False) # else: # samps.tofile(out_file) if __name__ == "__main__": main()
_______________________________________________ USRP-users mailing list -- usrp-users@lists.ettus.com To unsubscribe send an email to usrp-users-le...@lists.ettus.com