zigbee(cc2530)定位软件的实现
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
GenericApp_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( uint8 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 SENSOR
int8 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);
}
