3353|3

206

帖子

0

TA的资源

纯净的硅(初级)

楼主
 

【安信可UWB室内定位模组NodeMCU-BU01】05.移植准备:测距功能代码分析 [复制链接]

上一篇帖子我们通过阅读代码分析了原厂对于NodeMCU-BU01的初始化配置过程,通过USART中断入口函数定位到了AT指令解析运行及相对应的功能调用函数的具体实现;这篇帖子我们来看一下,这份功能代码是怎么一个测距流程的……

首先我们还是先看一下对应的AT指令功能调用函数的实现部分(仅与测距相关的部分):

 

1、AT+anchor_tag指令:这个AT指令的功能,是将当前的NodeMCU-BU01设置为基站还是标签模式,将设置数据写入到FLASH的USER_FLASH_BASE地址进行存储;

int AT_CmdFunc_ANCHOR_TAG(int opt,int argc, char *argv[])
{
	//phy_printf("aliGenie set opt:%d\r\n",opt);
	if(opt==EXECUTE_CMD)
	{
		
		
			uint16_t write=66;
			FLASH_WriteMoreData(USER_FLASH_BASE,&write,1);
		
		
	}
	else if(opt==SET_CMD)
	{
		char *get=NULL;
		get=strtok(argv[0],",");
		uint16_t Set=atoi(get);
		uint16_t write[3]={0};
		
		if(Set==1)
		{
			//uint16_t write=1;
			write[0]=1;
			//FLASH_WriteMoreData(USER_FLASH_BASE,&write,1);
		}
		else if(Set==0)
		{
			write[0]=0;
			//uint16_t write=0;
			//FLASH_WriteMoreData(USER_FLASH_BASE,&write,1);
			
		}
		else
		{
			return -1;
		}
		
		get=NULL;
		get=strtok(NULL,",");
		Set=atoi(get);
		if(Set>=0 && Set<=255)
		{
			write[1]=Set;
			
		}
		else
		{
			return -1;
		}
		
		FLASH_WriteMoreData(USER_FLASH_BASE,write,2);
		
	}
	else if(opt==QUERY_CMD)
	{
		uint16_t buff[3]={0};
		FLASH_ReadMoreData(USER_FLASH_BASE,buff,3);
	
		printf("buff0:%d\r\n",buff[0]);
		printf("buff1:%d\r\n",buff[1]);
		printf("buff2:%d\r\n",buff[2]);
		
	}
	
	
	return 1;
}

 

2、AT+interval指令:这个AT指令的功能是设定测距的间隔时间,单位是毫秒,设置值范围在5~50之间,而AT指令的参数,被赋值到ANCHOR_REFRESH_COUNT_set这个全局变量中进行存储;

int AT_CmdFunc_interval(int opt,int argc, char *argv[])
{
	//phy_printf("aliGenie set opt:%d\r\n",opt);
	if(opt==EXECUTE_CMD)
	{
		
	}
	else if(opt==SET_CMD)
	{
		char *get=NULL;
		get=strtok(argv[0],",");
		uint16_t Set=atoi(get);
		if(Set>=5&& Set<=50)
		{
			ANCHOR_REFRESH_COUNT_set=Set;
		}
		else
		{
			return -1;
		}
	
	}
	else if(opt==QUERY_CMD)
	{
		
		
	}
	
	
	return 1;
}

 

3、AT+switchdis指令:这个AT指令的功能就是控制测距的使能,控制开始进行测距和停止测距,而AT指令的设置参数被保存在SWITCH_DIS这个全局变量中;

int AT_CmdFunc_ondis(int opt,int argc, char *argv[])
{
	//phy_printf("aliGenie set opt:%d\r\n",opt);
	if(opt==EXECUTE_CMD)
	{
		
	}
	else if(opt==SET_CMD)
	{
		
		char *get=NULL;
		get=strtok(argv[0],",");
		uint16_t Set=atoi(get);
		
		if(Set==1)
		{
			SWITCH_DIS=1;
		}
		else if(Set==0)
		{
			SWITCH_DIS=0;
		}
		else
		{
			return -1;
		}
	
	}
	else if(opt==QUERY_CMD)
	{
		
		
	}
	
	
	return 1;
}

 

那测距过程,是如何通过这些AT指令来相互配合实现的呢?

 

首先,我们还是看MAIN函数的实现:在进行外设初始化完成后,接着对DW1000进行复位操作,在低SPI速率的情况下,对DWT进行初始化操作,等初始化完成后再提升SPI的通讯速率;然后就是配置DWT的设置参数;接着从FLASH中读取AT配置的工作模式,如果在没有配置的情况下,默认为基站模式;接下来就是根据工作模式来进行不同的函数调用;

int main(void)
{
    uint8 anthor_index = 0;
    uint8 tag_index = 0;

    uint8 Semaphore_Enable = 0 ;
    uint8 Waiting_TAG_Release_Semaphore = 0;
    int8 frame_len = 0;
		//lable1:
    /* Start with board specific hardware init. */
    peripherals_init();
	
    printf("hello dwm1000!\r\n");

    /* Reset and initialise DW1000.
     * For initialisation, DW1000 clocks must be temporarily set to crystal speed. After initialisation SPI rate can be increased for optimum
     * performance. */

	reset_DW1000(); /* Target specific drive of RSTn line into DW1000 low for a period. */
    spi_set_rate_low();

		
    if(dwt_initialise(DWT_LOADUCODE) == -1)
    {
        printf("dwm1000 init fail!\r\n");
        OLED_ShowString(0,0,"INIT FAIL");
        while (1)
        {
					  //STM_EVAL_LEDOn(LED1);
					GPIO_SetBits(GPIOC,GPIO_Pin_13);
            deca_sleep(1000);
            //STM_EVAL_LEDOff(LED1);
					GPIO_ResetBits(GPIOC,GPIO_Pin_13);
            deca_sleep(1000);
					
 
        }
    }
    spi_set_rate_high();

    /* Configure DW1000. See NOTE 6 below. */
    dwt_configure(&config);
    dwt_setleds(1);
		
    /* Apply default antenna delay value. See NOTE 1 below. */
    dwt_setrxantennadelay(RX_ANT_DLY);
    dwt_settxantennadelay(TX_ANT_DLY);
    OLED_ShowString(0,0,"INIT PASS");

    printf("init pass!\r\n");
		printf("AIT-BU01-DB V100 T2020-5-17\r\n");
		
		
    AnchorList[0].x =0.12;
    AnchorList[0].y =0.34;
    AnchorList[0].z =0;

    AnchorList[1].x =0.25;
    AnchorList[1].y =0;
    AnchorList[1].z =0;

    AnchorList[2].x =0;
    AnchorList[2].y =0;
    AnchorList[2].z =0;
    int rx_ant_delay =32880;
    int index = 0 ;
		
	extern UserSet UserSetNow;
	uint16_t buff[3]={1,0,0xff};//ĬèÏÖμ
	FLASH_ReadMoreData(USER_FLASH_BASE,buff,3);
	if(buff[0]==1)
	{
		UserSetNow.ANCHOR_TAG=1;
	}
	else if(buff[0]==0)
	{
		UserSetNow.ANCHOR_TAG=0;
	}
	else
	{
		UserSetNow.ANCHOR_TAG=1;
	}
	
//#ifdef ANTHOR
	
if(UserSetNow.ANCHOR_TAG==1)
{
	if(buff[1]>=0 && buff[1]<=255)
	{
		UserSetNow.ID=buff[1];
		ANCHOR_IND=UserSetNow.ID;
	}
	printf("device:anchor ID:%d\r\n",ANCHOR_IND);
	
			    Anchor_Array_Init();
    /* Loop forever initiating ranging exchanges. */
    OLED_ShowString(0,0,"DS TWR ANTHOR");
    //OLED_ShowString(0,2,"Distance:");

    //KalMan_PramInit();
		ANTHOR_MEASURE();

	
}

//#endif

//#ifdef TAG

if(UserSetNow.ANCHOR_TAG==0)
{
	
	if(buff[1]>=0 && buff[1]<=255)
	{
		UserSetNow.ID=buff[1];
		TAG_ID=UserSetNow.ID;
		MASTER_TAG=TAG_ID;
	}
	
	printf("device:TAG ID:%d\r\n",UserSetNow.ID);
	if(TAG_ID == MASTER_TAG)
    {
        OLED_ShowString(0,0,"DS MASTER TAG:");
    }
    else
    {
        OLED_ShowString(0,0,"DS SLAVE TAG:");
    }
		
    /* Set expected response's delay and timeout. See NOTE 4 and 5 below.
     * As this example only handles one incoming frame with always the same delay and timeout, those values can be set here once for all. */
    dwt_setrxaftertxdelay(POLL_TX_TO_RESP_RX_DLY_UUS);
    dwt_setrxtimeout(RESP_RX_TIMEOUT_UUS);
    

    //OLED_ShowString(0,2,"Distance:"); chnage by johhn

    if(TAG_ID ==  MASTER_TAG)
    {
        Semaphore_Enable = 1 ;
        Semaphore_Init();
        Waiting_TAG_Release_Semaphore = 0;
    }
    else
    {
        Semaphore_Enable = 0 ;
    }
    //Master TAG0
			
		TAG_MEASURE();
  


}
		
//#endif
}

 

在基站模式下,程序中通过OLED在其显示“DS TWR ANTHOR”信息,通过调用ANTHOR_MEASURE函数来完成具体的功能;

在标签模式下,程序中根据当前TAG_ID的主从通过OLED在其显示“DS MASTER TAG”或者“DS SLAVE TAG”信息,通过调用TAG_MEASURE函数来写成具体的功能;

 

而TAG_MEASURE和ANTHOR_MEASURE这两个函数在整个工程文件中,只在lib.h中进行了声明,也没有具体的实现……所以这函数具体实现的代码是被封装了STM3210E-EVAL.lib这个库文件里了吗?那么我想把这个UWB功能移植到其它的MCU平台,该怎么来实现或者操作呢?感觉又被卡住了……

 

此帖出自RF/无线论坛

最新回复

确实,搞那么多,我想自己画板子买bu01弄进去,看到这个代码真的劝退   详情 回复 发表于 2022-7-20 10:31
点赞 关注
个人签名We are a team and we work as a team !
 

回复
举报

6802

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

功能移植到其它的MCU平台需要考虑兼容性,因为不同平台包含与编译器兼容的类型说明与定义

此帖出自RF/无线论坛

点评

说得是没错,但对于NodeMCU-BU01开发板来说,平台就是STM32呀,平台都确定了,干嘛还封装一个LIB呢,直接说这套代码仅是在STM32F103平台上适用就可以了呀……封装代码就有点……我本来是想  详情 回复 发表于 2022-2-28 08:58
 
 

回复

206

帖子

0

TA的资源

纯净的硅(初级)

板凳
 
Jacktang 发表于 2022-2-28 08:33 功能移植到其它的MCU平台需要考虑兼容性,因为不同平台包含与编译器兼容的类型说明与定义

说得是没错,但对于NodeMCU-BU01开发板来说,平台就是STM32呀,平台都确定了,干嘛还封装一个LIB呢,直接说这套代码仅是在STM32F103平台上适用就可以了呀……封装代码就有点……我本来是想用安信可的UWB应用到自己项目上,对比一下的,现在倒好,代码都移植不了……之前用的研创物联的UWB,和安信可的内核一样都是DW1000,也没见人家封装源代码哈……

此帖出自RF/无线论坛
个人签名We are a team and we work as a team !
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

4
 

确实,搞那么多,我想自己画板子买bu01弄进去,看到这个代码真的劝退

此帖出自RF/无线论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
快速回复 返回顶部 返回列表