使用STM32W108无线节点完成基于接收信号强度指示(RSSI:Received SignalStrength Indication)的N次三边质心加权定位,对移动中的节点实时进行定位,并将定位结果发送到汇集中心。图15.1为定位实验的实际场景,所有实验在室内完成,共使用9个节点,1个移动节点,8个信标节点。
图15.1.
定位实际场景
基于第10章介绍的SimpleMac协议栈,对程序进行删减更改,下面给出更改部分代码:
文件solar-system.c相关内容:
函数processRxPacket():
/************************************************************************** 功能描述:对接收的数据包进行解析解码处理,并根据不同类型的数据包执行不同的操作,数据包信息通过数据包回调函数保存在结构体变量rxData中 输入参数:无 输出参数:无 ***************************************************************************/ void processRxPacket(void) { …… //检查确定数据包帧类型,代码中只用到了FT_DATA类型 switch(rxData.packet[1]&0x7) { case FT_DATA: RX_DETAILS(printf("FT_DATA\r\n");) packetType = (FT_DATA<<4); break; case FT_MAC_COMMAND: RX_DETAILS(printf("FT_MAC_COMMAND\r\n");) packetType = (FT_MAC_COMMAND<<4); break; default: RX_DETAILS(printf("Unknown frame type\r\n");) goto stopProcessing; }; //判断数据包中是否有PAN ID信息 if((rxData.packet[1]&0x40)!=0x40) { pktHasSrcPanId=TRUE; srcAddrOffset = 2; } //四种不同的地址类型 switch(rxData.packet[2]) { …… } RX_DETAILS( if(pktHasSrcPanId) { printf("src pan = 0x%04X\r\n", srcPanId); } ) //判断数据包长度是否满足足够的长度保存负载类型 if(rxData.packet[0]<payloadStart) { RX_DETAILS(printf("Length byte too short\r\n");) goto stopProcessing; } //通过帧类型及负载类型计算数据包类型 packetType |= (rxData.packet[payloadStart]<<0); RX_DETAILS(printf("packet type = 0x%02X\r\n", packetType);) //不同的数据包类型执行不同的操作 switch(packetType) { case (GENERIC_DATA_PACKET): //普通类型数据包,Sun节点和Planet节点都会收到 RX_DETAILS(printf("GENERIC_DATA_PACKET\r\n");) printf("%d\n", rxData.rssi);//RSSI输出 break; …… default: RX_DETAILS(printf("Unknown payload type\r\n");) goto stopProcessing; } stopProcessing: rxData.packetBeingProcessed = FALSE; } |
函数joinCmd():
/************************************************************************** 功能描述:Planet广播搜索Sun节点,完成加入网络 输入参数:无 输出参数:无 *************************************************************************/ void joinCmd(void) { …… #ifdef PLANET_ROLE autoSendRate = 1; //设置节点向Sun节点发送数据包频率,加快频率,用于计算RSSI halSetLed(LED_D4); //点亮LED4 #endif …… } |