Trouble Combing nrf_dm and lvgl.

Hi,

We've been working on taking the distance measurements from the nrf_dm sample and displaying them on a waveshare e-paper 2.13 in display. We've been able to get both of these parts running separately, the distance measurement works, and so does the display, but combining them has proven to be difficult. 

So far we have created a work thread, and defined the function that will print to the e-paper display. 

void print_me() {
	char count_str[11] = {0};
	lv_obj_t *count_label; 
	
	float best_test =3.14;

	count_label = lv_label_create(lv_scr_act());
	lv_obj_set_style_text_font(count_label, &lv_font_montserrat_36, LV_PART_MAIN | LV_STATE_DEFAULT);
	lv_obj_align(count_label, LV_ALIGN_RIGHT_MID, 0, 0);
	
	sprintf(count_str, "%.2f", best_test);
	lv_label_set_text(count_label, count_str);
	// //lv_label_set_text(count_label, "hello");
	lv_task_handler();
}


/****************/
/* WORK THREADS */
/****************/
// Define stack size used by each thread
#define WORQ_THREAD_STACK_SIZE  4096

/* STEP 2 - Set the priorities of the threads */
#define WORKQ_PRIORITY   4

// Define stack area used by workqueue thread
static K_THREAD_STACK_DEFINE(my_stack_area, WORQ_THREAD_STACK_SIZE);

// Define queue structure
static struct k_work_q offload_work_q = {0};

/* STEP 7 - Create work_info structure and offload function */
struct work_info {
    struct k_work work;
    char name[25];
} my_work;

void offload_function(struct k_work *work_tem)
{
	print_me();
}

void submit_to_print_me_queue(){
	/* STEP 9 - Submit the work item to the workqueue instead of calling emulate_work() directly */
	/* Remember to comment out emulate_work(); */
	k_work_submit_to_queue(&offload_work_q, &my_work.work);
}

void print_best_work_queue_init()
{
	/* STEP 8 - Start the workqueue, */
	/* initialize the work item and connect it to its handler function */ 
	k_work_queue_start(&offload_work_q, my_stack_area,
					K_THREAD_STACK_SIZEOF(my_stack_area), WORKQ_PRIORITY,
					NULL);

	strcpy(my_work.name, "print me wq");

	k_work_init(&my_work.work, offload_function);
}

Then after the section in peer.c where the nrf_dm sample prints the measurements to the serial monitor, we want to take in the best result value and pass it to the print_me function.

/* FIFO QUEUE FOR "BEST" DM DATA */
K_FIFO_DEFINE(my_fifo);

struct data_item_t {
    void *fifo_reserved;   /* 1st word reserved for use by FIFO */
    float best; // holds best DM value
};

/* CONSUMER OF FIFO DATA */
void consumer_thread()
{
    struct data_item_t  *rx_data;

    while (1) {
        rx_data = k_fifo_get(&my_fifo, K_FOREVER); //wait here forever until something gets put in fifo queue

		BEST_DM_VALUE = rx_data->best; // copy best data to a global variable

        /* process FIFO data item */
        submit_to_print_me_queue(); // submit the printme function to the work queue thread
    }
}



static void print_result(struct dm_result *result)
{
	if (!result) {
		return;
	}

	const char *quality[DM_QUALITY_NONE + 1] = {"ok", "poor", "do not use", "crc fail", "none"};
	char addr[BT_ADDR_LE_STR_LEN];

	bt_addr_le_to_str(&result->bt_addr, addr, sizeof(addr));

	printk("\nMeasurement result:\n");
	printk("\tAddr: %s\n", addr);
	printk("\tQuality: %s\n", quality[result->quality]);

	printk("\tDistance estimates: ");
	if (result->ranging_mode == DM_RANGING_MODE_RTT) {
		printk("rtt: rtt=%.2f\n", result->dist_estimates.rtt.rtt);
	} else {
#ifdef CONFIG_DM_HIGH_PRECISION_CALC
		printk("mcpd: high_precision=%.2f ifft=%.2f phase_slope=%.2f "
			"rssi_openspace=%.2f best=%.2f\n",
			result->dist_estimates.mcpd.high_precision,
			result->dist_estimates.mcpd.ifft,
			result->dist_estimates.mcpd.phase_slope,
			result->dist_estimates.mcpd.rssi_openspace,
			result->dist_estimates.mcpd.best);

			/* send data to consumers */
			float best = result->dist_estimates.mcpd.best; //copy to float "best"
        	k_fifo_put(&my_fifo, &best); //push into fifo queue
#else
		printk("mcpd: ifft=%.2f phase_slope=%.2f rssi_openspace=%.2f best=%.2f\n",
			result->dist_estimates.mcpd.ifft,
			result->dist_estimates.mcpd.phase_slope,
			result->dist_estimates.mcpd.rssi_openspace,
			result->dist_estimates.mcpd.best);
#endif
	}
}

When I flash the program, the distance measurement initializes, but does not print any measurements and the display stays blank. Previously it was printing one distance measurement and then, MPU stack overflow error and it would reset. This was fixed by increasing the stack size. Any help figuring out what is going wrong with the distance meausrement and why it  won't print to the display would be appreciated. 

Thank you

  • Hi Jennifer

    Is your main handling these threads in the right order, so that there actually is some data to print available before the screen tries to print it. And do you wait for enough time after a distance measurement has been done to let the screen print the current value, or does the DM library just continuously doing measurements and not letting the data be forwarded to this screen?

    At first glance I'm not able to see something obviously wrong, but do you see anything from logging that might point to what is going wrong? Any functions returning error codes that might give some insight into what's going on here? Can you also explain what stack you increased the size of to fix the MPU stack overflow exactly?

    Best regards,

    Simon

Related