In the previous chapter we saw how the baseband complex signal are generated. Let's see how to detect the movement direction through the phase shift between the I and Q coplex signals!

What are complex or imaginary numbers anyway? According to definition they are defined by the property that i2 = - 1. It's hard to believe that i really exists, the name "imaginary" originates from the early times when they were concidered as a number system which consit of the square root of negative numbers. Why we need them here? - Because our frequencies can be negative as we will see in the measurements.

Let's begin the experiment!

The purpose of this experiment is to understand how to build a system whih is able to detect the direction of the movement. It consist of a two channel signal generator and a two channel A/D converter. I recommend to use the Red Pitya which is an extremely powerful signal generator and data aquisition system.  For the A/D converter using a microcontroller (or an USB DAQ) might be the most simple solution. Important, that the microcontroller needs to have two independent  A/D units (for I and Q). Many cortex controllers do  have, I recommend the Cortex M4 based ones. XMC4500F100 or STM32F401RE are both great microcontrollers for this task.


Nucleo-F401RE with STM32F401RE KIT_XMC45_RELAX_V1 with XMC4500F100

The test System

 Most important is the signal generator! You need a two channel generator. Alternatively you may use a uC with two DACs or a nice Mikroelektronika DAC shiled.

Figure: Main blocks of the test setup.

The discovery board is connected via USB (virtual serial port) to the PC.


Figure: The "test tower" with the XMC board and the Red Pitaya

The Red Piatya is accessed via ethernet through the white hub on the bottom.


The Software

Code for the XMC

The code for the XMC was wiritten in the DAVE 3 environment. The two 12bit  ADCs are running sychronously triggered by the an interrupt with fs=4KHz. The processing is done with a 2 x 1024 element ping-pong buffer (uint32). First the I and Q raw values are arranged into a new buffer with the order reqired by the CMSIS FFT function, arm_Cfft_radix4_f32(). The array type is float, and the content is {real[0], imag[0], real[1], imag[1], ...}. The result is the 1024 element spectrum, which is send over the serial port for the matlab processing.

The source code with the DAVE Project is avaiable in the google drive:,  but you can download only the hex also: CMPLX_FFT_XMC4500.hex

Fig.: The Dave3 Apps and connections.

On the left side the sampling frequency is configured which will trigger the synchronised and grupped ADCs.NVIC002/1 is ste standard ARM interrupt controller, which in case generates the sampling frequency. NVIC002/0 is the ADC ready interrupt.

Matlab Code

The code is not final, but I have limited time. It collects and plot the spectrum recieved from the XMC. There is also a possibility to toggle a uC on via serial command (e.g. for target detection). The code is avaiable in the github repository or as direct download.


PlotXMCdata.m : you should run this. It will call the other functions. It combines the 4 byte parts of the float numbers back to 4 byte float and creates a circular buffer for the imagesc() function. In the waterfall diagramm imagesc() will display 100 FFT spectrums. The last recieved FFT spectrum is also displayed in the plot on the figure. The green line is the adaptive average of the last 20 spectum, which we will use for "automatic" threshold calculation later.

readDataXMC.m : reads the data from the XMC.

envelope.m : the function by Lei Wang calculates the envelope curve of each spectrum, which will be later averaged. The average of the envelops are important for the automatic treshold setting as we will see.


The Hardware

You need to connect the Red Pitaya (or any signal source) to the input pins of the XMC. If you have coaxial cable you are lucky, if not just use wires, the generated frequency is low. Below is the table, but you can check the connection on the picture below.


App Signal Port-Pin Pin Number Description
IO001/1[CH_I] pin P14.1 #30 I channel input (blue)
IO001/2[CH_Q] pin P14.2 #29 Q channel input (yellow)
IO004/0[LED_1_0] pin P1.0 #79 LED controlled by Matlab
PWMSP001/0 pin_directoutput P2.2 #50 sampling frequency (fs)=4KHz


You can import the complete project into DAVE 3 or use the hex file. In order to flash the uC you will have to install the Segger J-Link drivers and the J-Flash Lite. Its a free tool to for the debugger of the discovery board. Afther the installation you can flash the hex file:

Inital window of the flashing tool, your device should be detected automatically.
Open the hex file and click on "Program Device".






 Let's turn the whole thing on!

Connect the flashed discovery board to your PC, a new serial port should be detected. Note, that Red Pitaya generates output between -1V ... +1V. Since the XMC will not accept negative voltages you have to set a +offset and reduce the amplitude. Find the optimal values by yourself or check the screenshots below.



Spectrum when only Q channel is active

Set the generator frequency to 500Hz and make sure that the signal is > 0. You should see the 500Hz in the Matlab plots. Since the plotting is running in an while(1) loop you need to apply CTRL+C to exit from the Matlab script. Also, the serial port must be manually close with the fclose(s) command.

Figure: Double sided spectrum of Q input

In a double sided spectrum the half of the energy is displayed at the positive frequency and half the energy at the negative frequency. See the explanation below.