Relative phase between antenna singals not consistent between UDP receiver restarts

Hi, i am analyzing the raw iq data coming from Heimdall in my own python scripts and noticed that for each time the IQ udp receiver reconnects, the phase seem to switch to a new random phase, even if the antenna and signal source setup is identical.

The Phase is consistent only changing ± 5 degrees for minutes at a time, but for every restart the relative signal phases switches to a new random phase. Both the phase and delay calibration reports back that it is good.

I also ask for the frequency to be set, but if i ask the frequency to be set to the same freq during a run without restarting the udp receiver, it will not change the phase.

If my understanding is correct, the “relative phase” between antenna singals should not change. Am i misunderstanding something or is it something else that explains the results?

Images of initial phase:

Image of phase after restarting the udp receiver:

On every reboot or retune the phases in the tuner are randomly scrambled. Each time that happens the Kraken reacquires coherence by comparing with Tuner 0, aligning USB samples (only after a full reboot), and creating a mew phase compensation vectors.

That makes sense to me as well. But wouldn’t that mean that the relative phase would stay the same after every re-tune, given that the received data is calibrated? If I pass the data toward a music algorithm, the estimated DOA is scrambled to a random value as well.

I don’t quite understand exactly what you are doing.

Do you mean that you have recorded IQ data from Heimdall, but every time you pass it through your MSUIC algorithm the result is different?

I have used the Krakensdr_doa udp receiver to get live iq data from heimdall. Then the code bandpass the signal around the strongest frequency (found via FFT) via the cannelize function in Krakensdr_doa. Then it calculate the correlation matrix between the antannas by multiplying the data with its complex conjugate transposed version. When creating the graph, i just extracted the first column of the matrix.

Now, when i use a PPT radio to generate a signal, both the measured phase and the estimated DOA stays constant during the whole test. But when i restart the Udp receiver during a test, the phase gets scrambled and the estimated DOA also gets scrambled. Its worth noting that i reject any data where the IQ sync or delay sync is not accepted.

When i check the heimdall logs, nothing seems out of the ordinary. Ill publish any code or logs, if it will be of any use:)

I assume you get correct results when using our DoA software?

I talked with our expert developer on DoA, but he’s also not sure on what could be causing your issue. He suggested that you might want to test your code first with simulated data to try and troubleshoot.

Yes, the DoA softare of yours works well:)

I pulled down the code on a fresh ubuntu 22 install and set up the code again, using as much as possible of the krakensdr code. Both the receiver class and channelize function is copied form the github page:

`data_queue = np.ndarray
receiver = ReceiverRTLSDR(data_queue, data_interface=“eth”)

    receiver.eth_connect()

    vfo_bw = 12_500

    receiver.set_center_freq(set_frequency)

    time.sleep(5)
    print("Starting to receive")
    time.sleep(1)

    num_success_receives = 0

    for i in range(0, 1000):

        receiver.get_iq_online()

        if isinstance(receiver.iq_samples, int):

            print("No value gotten")

        else:

            freq_data = np.fft.fftshift(np.fft.fft(receiver.iq_samples, axis=1))

            if receiver.iq_header.delay_sync_flag and receiver.iq_header.iq_sync_flag:

                max_val_idx = np.argmax(abs(freq_data[1, :]))

                n_samples = freq_data[0, :].size / 2.0

                num_success_receives = num_success_receives + 1

                freq = (receiver.iq_header.sampling_freq / 2) * ((max_val_idx - n_samples) / n_samples)

                print("max_freq val idx is: ", freq + receiver.iq_header.rf_center_freq)

                decimation_factor = receiver.iq_header.sampling_freq // vfo_bw

                fir_order_factor = 2

                vfo_channel = channelize(
                    receiver.iq_samples,
                    freq,
                    decimation_factor,
                    fir_order_factor,
                    receiver.iq_header.sampling_freq,
                )


                signal_diff = (1 / receiver.iq_header.active_ant_chs) * np.dot(vfo_channel[0, :],
                                                                               vfo_channel[:, :].conj().T)

                angle_diff = np.angle(signal_diff, deg=True)

`

Does this code make it any clearer what is happening?

When you are testing the phase, have you forced the noise source to remain always on?

Kinda big update! If the heimdall server is restarted each time before the receiver is connected, it works flawlessly. The measured phase is consistent at every startup:)

It seems that if you reconnect with a new receiver during a data transfer, the sent data seems to get scrambled. Almost like the data indexing in the packages get shifted, creating essentially random noise. in the sent data. I haven’t checked the heimdall code for the indexing so the error might still be at my side, but there might some data transfer tings that should be reset every time a new connection is made?

And the noise turns off after being calibrated as expected:)

I’m not aware of anything that needs to be reset when making a connection. Perhaps you are not separating the header from the data correctly?