DMR app for repeaters

I know I haven’t written for quite some time. I decided to write again since I’ve done some work for hamradio community and I want to share it.

As it happened lately, more and more hamradio operators switched to DMR (Digital Mobile Radio) protocol where there are already several world wide networks: BrandMeister, MARK, DMR+, etc and one way to access the network and talk to people around the world is having access to a repeater in close vicinity.

The DMR protocol is not roaming friendly like GSM, 3G or 4G and basically one needs to enter a list of repeater’s frequencies into your radio in advance so that access to those repeaters will be possible. The good side of BrandMeister network is that it provides a way to get access to all repeaters list in real time and here comes the idea of having an app to choose the right repeaters based on the distance and/or radioamateur callsign.

So here it goes the Android app that does that: DMR BrandMeister repeaters

The app can be found on Google Play Store on any Android based phone/tablet/etc.

The app allows downloading the repeaters list and storing it on the Android phone/tablet so that it can be used when there is no internet connectivity in the current location.



Possible next steps:

  • build a codeplug from search result and write it into DMR radios
  • 73 de YO3IIU


RTL2832u based coherent multichannel receiver

This paper explains the experiment done with multiple RTL2832u SDR receivers in order to create a multichannel receiver by using an unique HW clock source and signal correlations to obtain correction of the sampling deltas between the signals.

The need for a coherent multichannel receiver brought us to the idea of using multiple cheap RTL2832u SDR receivers in a system that will be phase coherent and will provide the user with access to multiple radio channels that can be used in subsequent signal processing algorithms requiring relatively high data rate per channel and in the same non continuous radio spectrum access.

Applications of this system could be in the areas of:

  • Direction Of Arrival (DOA) estimators.
  • Beamforming receivers.
  • Multichannel receivers using frequency hopping like GSM.
  • Multiple FM receivers for specific applications.
  • Scientific applications requiring phase coherent receivers.
  • Bandwidth aggregation (for continuous/non-continuous spectrum)

Technical implementation:

The HW:

The experiment uses the CDCLVC1310-EVM board from TI that provides 10 output low jitter clock distribution system with selectable inputs from external clock sources or a local XTAL soldered on the board. The XTAL the board is equipped with, which is 25Mhz, has been replaced with one of 28.8Mhz XTALs that the RTL2832u usually has as default clock.

The RTL2832u eats up 185mA when equipped with R820T tuner so a USB 2.0 hub with 10 sockets will need to have its own power supply to supply 185x10mA needed current.

The USB controller of the PC to which the USB hub is connected will need to support the high transfer bandwidth on the USB port or the number of RTL2832u receivers can be split between several USB hubs. A simple calculus for the required transfer rate using 10 SDRs on the same USB port will give:

2 x 8bit/sample x 2Msample/second * 10 SDRs = 320Mbit/s which is less than the theoretical maximum speed of USB2.0 that is 480Mbit/s.

A picture with a 4 receiver system is presented below:

Achieving sample coherence between receivers:

When the USB transfer is started for each receiver, there is no way to control the moment of acquisition of the samples relatively to the other receivers. In order to still achieve the sample coherence between receivers a simple method of calculating the correlation between the channels signals is employed. The correlations will have a peak where the samples are correlated and therefore one could calculate the time deltas in number of samples between the channels. Those time deltas are used to correct the stream timing from each of the receiver so that a synchronization in time is obtained. This assumes that once the USB transfer is started from a receiver, no sample will be lost and in general according to my observation this holds true on the PC systems I tested the project.

A gnuradio GRC script has been used to acquire data from the SDRs then a Matlab script was used to do the math calculations. In a later step, a gnuradio block has been created to do all math calculations.

Practical results:

Short-circuit on the antenna inputs for three SDRs. In this case only the internal noise is available and one can see there is no or very small correlation between the signals:

Open input for three SDRs. In this case the environmental noise is available and so there is correlation between the signals but still the peak does not reach close to 1 as it should be in the case of a strong signal.

FFT for four SDRs fed with a strong NBFM signal on 430Mhz, sample rate is at 1Msps as in all cases during this experiment.

Correlation of signals between four SDR signals: ab, ac, ad given the signals a, b, c, d. The calculated time delta between the channels given in number of samples:

Correlations for the same signal as above but after correction of the signals with deltas samples. In this case if deltas is calculated again, it will be zero:

Angle error between corrected signals in case of the signal at 1Msps rate (above) and 1Ksps (below) after resampling with linear interpolation:

Further work:

Using this system, several usecases will be presented in the next posts like:

  • bandwidth aggregation
  • receive and decode SFH (Slow Frequency Hopping) GSM signals


The use of RTL2832u SDR receiver in a multichannel coherent receiver proved to be successful and opens a new range of applications that are usually implemented with much more expensive HW.

The drawbacks and limitations of the RTL2832u type SDRs like small dynamic range (given by 8bit/sample), instability with temperature, gain differences between different boards are also the limitations of the multichannel system as a whole.

We tried to feed all the SDRs clocks from just one SDR an it worked fine for a system with 3 receivers maximum. Adding the fourth receiver destroyed the clock synchronization and that is the reason a clock distribution has been added.


[Ref 1]

[Ref 2]

[Ref 3]!topic/sara-list/qrtf_TzTyHo

Direction Of Arrival simulation with Nec2

This paper presents the method used for simulation of an Uniform Linear Array in 4Nec2 program and the results that are obtained by using the array output in Matlab with DOA methods rootMusic, Esprit, wsf, beamscan, MVDR. For increasing resolution, mutual coupling impedances for the array are calculated with 4Nec2 program and subsequently used to correct the output of the array. The absolute error is plotted for both cases, with mutual coupling correction and without mutual coupling correction.

Method of simulation of Uniform Linear Array array and signal source impinging on the array:

A simple ULA array of dipoles is simulated in 4Nec2 and the source of the signal is a similar dipole excited by a voltage source modulated in amplitude by a cos() function. In order to have a closer to reality simulation, the voltage source is modulated in amplitude by a low frequency signal that is sampled at a sampling frequency fs. One simulation is run for each sample of the voltage so that the response of the array is obtained for each of the sample.

The ULA is presented in the following picture:

Calculating the mutual impedance matrix:

The literature of antenna array makes distinction between the mutual impedance for transmitting arrays for which the elements are excited and produce electromagnetic field and the mutual impedance for receiving arrays in which the source of the electromagnetic field is outside of the array – see Yantao et all in [Ref1].

The mutual correction matrix used to obtained uncoupled voltages (U) form the coupled voltages (V) is presented below:

Here the mutual impedances between antenna 1 and 2, Z12, is calculated by Z12 = – (V1 – U1)/I2 where V1 is the voltage on the antenna 1 when antenna 2 is existing and connected to ZL impedance and U1 is the uncoupled voltage in antenna 1 with antenna 2 removed. I2 is the current in the antenna 2. This is the correction matrix used in our simulations and below is presented as a reference the transmitting correction matrix that is deducted when the antenna array elements are emitting electromagnetic field:

The above formula relates Vo which is the open circuit voltage to the coupled voltages, assuming that the open circuit voltage is independent of the mutual coupling.

Practical results:

The ULA array is formed by 9 dipoles resonating at around 430Mhz frequency. The dipoles are separated by 0.2m which is a distance lower than lambda/2=0.4836/2 meter so a strong mutual coupling between array elements is expected. In the Nec2 model each dipole has 9 segments and a 50 Ohm impedance is connected on segment 5. The source is a far source modeled as a dipole placed at 10km distance and powered by a voltage source modulated by a 300hz cosine source sampled at fs=8000Hz.

A sweep with a resolution of 5 degrees azimuth (xy plane) is executed by placing the source at an azimuth between -85 to +85 degrees angle in the far field and calculating the array output. A set of Nec2 models is created by having one .nec file for each azimuth angle and each sample, e.g. the file represents the model with a source placed at -40 degrees azimuth in the far field and with the voltage source exciting the transmitting dipole representing the 7999th sample.

Therefore, the set of input .nec files is of size (85×2 + 1) * 8000 = 136800. Correspondingly the set of output files is of the same size.

A set of tools was created to parse the .out files and create one file for each azimuth degree which are in turn imported into Matlab as antenna array output.

The correction matrix is calculated by running a simulation with the source placed in far field at zero degree azimuth and calculating Zxy by running simulations with antenna x and with antenna y placed in the model and then with antenna x and antenna y taken out from the model. Another tool is created to parse the output of the 4Nec2 program and generate a file containing the 9×9 correction matrix which in turn is imported in Matlab.

A set of plots is presented below for a set of DOA algorithms with and without mutual coupling correction:

It can be seen that the mutual coupling compensation is useful for azimuth in range -80 to -15 and 15 to 80 degrees. For the rest of the situations the DOA error is lower in the case of not using correction. It will be of interest to test the simulation results in real life situation.

Many sources DOA:

Two simulations has been run with two signal sources of frequency 300Hz respective 400Hz that modulates in amplitude the 430Mhz carrier. The first one has the sources placed at -30 and +45 degree azimuth and the second has the sources at +17 respective +22 degrees.

The following table shows the DOA results with two sources for the case of uncorrected array output and corrected output:

It can be seen that when the sources are separated by a relatively small angle (5 degree in our second simulation) only rootMusic and Esprit algorithms can determine the two signal directions but even in this situation the error is bigger and generate an increase of the detected angle between the two sources.


  • The method of using Nec2 MoM program to simulate the antenna array and obtain the array manifold provides good insights on the mutual coupling compensation versus azimuth and elevation. The exciter signal can be modeled by having any modulation type and also the multipath effects can be simulated.
  • Receiving of different number of samples can be simulated.
  • Using the mutual coupling compensation improve the precision of DOA for absolute azimuth angles that satisfy the approximate relationship: 15 < |az| < 80.
  • The theory developed for ULA can be applied also for Uniform Circular Array (UCA) if transformation is done from UCA to ULA so that the steering vector becomes a Vandermonde matrix. This will be shown in another paper.

A word about tools:

  • 4Nec2 MoM tool was used during the simulation. It uses Nec2 core and is created for running under Windows but can run just fine on Linux (Ubuntu 12.04) using wine. The tools generate a .bat files that will be executed in windows console under wine.
  • The method of creating model files for each sample and each azimuth value is inneficient from computing time point of view. As an example, running the whole azimuth sweep -85, 85 and whole sample range 0-7999 takes 2 days execution time on a SandyBridge core i7 at 3.4Mhz. Therefore a way to run the 4Nec2 in an multithreaded fasion is a must in order to decrease the computing time.


[Ref1] Yantao Yu, Hoi-Shun Lui , Choon Hock Niow , Hon Tat Hui – Improved DOA Estimations Using the Receiving Mutual Impedances for Mutual Coupling Compensation: An Experimental Study

[Ref2] github code for tools:

[Ref3] 4Nec2 is created by Aries Voors:

DVB-T implementation in GNUradio – Viterbi decoder implementation

Later edit: source code added here:

The picture above is not directly connected to the following discussion but it is showing a 64-QAM signal decoded with the gr-dvbt.

In this post I thought I should write about the Viterbi decoder implementation on which I spent more time than usual just because I tried to understand why the whole DVB-T decoding take so much processor time. Investigating the processor time used by each module it turned out that the most computing power hungry module was the Viterbi convolutional decoder.

The initial implementation of convolutional decoder I used was based on the gr-trellis implementation from gnuradio which I modified for hard bit decision decoding. It means that each input symbol is actually one bit as compared with the soft bit decision decoding in which each input symbol is represented on a number of bits representing the probability of receiving the transmitted symbol.

I did a calculation for the bitrate at the input of the convolutional decoder using various parameters of the DVB-T just to understand what will be the maximum rate expected at the input in the case of a real time decoding. Here it is the worst case scenario as an excerpt from the calculation done in an excel file:

It is seen that the rate after decoder in the worst case scenario is 34.36Mbit/s and the rate before decoder is 39.27Mbit/s for a FEC rate of 7/8. However, due to the fact that the 7/8 FEC comes actually from ½ FEC rate punctured then the actual data rate at the input of the decoder is 2*34.36Mbit/s=68.43Mbit/s. This is the maximum rate that can be processed in real time by the decoder.

I tried different implementation of convolutional decoder and the next one I tested was the Karn C implementation already existing in gnuradio 3.7.x. It gave some speed-up but still it was slow compared with what I needed.

I should mention that my target was to run in real time decoding of QAM-16, FEC rate ½, 2k OFDM which requires around 26Mbit/s rate at the entry of the decoder.

I tried another decoder implementation, namely the one from IT++ which gave me poor results too in terms of maximum data rate that can be processed.

So the next step was to actually craft my own Viterbi decoder implementation using SIMD instructions. The implementation requires SSE2 support in the processor and the next step is to move this implementation into it’s own VOLK kernel. Here are some results I measured with the various Viterbi decoder implementations I tried:

A note on depuncturing:

I developed the initial code for FEC rate ½ and therefore once it worked I started thinking about how to integrate the depuncturing in the whole solution as te DVB-T standard includes FEC for several n/(n+1) rates.

Usually depuncturing is done by adding symbols in the place of punctured ones and then run the decoder as it received data at the master rate which in my case is ½. For example the rate 2/3 comes out of the ½ rate by puncturing a bit. At the receiving side there is one symbol to add in order to restore the initial, not punctured, rate but it gives the risk of inserting the symbol in the wrong position if the start of the depuncturing is not synchronized. Therefore there is need to make sure that the depuncturing starts at the right position.

The next issue appearing in the case of depuncturing was: what is the unknown symbol to add? There are several solutions used in this case and this depends on many conditions for example on the soft/hard decoding. In the case of soft bit decision one can add a median value, for example 0 in the case of a symbol ranging from -127, 127. In the case of hard bit decision when the symbols are bits with values 0,1 I have seen solutions using insertion of alternating 0, 1 in the place of the unknown symbols. I tried this and it works for rate 2/3 decoding but for the other rates like 3/4, 5/6, 7/8 it did not work.

One solution on the above problem is to modify the decoder to be aware of the puncturing matrix(or puncturing vector) so that whenever the unknown symbol is processed, the Accumulate in the ACS (Accumulate, Compare, Select) is not done meaning that the symbol does not influence the result of ACS. This is what I used in my case, specifically inserting a symbol with value 2 and testing the value inside the decoder to decide whether to do the Accumulate or not.

The traceback length when depuncturing:

It is known that the traceback length in the Viterbi decoder should be of 5*K where K is the constraint length of the convolutional code. For example for the NASA code that is also used in DVB-T the constraint length is K=7. It gives the traceback 35 meaning that all paths will get back to the same state if we traceback with 5*K positions in the trellis.

However, it is clear that in the case of depuncturing the more unknown symbols we add the lengthier we need to go back in order to reach a stable state. Therefore we need to extend the traceback length depending on the code rate we want to achieve.

I can conclude with the followings: I needed to make the Viterbi decoder aware of the puncturing matrix and also adapt the traceback length for each FEC rate.

Another image capturing a lower SNR receiving with 8K OFDM, FEC rate 7/8, QAM-64. It still decodes the MPEG2-TS perfectly:

Using WiFi Atheros chips in hamradio bands


I was aware for long time that Atheros (bought by Qualcom in May 2011) wifi chips can work in the below 2.4Ghz band and lately I saw an old post from here confirming that but I had never tried this.

So I thought it will be an interesting and not so complex experiment to try this out:

1. use wifi USB sticks in the 2300-2400Mhz band

2. increase the power level to more than the 20dBm which is the current limit

3. verify all of the above #1 and #2 in a real life environment

Note: check your country’s legislation and your hamradio license to understand the conditions under you can do this.

The HW:

I bought two TL-WN722N WiFi USB sticks, they are under 10EUR each. The dongles have the AR9271 chips:

Having a connector for an external antenna makes room for a lot of experiments, including using of high gain point-to-point antennas.

The SW:

A bit about Wireless stack on Linux:

The AR9271 chip is using a kernel driver and a SoftMAC driver which is the software implementation of the MLME (MAC Layer Management Entity). However, other chips implement this sublayer into HW. The wireless stack in Linux kernel is presented below and a good overview is presented here.

Linux kernel HW driver changes:

The AR9271 chip actually does not know about wireless channels and that seems to be the solution to add more frequencies in the hamradio bands. The driver that knows AR9271 is ath9k_htc. I added a number of channels below channel 1 of 2.4Ghz by modifying the channel table in drivers/net/wireless/ath/ath9k/htc_drv_init.c like in the following snippet:

#define CHAN2G(_freq, _idx)  { \
.center_freq = (_freq), \
.hw_value = (_idx), \
– .max_power = 20, \
+ .max_power = 30, \

CHAN2G(2397, 16), /* Channel -2 */
CHAN2G(2402, 15), /* Channel -1 */

CHAN2G(2407, 14), /* Channel 0 */
CHAN2G(2412, 0), /* Channel 1 */
CHAN2G(2417, 1), /* Channel 2 */

Another change to do is in drivers/net/wireless/ath/ath9k/regd.c:

-#define ATH9K_2GHZ_CH01_11 REG_RULE(2412-10, 2462+10, 40, 0, 20, 0)
+#define ATH9K_2GHZ_CH01_11 REG_RULE(2312-10, 2462+10, 40, 0, 30, 0)

The new channels will appear as negative channels and for that there is another change to do, this time in net/wireless/util.c, ieee80211_channel_to_frequency() function:

} else { /* IEEE80211_BAND_2GHZ */
+    chan = (int)(char)chan;

This is because the channel is seen internally as unsigned number and it need to be transformed in a negative number so that the returned frequency will be the right one. The channels in 80211 are separated by 5Mhz and how the new ones are seen in user space is shown below.

Recompiling the kernel and installing the new drivers should give the following capabilities of the wireless device:

>iw list

Wiphy phy0
Band 1:
Capabilities: 0x116e
SM Power Save disabled
RX STBC 1-stream
Max AMSDU length: 7935 bytes
Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
Minimum RX AMPDU time spacing: 8 usec (0x06)
HT TX/RX MCS rate indexes supported: 0-7
* 2312 MHz [-19] (30.0 dBm)
* 2317 MHz [-18] (30.0 dBm)
* 2322 MHz [-17] (30.0 dBm)
* 2327 MHz [-16] (30.0 dBm)
* 2332 MHz [-15] (30.0 dBm)
* 2337 MHz [-14] (30.0 dBm)
* 2342 MHz [-13] (30.0 dBm)
* 2347 MHz [-12] (30.0 dBm)
* 2352 MHz [-11] (30.0 dBm)
* 2357 MHz [-10] (30.0 dBm)
* 2362 MHz [-9] (30.0 dBm)
* 2367 MHz [-8] (30.0 dBm)
* 2372 MHz [-7] (30.0 dBm)
* 2377 MHz [-6] (30.0 dBm)
* 2382 MHz [-5] (30.0 dBm)
* 2387 MHz [-4] (30.0 dBm)
* 2392 MHz [-3] (30.0 dBm)
* 2397 MHz [-2] (30.0 dBm)
* 2402 MHz [-1] (30.0 dBm)
* 2407 MHz [0] (30.0 dBm)

* 2412 MHz [1] (30.0 dBm)
* 2417 MHz [2] (30.0 dBm)

Regulatory Database changes:

The regulatory database (regdb) is the Linux solution to achieve legal regulation for each country the machine is used in. It is basically a user space database that lists specifics like allowed bands, channels enabled, power levels, antenna gain, etc for each country. The WiFi chips usually have an EEPROM to store various similar details and those will be intersected with the details from the regdb set by the system/user.

The idea of regdb is to allow a roaming user’s machine to accomodate the settings of wifi while going to other countries than the base country.

Regdb is presented in a signed binary form compiled from a text in a user readable form. One needs to modify the database in text format and then compile it together with the necessary keys. I will not explain this as it is better explained on wireless kernel pages.


There are basically two packages one need to build and install after one another. The first one is wireless-regdb that generates the binary form of regdb from its text form. My wifi USB stick came with CN as the country set in EEPROM so the CN will be modified into db.txt:

country CN:

(2402 – 2482 @ 20), (N/A, 20)

(2302 – 2482 @ 20), (N/A, 30)

Central Regulatory Domain Agent (CRDA)

CRDA is the user space app that kernel uses to interrogate the regdb database. It is mandatory to be rebuild and installed together with the keys generated in the wireless-regdb build process.

Commands for working with regulatory database:

a. to dump whole regulatory database

>regdbdump /lib/crda/regulatory.bin

b. to dump the current regulatory settings

>iw reg get

c. to set country CN in regulatory settings. Usually this is overwritten by the setting in the EEPROM of the WiFi card.

>iw reg set CN

Hostapd changes (for v2.0):

One of the goals of this project is to run an Access point (AP) to which a client (STA) will connect and communicate. Scanning, association, sending, receiving data should work.

One of quick solution for running an AP is hostapd package because it implements MLME in user space.  One need to change hostapd to accept the negative channels we have just been added.

In src/ap/hw_features.c:hostapd_select_hw_mode()

– if (chan->chan == iface->conf->channel) {

+if ((0xff & chan->chan) == iface->conf->channel) {

In src/ap/hw_features.c:hostapd_hw_get_freq()

-if (ch->chan == chan)

+if ((0xff & ch->chan) == chan)

In hostapd.conf:

channel=-19 or whatever the card shows that it supports

Run hostapd after it is built:

./hostapd ./hostapd.conf

And now we have the AP running on the channel -19 (freq 2312Mhz):


wlan5     IEEE 802.11bgn  Mode:Master  Frequency:2.312 GHz  Tx-Power=30 dBm
Retry  long limit:7   RTS thr:off   Fragment thr:off
Power Management:off

mon.wlan5  IEEE 802.11bgn  Mode:Monitor  Tx-Power=30 dBm
Retry  long limit:7   RTS thr:off   Fragment thr:off
Power Management:off

Real life tests:

We now need to connect a client (STA) to the AP so this is done on another Linux machine with the same changes done on the kernel and regulatory database.


>iw scan

BSS 10:fe:ed:14:2f:bd (on wlan0)
TSF: 399462784 usec (0d, 00:06:39)
freq: 2312
beacon interval: 100
capability: ESS ShortSlotTime (0x0401)
signal: -49.00 dBm
last seen: 168 ms ago
Information elements from Probe Response frame:
SSID: test
Supported rates: 1.0* 2.0* 5.5* 11.0* 6.0 9.0 12.0 18.0
DS Parameter set: channel 237
ERP: Barker_Preamble_Mode
Extended supported rates: 24.0 36.0 48.0 54.0
WMM:   * Parameter version 1
* BE: CW 15-1023, AIFSN 3
* BK: CW 15-1023, AIFSN 7
* VI: CW 7-15, AIFSN 2, TXOP 3008 usec
* VO: CW 3-7, AIFSN 2, TXOP 1504 usec


This can be done using regular UI tools on Linux like nm-applet. If the dhcp is not available on AP then a static IP address is to be given:

On AP: ifconfig wlan0

On STA: ifconfig wlan0

Show the connection:


wlan0     IEEE 802.11bgn  ESSID:”test”
Mode:Managed  Frequency:2.312 GHz Access Point: 10:FE:ED:14:2F:BD
Bit Rate=54 Mb/s   Tx-Power=30 dBm
Retry  long limit:7   RTS thr:off   Fragment thr:off
Power Management:off
Link Quality=70/70  Signal level=-24 dBm

Rx invalid nwid:0  Rx invalid crypt:0  Rx invalid frag:0
Tx excessive retries:0  Invalid misc:7   Missed beacon:0

Check the communication is on selected channel:

I choose another channel -11 <=> 2352Mhz to see if I can see a change in the frequency domain. It is important to have an ongoing data transfer between the AP and STA in order to see the shape of the waveform and for that I used NC (Network Cat):

Check the change in the power level:

The above picture is for the 30dBm power limit. The next one is for the 20dBm and one with 10dBm transmit power. There is a visible difference between the three images, however probably a more precise measurement needs to be done.

Source code:

Patches for the kernel code and hostapd are here: atheros_hambands.tgz


– it was possible to add 20 channels from 2312Mhz to 2407Mhz and the connection between similar wifi devices is possible.

– there seems to be no difference in the transmit power for any channel between 2312Mhz (channel -19) to 2472Mhz (channel 13).

– there is an increase of power level when changing above 20dBm although this needs to be checked with finer tools and also the thermal regime of the devices needs to be taken into consideration.

– the same traffic speed is obtained for each channel compared with regular channels (1-14).

Next steps:

– to create a point-to-point link between two wifi devices using high gain antennas. An excel file calculating the theoretical results is here: Radio_Link_Budget_Calc.xls.

– play around with spectral scan

DVB-T implementation in GNUradio – part 3

Later edit: source code added here:

In this article I will describe my  DVB-T receiver implementation in GNUradio.

The blocks used for receiving are basically the transmitter blocks in the reverse order with a major difference that there is need for synchronization blocks in order to obtain a clean constellation.

OFDM symbol aquisition:

The task of this block is to synchronize the receiver so that a clean time domain signal is obtained before the FFT block. There are several subtasks that this block takes care of:

1. Use Cyclic Prefix (CP) to obtain the start of the OFDM symbol in time domain. Here I’ve chosen to use a MLSE algorithm that is presented in [REF1 – Van de Beek]. It minimizes a log likelihood function in order to obtain frequency correction, epsilon – a fractional of intercarrier frequency, and time correction, theta – number of samples to the detected start of OFDM symbol. Since the CP is added in front of the OFDM symbol and being a copy of the last part of the symbol there should be a correlation maximum that will signal the beginning of the symbol. This is called pre-FFT NDA (Non Data Aided) correction and basically will obtain sync on the beginning of the OFDM symbol and will assure the subcarriers will fit into the center of the FFT bin.

Note: The algorithms used in OFDM for 802.11 [Schmidl and Cox – REF2] are using a preamble that is specially created to create two identical halves in time domain. In DVB-T this option is not available and the pre-FFT correction is called Non Data Aided acquisition because no pilots are used to achieve the synchronization task. However, there will be pilots used for post-FFT synchronization and I will explain it later in this article.

2. Once the CP start is found and epsilon is also found, de-rotation of the signal is applied in order to obtain the correct time domain OFDM symbol.

Note: The MLSE algorithm is quite computational intensive due to the correlations necessary to be calculated. For that reason for the subsequent symbols only +/-4 samples is taken in consideration to assure the CP is found again. In case of a number of consecutive CP misses a full initial aquisition is triggered.

Note 2: The MLSE of Beek requires knowledge of SNR value. For now this is entered manually as a parameter to the processing block.

TODO: Add one methods of SNR estimation

3. The CP in front of the OFDM symbol is taken out

FFT for time to frequency domain conversion:

This is just plain FFT conversion for 2k, 8k or 4k depending on the parameters. Here the GNUradio block is used.

A plot of the constellation after the FFT is in order. One may see that the constellation is rotating and therefore requires more processing in order to be useful for de-mapping:

Plot is made when transmitting with USRP N210 and receiving with USRP N210, both equipped with WBX daughterboards. DVB-T parameters are 8Mhz bandwidth, FFT 2k, 16-QAM, FEC 1/2

Demodulation of Reference signals:
The DVB-T standard uses several sub-carriers to insert pilot signals that are used for synchronization, signal parameters transmission and equalization.

There are three pilot signals types used in DVB-T standard:

– scattered pilot signals

– continual pilot signal

– TPS (Transmission Parameter Signals)

1. Post-FFT DA (Data Aided) synchronization.

The continual pilots and (in my implementation) scattered pilots are used to obtain an integer frequency correction after the FFT is performed. The position of the scattered and continual pilots is known and therefore by using ML correlation of the signal with the expected values one can obtain an integer frequency correction. This is the number of bins the synchronizer needs to take in consideration when correcting the signal after the FFT.

There are two roots of frequency deviations that we need to take into account beside the nature of the transmission channel: Carrier and Sampling-clock deviations. These produces ICI (Inter Carrier Interferences) that are important due to the small intercarrier frequency and can be modelled as noise. See [Speth and all – REF3].

After pre/post-FFT carrier synchronization that is to be performed one time only, a continuous correction still need to be done for the residual correction that will appear during time using a PID-like algorithm described also in [Speth and all – REF3].

TODO: implement this correction.

2. Demodulation of TPS block

Transmission Parameter Signalling is used to assist the receiver in knowing the parameters of the stream that is received. The TPS is send using using predefined position pilots on witch  the data is modulated using DBPSK modulation. Being differential modulation, this is suitable for demodulation even though the constellation is rotating. The same bit of information is sent in an OFDM symbol so majority voting is used to decide the actual value of the data bit. There are 68 symbols in an frame and 4 frames in a superframe.

3. Equalization of signal based on pilot signals

A simple continual and scattered pilot based equalizer is used to perform correction of the data. The scattered pilots have a position inside the frame that is based on the following formula {k = Kmin + 3 × (l mod 4) + 12p p integer, p ≥ 0, k ∈ [Kmin; Kmax] } whre l is the symbol index. The idea behind scattered pilots is to allow for a better coverage of the whole channel when moving from one symbol to the other.

TODO: Implement DFE (Decision Feedback Equalizer) – See [Proakis – REF4]

The following plot shows the signal constellation for 16-QAM after the equalization:


[REF1]: Jaan-Jaap van de Beek, ML Estimation of Time and Frequency Offset in OFDM Systems

[REF2]: Timothy M.Schmidl and Donald C. Cox, Robust Frequency and Timing Synchronization for OFDM

[REF3]: Michael Speth, Stefan Fechtel, Gunnar Fock, Heinrich Meyr, Optimum Receiver Design for OFDM-Based Broadband Transmission – Part I and II

[REF4]: John G. Proakis, Masoud Salehi, Digital Communications

DVB-T implementation in GNUradio – part 2

Later edit: source code added here:

In the previous post I presented the results when using the gnuradio DVB-T transmitter together with the RTL2832U Elonics receiver. Now I’m going to dig into more technical details regarding the actual implementation of the DVB-T standard and I will insist less on transmitter side and more on the receiver side. The standard is defined in ETSI 300 744 and beside that there is doxygen documentation provided with the gnuradio modules.

TX and how to get on the air:

The chain of the transmitter is like the one described in the image below (taken from ETSI):

This is how the GNUradio implementation is done using gnuradio-companion. The majority of the blocks is implemented as new GR blocks as nothing that already exists in GR is fitting into this standard:

It worth talking about each module so here it is:

Energy dispersal:

In order to disperse the energy in the MPEG2-TS source, this block does a xor of the actual data with the output of the PRBS generator. It also creates MUX frames composed of 8 MUX packets of 188bytes. The sync is done by replacing the 0x47 sync byte with 0xb8 at the beginning of the MUX frame.

Outer coder (Reed-Solomon):

Implements RS(188, 204) encoding with t=8 error correcting capability.

Convolutional interleaver:

The whole point of using an outer coder+interleaver+inner coder is to generate a long codeword.

The inner interleaver is of Ramsey type III (TODO add IEEE paper link here).

Inner coder:

This is a convolutional encoder with mother code 1/2 and puncturing rate so that will obtain 2/3, 3/4, 5/6, 7/8 rates.

Inner interleaver:

The inner interleaver is made of symbol interleaver and bitwise interleaver. The result should be prepared for mapping of number of bits to the constellation according to the used modulation type.


Maps the bits to a constellation and this depends not only on the type of modulation but also on whether the hierarchical modulation is used.

Reference signals block:

In order to support the synchronization and equalization at the receiver side, the standard adds three types of pilots: continual pilots, scattered pilots and TPS. Actually TPS (Transmission Parameter Signalling) is a way to send over the transmission parameters and this is done using differential modulation that is immune to phase rotations.  Decoding of TPS is the first thing to do at receiver after an initial synchronization.


The COFDM (Coded OFDM) modulation used in DVB-T is creating frequency domain bins and then do an I-FFT to convert them to time domain. 2k, 8k and 4k FFT size can be used.

Cyclic prefix:

In order to prevent ISI, ICI in the SFN(single frequency networks) that are usually employed in the DVB-T implementations, a cyclip prefix (CP) of various sizes is used. It consist in copying of the last part of the time domain signal to the beginning of the signal. The fact that the signal becomes periodic helps in synchronizing at the receiver and many algorithms for time and frequency correction are based on CP.

Rational resampler:

The USRP N210 I’m using as receiver and transmitter has a clock of 100Mhz. Unfortunately, in DVB-T the clock at which the samples are out are at Fs=8*B/7 =9.14xxMsps/s for 8Mhz bandwidth and for that we need a resampler. This proved to be the most time consuming block (taken from GR) and probably it needs to be rewritten with another one in the future. I also noted that group delay is having variations so it needs to be investigated.

Processing power when running the transmitter:

I’m using a core i7 processor with 4 HT and 3.4Ghz frequency which consumes on transmitting 170% resources (less than 2 HT cores). This is where the things become interesting as long as there are a lot of improvements to do, e.g. using VOLK, do some calculations at init time with a trade-off between memory and processing. But this should be a chapter for itself at the end.

Finally, I attach a screenshot that shows the constellation and the FFT at tha baseband. Given the fact that the points in the WXwidget are so small I used the options to show the constellation with connected points, hope you like it 🙂

That’s all folks about DVB-T transmitter. Next post: the DVB-T receiver.

73, Bogdan – YO3IIU

DVB-T implementation in GNUradio – part 1

Later edit: source code added here:

Motivation for implementing DVB-T RX/TX:

I thought I should write about my work on implementing the ETSI 300 744 (DVB-T ) standard on GNUradio and what were the challenges I needed to overcome and challenges that still remained.

The entire work for DVB-T, both TX and RX, is going to be on github in the next couple of weeks.

The whole idea of the project was to provide a framework for researchers that want to play with various algorithms for synchronization, demodulation equalization, etc and none the less for individuals wanting to have a testing tool for real life implementation of the DVB-T standard.

The presentation here will be of low complexity and intended for understanding the principles that drive the digital broadcasting. I will write later on a more academic like paper with studies on effect of various SNR levels on the BER, MER and entire system together with further development directions. Given the complexity of the receiver, the tool can be used also as a benchmark to understand how different architectures can minimize the processing required together with lowering power consumption.

Quick start with a challenge:

Let’s get started by telling you that looking for sources of open source DVB-T implementation I found none that can work in real life or that can be used as a research in real life (TODO: insert OpenDVBT, Barruffa, Pellegrini, other). Therefore I decided to dig the ETSI 300 744 standard and implement it step by step.

Actually, the whole started when I wanted to use the cheap RTL2832U dvbt stick on ham radio frequencies like 1200Mhz band where I did not have a transmitter available. As you may probably know, the Elonics dvb-t stick has a driver for Linux kernel available. And also you may know that the chip inside can go up more than 1Ghz frequency. Modifying the driver to accept frequencyes above the regular DVB-T frequencyes is easy like this:

— a/RTL2832-2.2.2_kernel-3.0.0/rtl2832u_fe.c
+++ b/RTL2832-2.2.2_kernel-3.0.0/rtl2832u_fe.c

–        .frequency_max      = 862000000,
+        .frequency_max      = 1700000000, //862000000

Now, let’s jump to some screenshots to show the functionality of the transmitter and the signal received with Elonics dvb-t stick. I am using Kaffeine in Ubuntu Linux:

Searching for the channel (see SNR):

Now the channel is found:

Display properties of the channel (see the frequency and the other parameters):

And finally a screenshot from Kaffeine playing the stream:

I used a MPEG2-TS file as an input file but also I did some tests with a webcamera Logitec C920 that is able to output H248 stream. I did not do many tests with the camera because an Ubuntu update changed the kernel and after that the whole USB system on my PC is failing (including USB mass storage) to sustain constant bitrate.

As you may know or imagine, the receiver was the most time consuming compared with the transmitter. I can say that implementing RX takes 3 times more time than implementing TX but that will be presented in the subsequent posts where I will dig into more technical details.

73, Bogdan – YO3IIU

Running GPS software on USRP

I checked today how the gnss-sdr project ( is working. I’m interested in algorithms used for the L1C/A and this project sounds just the right one to start with. This project aims at providing an open source implementation for GPS/Galileo GNSS (Global Navigation Satellite System). It is provided under GNU GPL V3.0 license and it is mainly targeted for research communities.

The gnss-sdr can use data samples from a file or can use directly USRP and gnuradio for realtime data input. Also it can use the cheap RTL2832U based DVB-T dongle. I tried the gnss-sdr with USRP N210 and the aim was to obtain a position update corresponding to my location.

USRP, Bias-T, Antenna

The HW:

The GPS signal is quite weak and for that reason I used an active GPS antenna and a Bias-T that allows one to inject the necessary DC voltage to the GPS antenna. This is necessary when using the WBX daughterboard or any other daughterboard as long as it does not provide directly the required DC voltage.

Bias Tee

Antenna - bottom view
Antenna bottom

The antenna has a magnet inside and has 27dB gain when powered at 3-5V DC.

I tested also the DBSRX2 board from Ettus which is the only one daughterboard having a bias tee onboard. One need to do strap J101 jumper in order to provide 3.3V to the antenna connected directly to the board.

DBSRX2 - see the J101 in the upper right corner that activates the Bias-T

Showed below is the USRP N210 with WBX daughterboard mounted:

USRP N210 + WBX - External Bias Tee is needed

The SW:

I like the software that runs without much tweaking and this was the case after I figured out the HW components. Building instructions are provided on the site.

svn co gnss-sdr
cd gnss-sdr

One need to have gnuradio and all dependencies installed on your computer in order to have a successful build (dependencies are listed on the gnss-sdr site). In the conf directory one will find several config files and I used gnss-sdr.cong almost unchanged. The executable is installed into install directory and one can use it from there.


cd gnss-sdr/install


Obtaining a fix requires getting ephemeris from at least 4 GPS satellites and for that a good SNR is required. I observed that sometimes gnss-sdr is not able to obtain a fix even after a long time. The necessary C/N0 seems to be above 40db-Hz in order to obtain an ephemeris from a satellite. Below is a screenshot showing the PRNs 23, 13, 32, 1, 17 and a fix obtained after 64seconds.

Note: The gnss-sdr software requires a lot of processing power so that is why I needed to run it on an i7 2900K machine.


With little effort someone interested in adding new algorithms for the GNSS can start with gnss-sdr project and advance the current state of the art in this area. Of course this is not a project that can be directly transformed into a product as long as paying at least 2k USD for the HW makes it worthless when an off the shef GPS module is $10. However, for researchers it is a great opportunity in having a framework where new ideas can be implemented and focus could be maintained on a specific area.

CDMA sensing with USRP

I decided to start looking at how UMTS works and obviously the first thing to look at is the CDMA. One thing an ME is looking at when powered on is the synchronisation channels. There are two such channels, the primary one in which PSC (Primary Scrambling Code)  is used and a secondary one where SSC (Secondary Scrambling Code) is used.

The BS is sending the frames at 10ms interval and one of the ways to determine whether there is something there or not is to calculate autocorrelation of the signal so that if a periodicity exists it will be shown.

One of the cells I’m using is on UMTS-FDD in the 900Mhz band (see TS 25.101- band VIII) which means DL: 925 – 960Mhz and UL: 880 – 915Mhz. The regular BW is 5Mhz but the standard allows a 200Khz raster. For example, below is the UL respective DL  spectrum when when my phone is using W-CDMA in 900Mhz:

Going further, I needed to autocorrelate the signals in order to see whether there are some periodicities there in both UL and DL. Fortunately there is set of packages for gnuradio called FAC (Fast Auto Correlation). The gnuradio block is written in python and is part of the gr-baz package [Ref 1]

Installing gr-baz and creating a GRC flowgraph is as easy as it sounds. See below the GRC flowgraph [Ref 2]:

FAC uses the Wienner-Khinchin theorem which allows obtaining of autocorrelation of a signal by using the FFT of the absolute square of the signal PSD [Ref 3]

The sample rate is 250khz and is obtained from the 4Mhz sample rate by decimating with 16 (I know there should be an anti-aliasing filter there, either before the decimation or after but in this case it is really not necessary).

Using a number of 32768 FFT points and a sampling rate of 250khz will give you a maximum correlation time of (32768/2 * 1/250000=~65mS)

Below is presented the autocorrelation for UL:and now for DL:

It is easy to see the periodicity of 10mS for both UL and DL created by the pilot signals. Also it is obvious the difference between amplitude of the signals between DL and UL since the phone was closer to the USRP.

Note: If the UL channel is observed, then in my case (WCDMA 900) there is for sure a corresponding DL channel so that one can go directly there instead of scanning.

[Ref 1]

[Ref 2]

[Ref 3]