Error in Angle of Arrival Calculation for Direction Finding

Hello

We are using nRF5340 as our EVK with a 12 antenna array plate(4x4 with center 4 ones not being there). Our beacon uses nRF52833.

We used Nordic's sample codes- 'Direction Finding Central' to flash our EVK and 'Direction Finding Peripheral' to flash our beacon.

We tried using MUSIC algorithm on a python pipeline to obtain AOA.

However, when we tried to find AOA, we are not getting correct values. It is either completely random values or angle doesn't change at all. 

We get the IQ samples-

When plotted, we can see something like this:

What can we do about this?

Parents
  • Hello,

    It is either completely random values or angle doesn't change at all.

    Did you change anything between these two observations? Because they are two very different cases. 

    Please see the readme.rst file for the central_direction_finding sample:

    * Guard period of 4 µs. There is a gap before the actual CTE reception and the adjacent PDU transmission to avoid interference.
    * Reference period where a single antenna is used for sampling. The spacing between the samples is 1 µs and the period duration is 8 µs.
    * Switch-sample period that is split into switch and sample slots. The length of each slot can be either 1 or 2 µs.

    Can you try the nRF Connect for Desktop -> Direction Finding app (source is on github), using your HW, and we can see whether this works on your HW. This should help indicating whether this is a HW or SW issue.

    BR,
    Edvin

  • Thankyou for the reply.

    Can you please share the source for Direction Finding App since we are not able to find it on github?

  • Hello,
    Sorry. I read some internal tickets that suggested this a bit too quick, and this seems to not be your solution. 

    Unfortunately, after discussing this with our product management, it seems that what we deliver, are the samples that you are using, which can provide the raw QI samples, but how to handle the data from there, that is up to the customer. 

    I tried to dig a bit into this using AI, and it seems like there are some common pitfalls:

    -------------------

    Fix #1: Compensate CFO using the 8 reference samples (most common cause of "random")
    This is the single most likely reason for random AoA. The standard procedure:

    Take the first 8 samples (reference period, same antenna, 1 µs apart).
    Estimate the phase rotation rate ω (e.g. average of angle(s[k+1] · conj(s[k]))).
    For every antenna sample at time t, multiply by exp(-jωt) to de-rotate it back to a common time reference.
    Then build the spatial covariance matrix and run MUSIC.
    Skipping this is the classic "MUSIC gives garbage" bug — the covariance matrix ends up dominated by CFO, not direction.

    Fix #2 — Map samples → antennas correctly (de-interleaving)
    The IQ report is just a flat list of I/Q values; the customer's code has to know which physical antenna each sample came from:

    Samples 0–7 → reference antenna (dfe-pdu-antenna = 0), discard for the spatial step.
    Samples 8+ → follow the ant_patterns[] order, looping when exhausted.
    In the unmodified sample, ant_patterns[] and the antenna count are tuned for Nordic's 12-patch reference board:

    (in direction_finding_central/src/main.c, with dfe-antenna-num = <12> in the net-core overlay).

    With 37 antenna samples over 12 antennas, the sequence loops ~3×. If the de-interleave or the loop indexing is off by even one, the steering vectors won't line up and the result is random.

    -------------------

    I believe a clue here is the first 8 samples. These are calibration samples. Use this to calculate the Carrier Frequency Offset (CFO).  

    Best regards,

    Edvin

Reply
  • Hello,
    Sorry. I read some internal tickets that suggested this a bit too quick, and this seems to not be your solution. 

    Unfortunately, after discussing this with our product management, it seems that what we deliver, are the samples that you are using, which can provide the raw QI samples, but how to handle the data from there, that is up to the customer. 

    I tried to dig a bit into this using AI, and it seems like there are some common pitfalls:

    -------------------

    Fix #1: Compensate CFO using the 8 reference samples (most common cause of "random")
    This is the single most likely reason for random AoA. The standard procedure:

    Take the first 8 samples (reference period, same antenna, 1 µs apart).
    Estimate the phase rotation rate ω (e.g. average of angle(s[k+1] · conj(s[k]))).
    For every antenna sample at time t, multiply by exp(-jωt) to de-rotate it back to a common time reference.
    Then build the spatial covariance matrix and run MUSIC.
    Skipping this is the classic "MUSIC gives garbage" bug — the covariance matrix ends up dominated by CFO, not direction.

    Fix #2 — Map samples → antennas correctly (de-interleaving)
    The IQ report is just a flat list of I/Q values; the customer's code has to know which physical antenna each sample came from:

    Samples 0–7 → reference antenna (dfe-pdu-antenna = 0), discard for the spatial step.
    Samples 8+ → follow the ant_patterns[] order, looping when exhausted.
    In the unmodified sample, ant_patterns[] and the antenna count are tuned for Nordic's 12-patch reference board:

    (in direction_finding_central/src/main.c, with dfe-antenna-num = <12> in the net-core overlay).

    With 37 antenna samples over 12 antennas, the sequence loops ~3×. If the de-interleave or the loop indexing is off by even one, the steering vectors won't line up and the result is random.

    -------------------

    I believe a clue here is the first 8 samples. These are calibration samples. Use this to calculate the Carrier Frequency Offset (CFO).  

    Best regards,

    Edvin

Children
No Data
Related