3494|3

241

帖子

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平台,该怎么来实现或者操作呢?感觉又被卡住了……

 

查看本帖全部内容,请登录或者注册
此帖出自无线连接论坛

最新回复

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

回复
举报

7032

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

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

此帖出自无线连接论坛

点评

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

回复

241

帖子

0

TA的资源

纯净的硅(初级)

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

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

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

回复

1

帖子

0

TA的资源

一粒金砂(初级)

4
 

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

此帖出自无线连接论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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