The amplitude value of the IQ data for nrf5340dk is too low

-21	45
17	-47
-16	45
9	-49
-8	46
11	-47
0	48
-19	-47
25	-54
-45	-25
-30	38
31	37
-8	-59
-52	7
-1	50
45	8
-53	-28
-34	40
35	37
43	-25
-59	-1
1	49
48	4
13	-47
-37	49
39	32
41	-26
-22	-40
-2	59
50	5
9	-52
-45	-15
41	41
41	-30
-22	-45
-46	18
59	5
8	-51
-49	-19
-21	44
49	-35
-29	-42
-41	26
17	46
8	-58

hardware:nrf5340dk

The above 45 pairs of IQ data are a set of data that I have received.The maximum amplitude of the IQ data I received seems to be only 128, which means that the quantization of IQ data is only 7 bits, which may result in insufficient accuracy. I would like to know if it is possible to modify the configuration to increase the quantization bit count and thus increase the amplitude value of IQ data? I think the data obtained this way will have higher accuracy.

Thank you in advance for your help!

Parents Reply Children
  • Hello, I made some changes to the code before and printed the 16 bit data directly, but later I found that there seems to be an error in this modification. Can you share how you modified the code? Looking forward to your help!

    Official zephyr code for receiving IQ data:

    static void cte_recv_cb(struct bt_conn *conn, struct bt_df_conn_iq_samples_report const *report)
    {
    	char addr[BT_ADDR_LE_STR_LEN];
    
    	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
    
    	if (report->err == BT_DF_IQ_REPORT_ERR_SUCCESS) {
    		printk("CTE[%s]: samples type: %s, samples count %d, cte type %s, slot durations: "
    			"%u [us], packet status %s, RSSI %i\n", addr,
    			sample_type2str(report->sample_type), report->sample_count,
    			cte_type2str(report->cte_type), report->slot_durations,
    			packet_status2str(report->packet_status), report->rssi);
    
    		if (IS_ENABLED(CONFIG_DF_CENTRAL_APP_IQ_REPORT_PRINT_IQ_SAMPLES)) {
    			for (uint8_t idx = 0; idx < report->sample_count; idx++) {
    				if (report->sample_type == BT_DF_IQ_SAMPLE_8_BITS_INT) {
    					printk(" IQ[%d]: %d, %d\n", idx, report->sample[idx].i,
    					       report->sample[idx].q);
    				} else if (IS_ENABLED(
    					CONFIG_BT_DF_VS_CONN_IQ_REPORT_16_BITS_IQ_SAMPLES)) {
    					printk(" IQ[%" PRIu8 "]: %d, %d\n", idx,
    					       report->sample16[idx].i, report->sample16[idx].q);
    				} else {
    					printk("Unhandled vendor specific IQ samples type\n");
    					break;
    				}
    			}
    		}
    	} else {
    		printk("CTE[%s]: request failed, err %u\n", addr, report->err);
    	}
    }

    The code modifications I made to IQ data reception:

    static void cte_recv_cb(struct bt_conn *conn, struct bt_df_conn_iq_samples_report const *report)
    {
    	char addr[BT_ADDR_LE_STR_LEN];
    
    	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
    
    	if (report->err == BT_DF_IQ_REPORT_ERR_SUCCESS) {
    		printk("%d\n", report->chan_idx);
    
    		for (uint8_t idx = 0; idx < report->sample_count - 22; idx++) {
    			if (report->sample_type == BT_DF_IQ_SAMPLE_8_BITS_INT) {
    				printk(" %d\t%d\t%d\t%d\n", report->sample16[idx].i,
    				       report->sample16[idx].q, report->sample16[idx + 22].i,
    				       report->sample16[idx + 22].q);
    			}
    		}
    	} else {
    		printk("CTE[%s]: request failed, err %u\n", addr, report->err);
    	}
    }

    After experimental testing, I found that the report received by the

    report->sample_type == BT_DF_IQ_SAMPLE_8_BITS_INT

    instead of BT_DF_IQ_SAMPLE_16_BITS_INT. This means that although I can obtain 16 bit quantized data for sample16, the actual data is not accurate. Therefore, I can obtain sample16 only because sample16 and sample8 are defined in the same union.

    union {
            struct bt_hci_le_iq_sample const *sample;
            struct bt_hci_le_iq_sample16 const *sample16;
        };
    So I have two questions:
    1. Can you modify the code to change the received report ->sample_type to BT-DF-IQ-SAMPLE-16-BITS.INT?
    2. Has the code you modified been validated for accuracy through experiments?
    Looking forward to your help!Thank you in advance!
  • Hi

    I found the pull request of this implementation available here, please refer to this for more details. Please make sure you use the Zephyr controller and that the sample_type returns 16_BITS in your application. Much modification shouldn't be needed and you only have to choose the 16 bits in the following in main.c:

    static const char *sample_type2str(enum bt_df_iq_sample type)
    {
    	switch (type) {
    	case BT_DF_IQ_SAMPLE_8_BITS_INT:
    		return "8 bits int";
    	case BT_DF_IQ_SAMPLE_16_BITS_INT:
    		return "16 bits int";
    	default:
    		return "Unknown";
    	}
    }

    I'm not aware of any specific tests being conducted on our end for accuracy measurements, since this is heavily dependent on the Direction Finding algorithm used to convert the IQ data to vector form to get useful data.

    Best regards,

    Simon

Related