Hello everybody, I'm trying to do some channel measurements using a setup based on three PCs with two USRP2 devices (equipped with RFX2400 daughterboards) and GNU Radio 3.7. One of the PCs acts as network controller, it creates data the other PCs should transceive. The network controller therefore iFFT processes some random data and tells the two daemons what the have to send. If the USRP of one of the daemons receives something the received data gets delivered back to the network controller, which FFT processes the data and does some calculations. So the GNU Radio action is happening only on the daemons. From the transmitter point of view it's just adding the cyclic prefix, on receivers point of view there is a Schmidl & Cox correlator for synchronization and a block picking the samples of the payload. The (i)FFT stuff is happening on the network controller, using NumPys FFT implementation. My predecessor (whom I sadly can't ask) built this communication system and used a decimation factor of 16 and a FFT size of 64. Now I wanted to try a different FFT size. I expected this modification to be straightforward, just changing values and using a proper, low PAPR preamble. However, I tried it with FFT sizes of 32, 96 and 128 - still with a decimation factor of 16 - and had no success. Bit error rates were far too high (about 40%). I looked into some log files and found that apparently at least the Schmidl & Cox correlator and the payload picking block is working, it catches the frame start and delivers the amount of samples needed for the FFT. Please notice, as already mentioned above, that I do the FFT with NumPy on the network controller after transmission has finished. Now if I compare the post FFT / frequency domain received data with the sent data, looking at the argument differences I can observe some strange values: I would expect a straight line with an slope (which I could correct by equalizing), as in this figure: http://abload.de/img/nfft32_decfac32l2sy3.png Please ignore the "jumps" by 2*pi (or 360) and keep in mind it's drawn using Matlab, this means one-based indexing, therefore ignore subcarrier 17 as it's the DC carrier. Instead, I get some random jumps by pi on some of the carriers, as seen in this figure: http://abload.de/img/nfft32_decfac163qsri.png This happens with all FFT sizes I tried except the original FFT size of 64 if I keep the decimation factor of 16. Now I noticed that there seems to be some correlation with the decimation factor: If I choose a decimation factor, so that the ratio between FFT size and sampling rate is the same as in my original and correctly working setup (FFT size: 64, decimation factor: 16, so about 100 kHz per subcarrier) , everything seems to work properly. The BER is low and comparing the argument of sent vs. received data I can see the expected line without any random jumps. This behaviour I could observe with FFT size 32 (using a decimation factor of 32) and 96 (using a decimation factor of 12) - with other decimation factors I didn't work. Now I'm trying to understand this phenomenon. I expected, that I would be able to change FFT size without touching decimation factor. At least I thought that using less FFT bins with the same decimation factor shouldn't harm, giving each subcarrier more bandwidth. It would be great if someone could help me regarding this problem as I'm quite confused now and don't really know what to do.
on 2013-12-18 19:49
on 2013-12-20 12:16
Hi everybody. (I had some problems with In-Reply-To header, so I hope this gets posted in the right thread. Otherwise I'm sorry, this message refers to http://lists.gnu.org/archive/html/discuss-gnuradio...) Thank you for your answer, Martin. Martin Braun wrote: > I'm not sure what your decimation factor does. By "decimation factor" I mean the ratio the USRPs 100 MS/s gets divided with. So a decimation factor of 16 would result in a sampling rate of (100 MS/s / 16) = 6.25 MS/s. In the source code I uploaded it's defined in send_receive.py and called "samp_rate_div", using set_samp_rate(100e6/samp_rate_ div) to set the USRPs sampling rate. Martin Braun wrote: > You're using your own OFDM codes, not the GNU Radio ones, right? Can you share these? I uploaded the relevant code, to give some more details: https://www.dropbox.com/sh/xdo456tvcqiwdwx/Y-6pcz_rR4 <https://www.dropbox.com/sh/xdo456tvcqiwdwx/Y-6pcz_rR4> I already tried to shorten it, but unfortunately it's still a bit confusing, as the person who wrote it did somehow bypass GNU Radio a bit and implemented a lot himself. Therefore, I give my best to describe how the code works: To give a short abstract of the system: https://www.dropbox.com/s/iphz1ix4b1as4pd/network_... <https://www.dropbox.com/s/iphz1ix4b1as4pd/network_... PC1 commands PC2 and PC3 to alternatingly send some data, at first PC2 is the transmitter and PC3 the receiver, then the other way round. The network controller (generating and evaluating all the data, using NumPy (I)FFT) commands the network daemons to send data and collects received data from them via Ethernet. The network daemons start the send_receive top_block and read from / push to send_receive.py queues by add_complex_list_to_queue() and fetch_complex_list_from_queue() functions. send_receive.py is the top_block, connecting message queues to jwdiplom.modulator (adding cyclic prefix) / jwdiplom.demodulator (Schmidl & Cox synchronisation) blocks, which are connected to UHD source/sink. The PCs running network daemons each are equipped with two network cards, one for communication with network controller and one for communication between send_receive and the USRP2 devices by UHD. More in detail: PC 1 is the network controller, running nc_kanalmessung_AB_BA.py. This Python script at first initializes the network daemons running on PC 2 and 3, it loads the settings dictionary from ofdmsettings.py and chooses the right preamble. It does an IFFT on the preamble (so it's in time domain, line 99) and sends this parameters by Ethernet to the daemons using send_ethernet_packet() (line 135). On line 107 it creates random data using modulation.py. Again using modulation.py, it PSK modulates the random data, adds the pilot and empty carriers (as defined in ofdmsettings.py) and does the IFFT (modulation.py, line 46). This ready-to-send time domain data is send frame by frame to the network daemons (nc_kanalmessung_AB_BA.py, line 114), once more using send_ethernet_packet() function. Now it's time to look at network_daemon.py, running on PCs 2 and 3. As one can see there are several threads running, at first InitThread gets started, waiting for nc_kanalmessung_AB_BA.py sending the parameters and preamble. After this happened the GNU Radio action begins: It starts the top_block of send_receive.py (handing over the parameters). send_receive.py features two message queues connected to jwdiplom.modulator and jwdiplom.demodulator. These message queues are read out / feed with data by fetch_complex_list_from_queue() (send_receive.py, line 84) and add_complex_list_to_queue() (send_receive.py, line 91) functions, which get accessed by InputThread and OutputThread in network_daemon.py. jwdiplom.modulator just adds a cyclic prefix and is connected to uhd_usrp_sink_0. jwdiplom.demodulator implements a Schmidl & Cox synchronization, it is connected to uhd_usrp_source_0. The source files are located in /gr-jwdiplom/python but for easier comprehension I made some .grc files and exported them: https://www.dropbox.com/s/2s7ssy5ypp0ekjy/ofdm_mod... <https://www.dropbox.com/s/2s7ssy5ypp0ekjy/ofdm_mod... https://www.dropbox.com/s/34lo5yytx9accgq/ofdm_dem... <https://www.dropbox.com/s/34lo5yytx9accgq/ofdm_dem... The demodulator block uses two custom blocks: - jwdiplom.schmidl_cox_correlator, implementing formula (6) from Schmidl & Cox "Robust Frequency and Timing Synchronization for OFDM" paper (http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=650240 <http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumb...) - jwdiplom.stream_to_vector_syncd, selecting the right (payload) samples according to the sync signal provided by the plateau detector I know that's a lot of text (and source code) and not relying on GNU Radios standard OFDM implementation makes it hard for others to review but it would be great if someone could help. Regards, Sebastian