1、由于是三点定位。 我们需要一个1. 协调器一个 2. 路由器两个 3.终端设备一个基础知识:协调器负责组网,也可以当设备用,路由器负责转发,也可以当设备用。1. 协调器 , 和两个路由器 定时 发送心跳包(带有自己的ID 1和2和3)。2.终端设备 会收到 协调器 和 两个路由器发的心跳包。 取出这三种信号强度。3. 终端设备 将这 3条信号强度数据发送给 协调器。4.协调器 接收到这 3条信号强度值传给pc机。pc机进行运算。算出带定位的设备的坐标。(算法参看另一篇经验 “如何用zigbee实现三角立体定位-算法”)
2、协调器 初始化的修改 设置串口功熹栳缂靖能void GenericApp_Init( uint8 task_id ){ halUARTCfg_t uartConfig; //20131014 Ge荏鱿胫协nericApp_TaskID = task_id; GenericApp_NwkState = DEV_INIT; GenericApp_TransID = 0; // Device hardware initialization can be added here or in main() (Zmain.c). // If the hardware is application specific - add it here. // If the hardware is other parts of the device add it in main(). GenericApp_DstAddr.addrMode = (afAddrMode_t)AddrNotPresent; GenericApp_DstAddr.endPoint = 0; GenericApp_DstAddr.addr.shortAddr = 0; // Fill out the endpoint description. GenericApp_epDesc.endPoint = GENERICAPP_ENDPOINT; GenericApp_epDesc.task_id = &GenericApp_TaskID; GenericApp_epDesc.simpleDesc = (SimpleDescriptionFormat_t *)&GenericApp_SimpleDesc; GenericApp_epDesc.latencyReq = noLatencyReqs; // Register the endpoint description with the AF afRegister( &GenericApp_epDesc ); // Register for all key events - This app will handle all key events RegisterForKeys( GenericApp_TaskID ); uartConfig.configured = TRUE;//20131014 uartConfig.baudRate = HAL_UART_BR_115200; uartConfig.flowControl = FALSE; HalUARTOpen(1, &uartConfig);//20131014 ZDO_RegisterForZDOMsg( GenericApp_TaskID, End_Device_Bind_rsp ); ZDO_RegisterForZDOMsg( GenericApp_TaskID, Match_Desc_rsp );}
3、协调器或者路由器定时6秒发一个心骇螺搭翳跳包uint16 GenericApp_ProcessEvent( ui荏鱿胫协nt8 task_id, uint16 events ){ afIncomingMSGPacket_t *MSGpkt; afDataConfirm_t *afDataConfirm; // Data Confirmation message fields byte sentEP; ZStatus_t sentStatus; byte sentTransID; // This should match the value sent (void)task_id; // Intentionally unreferenced parameter if ( events & SYS_EVENT_MSG ) { MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID ); while ( MSGpkt ) { switch ( MSGpkt->hdr.event ) { case ZDO_CB_MSG: GenericApp_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt ); break; case KEY_CHANGE: //GenericApp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys ); break; case AF_DATA_CONFIRM_CMD: // This message is received as a confirmation of a data packet sent. // The status is of ZStatus_t type [defined in ZComDef.h] // The message fields are defined in AF.h afDataConfirm = (afDataConfirm_t *)MSGpkt; sentEP = afDataConfirm->endpoint; sentStatus = afDataConfirm->hdr.status; sentTransID = afDataConfirm->transID; (void)sentEP; (void)sentTransID; // Action taken when confirmation is received. if ( sentStatus != ZSuccess ) { // The data wasn't delivered -- Do something } break; case AF_INCOMING_MSG_CMD: GenericApp_MessageMSGCB( MSGpkt ); break; case ZDO_STATE_CHANGE: GenericApp_NwkState = (devStates_t)(MSGpkt->hdr.status); if ( (GenericApp_NwkState == DEV_ZB_COORD) || (GenericApp_NwkState == DEV_ROUTER) || (GenericApp_NwkState == DEV_END_DEVICE) ) { // Start sending "the" message in a regular interval. //osal_start_timerEx( GenericApp_TaskID, // GENERICAPP_SEND_MSG_EVT, // GENERICAPP_SEND_MSG_TIMEOUT ); osal_start_timerEx( GenericApp_TaskID, COORDINATOR_UART_BROADCAST, 6000); //定时6秒 到了会报COORDINATOR_UART_BROADCAST事件 } break; default: break; } // Release the memory osal_msg_deallocate( (uint8 *)MSGpkt ); // Next MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID ); } // return unprocessed events return (events ^ SYS_EVENT_MSG); } if(events & COORDINATOR_UART_BROADCAST) //COORDINATOR_UART_BROADCAST 事件产生 { GenericApp_SendTheMessage(); osal_start_timerEx( GenericApp_TaskID, COORDINATOR_UART_BROADCAST, 6000); //osal_msg_deallocate( (uint8 *)MSGpkt ); // Next //MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID ); return (events ^ COORDINATOR_UART_BROADCAST); } // Send a message out - This event is generated by a timer // (setup in GenericApp_Init()). if ( events & GENERICAPP_SEND_MSG_EVT ) { // Send "the" message //GenericApp_SendTheMessage(); // Setup to send message again //osal_start_timerEx( GenericApp_TaskID, //GENERICAPP_SEND_MSG_EVT, //GENERICAPP_SEND_MSG_TIMEOUT ); // return unprocessed events return (events ^ GENERICAPP_SEND_MSG_EVT); }#if defined( IAR_ARMCM3_LM ) // Receive a message from the RTOS queue if ( events & GENERICAPP_RTOS_MSG_EVT ) { // Process message from RTOS queue //GenericApp_ProcessRtosMessage(); // return unprocessed events return (events ^ GENERICAPP_RTOS_MSG_EVT); }#endif // Discard unknown events return 0;}
4、协调器收到设备发送的数据时通过串口发送给PC。四个字节。static void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pkt ){ //unsigned char buffer[4] = ""; unsigned char buffer[6] = ""; switch ( pkt->clusterId ) { case GENERICAPP_CLUSTERID: osal_memcpy(buffer,pkt->cmd.Data,4); //读取收到的数据 HalUARTWrite(1,buffer,4); //发给PC。4个数据(ID+rssi+温度) break; }}协调器或者路由器的心跳包发送。static void GenericApp_SendTheMessage( void ){ char theMessageData[] = "1"; //1为协调器,2为路由一 3 为路由二 GenericApp_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast; GenericApp_DstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR_DEVALL; GenericApp_DstAddr.endPoint = AF_BROADCAST_ENDPOINT; if ( AF_DataRequest( &GenericApp_DstAddr, &GenericApp_epDesc, GENERICAPP_CLUSTERID, (byte)osal_strlen( theMessageData ), (byte *)&theMessageData, &GenericApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS ) { int i=0; i++; }}
5、终端设备加了一个读温度函数//TEMPERATURE SENSORint8 readTemp(void){ static uint16 reference_voltage; static uint8 bCalibrate = TRUE; uint16 value; int8 temp; ATEST = 0X01; TR0 |=0X01; ADCIF = 0; ADCCON3= (HAL_ADC_REF_115V | HAL_ADC_DEC_256 | HAL_ADC_CHN_TEMP); while(!ADCIF); ADCIF = 0; value = ADCL; value |= ((uint16) ADCH) << 8; value >>= 4; if(bCalibrate) { reference_voltage = value ; bCalibrate = FALSE ; } temp = 22+((value - reference_voltage) /4); return temp;}终端收到路由或者协调器的心跳时就将 ID(1代表协调器,2代表路由一 ,3代表路由二) 和 rssi 和 温度 发给协调器。共四个字节static void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pkt ){ int8 tvalue; tvalue = readTemp(); //if(strlen(cmd.Data) == 2) unsigned char buffer[6] = ""; afAddrType_t my_DstAddr; osal_memcpy(buffer,pkt->cmd.Data,1); //读取收到的数据 可能是1,2,3之一 buffer[1] = pkt->rssi; buffer[2] = tvalue/10 + '0'; buffer[3] = tvalue%10 + '0';my_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;////my_DstAddr.endPoint = GENERICAPP_ENDPOINT;my_DstAddr.addr.shortAddr = 0x0000;AF_DataRequest( &my_DstAddr, &GenericApp_epDesc, GENERICAPP_CLUSTERID, 4, buffer, &GenericApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS);}