Extracting Coherent and Calibrated IQ Data for 5xRX from Kraken via Ethernet DAQ (heimdall_daq_fw)

Hello Kraken SDR Community,

I am currently exploring DOA (Direction of Arrival) in various environments such as MATLAB Simulink. Using the RTL-SDR block in Simulink, I managed to receive data from all channels, but the lack of synchronization in the data prevents further progress.

The heimdall_daq_fw works excellently, but I am only interested in its calibration and SDR configuration features, without the DOA processing components. My goal is to extract IQ data for 5 channels in frames, may be formatted as follows: each IQ pair consists of int16 (2 bytes), resulting in 5 columns for the channels and 1024 rows for the samples per frame, creating a 1024x5 matrix. This extracted data will significantly speed up computations since DOA DSP processing and web page plotting on R.Pi (other mini PC) are unnecessary for my application.

I have two main questions:

  1. At which point in the heimdall_daq_fw can we extract this synchronized IQ data and transmit it via ethernet or other fast protocol? Any guidance or references on this would be greatly appreciated.
  2. To increase the DAQ speed, would implementing an FPGA or DSP system be the best solution? If so, could you provide advice on where to start with this approach?

Thank you for your assistance.

Best regards,

For heimdall I would suggest looking at the GitHub - krakenrf/gr-krakensdr code to see how to connect to heimdall via Ethernet and get the coherent IQ data out. I’m not very familiar with custom MATLAB blocks, but I believe you should be able to replicate similar code in MATLAB as long as there is some way to read data from Ethernet.

The DAQ speed is limited by the CPI block size. A block of data is collected over X ms, and that block of data is used in DOA processing. By default it is set to about 436 ms per block. You can try to decrease that time by changing the DAQ settings, but less data collected also means results could be poorer due to less processing gain.

A Pi 4 or Pi 5 is fast enough to run the DAQ at full speed, so there wouldn’t be much advantage to using an FPGA or DSP.

1 Like

Thank you very much for your response. As per your instructions I was able to get the up data from server via Ethernet using code of gnu kraken block. I took that class and modified slightly to get and save data to class variable. In main program there is while loop which sends this class variable data to matlab via tcpip localhost. But the since data size is quite big (2^20 x 5) 64 but samples, so it becomes difficult for matlab to process.

I am confused about cpi block length (2^20), what is cpi and why its length is so big. Can’t we take less number of samples from firmware? Or we have to get this size always. If we read 2^20 samples, does all sample have data or some are zeros as well in calibration and later.

Can’t we write a block for simulink, similar to gnu radio block. Because simulink and matlab has tons of tools to play with rf data.

Further I have noticed that signal is decimated via 128 with 640 taps. But when I do it, I loose the signal peak in fft. I don’t know where I am making mistake.

Sorry for typos, typed from mobile device.


CPI is the “coherent processing interval”. Basically it’s a block of coherent data that is collected, and that block of data is sent to DSP algorithms like DoA calculations for processing. This is because algorithms like DoA calculations require a block of data to work on.

You can indeed reduce the CPI if you want, but reducing it could result in poorer results from your DSP as more data yields more processing gain, which means better SNR, and better results.

Once heimdall’s calibration is done, the samples will be all data.

Unfortunatley I am not familiar enough with MATLAB Simulink to give advice on that. When decimating do you mean that you are decimating in heimdall, or in MATLAB? When you decimate you are essentially zooming in on the center of the spectrum. If your signal is not centered, you will need to shift the spectrum while decimating.

Totally agree with you that Lagos like DoA works on frames of data, but such a large size frame, very strange for me.
I tried decimation once I receive the signal in python code. (Modified code of gnu radio block).

3 questions plz.
Is my approach of receiving the data from heimdall and updating a class variable, running in a thread. And then getting that data via a get-iq-samples() function in while loop of main function, a good approach? There is no buffer or que utilized (like used in gnu radio block).

Since data is 8 bit coming from adc, can’t we rely on 16bit float I and 16 bit q, instead of 32bit float?.
If we decimate data in heimdall/ receiving code,

do we have any measure, how much result will be come poorer for a some amount of decimation?

Since I want to run hiemdall_only at startup, for that purpose I have edited the script /boot/start_kraken.sh.
the contents of this script are,


# This script is run on startup by a systemd service at /lib/systemd/system/krakensdr.service
sleep 2
cd /home/krakenrf/krakensdr_doa

But unlike ./kraken_doa_start.sh script, the ./heimdall_only_start.sh won’t start at startup.

Found the solution,

the default contents of ./heimdall_only_start.sh will be,


#source /home/krakenrf/miniforge3/etc/profile.d/conda.sh <- required for systemd auto startup (comment out eval and use source instead)
eval "$(conda shell.bash hook)"
conda activate kraken

sleep 2

cd heimdall_daq_fw/Firmware
#sudo ./daq_synthetic_start.sh
sudo env "PATH=$PATH" ./daq_start_sm.sh

uncomment the second line and comment the third line,


source /home/krakenrf/miniforge3/etc/profile.d/conda.sh #<- required for systemd auto startup (comment out eval and use source instead)
#eval "$(conda shell.bash hook)"
conda activate kraken

sleep 2

cd heimdall_daq_fw/Firmware
#sudo ./daq_synthetic_start.sh
sudo env "PATH=$PATH" ./daq_start_sm.sh

it worked now.

You don’t need a buffer if you are okay with possibly dropping some frames.

If it’s already in float format the 8-bitness won’t matter. I think you mean to keep it as 2x 8-bit ints? Going down to 16-bit float will lose precision but it might not matter.

Decimation won’t make the result poorer unless it was a wideband signal.