CC2530自動聯網的苦惱
不知道部落格園裡面有沒有人研究CC2530,也就是zigbee技術,其實我在做東西的時候很糾結一個問題,那就是我如何將裝置連上後,如何通過協調者傳送命令給終端呢?有什麼方法可以快捷的解決這個事情呢?zigbee確實是讓我們能夠直接形成一個網路了,但是我們要的是能夠在協調者裡面直接找到相應的終端,然後直接相連不就行了嗎,這樣又快又好!但是在這個過程中我們經常碰到是,我們根本找不到目標終端!
- zigbee的協調者是會給終端隨機分配一個16位的短地址
- CC2530雖然有IEEE的長地址,但是這個長地址在獲取的過程中相當複雜
- CC2530也沒有非常好的demo來解決
我的思考與想法
既然我們無法容易的得到長地址,而且長地址的資料量也是有點大的,光使用協議,每次都輸相應的長地址,這不是找死是什麼,閒自己的資料還不夠多嗎?於是我思考了一段時間,哈哈哈,為什麼我們不能自己建立對映表來對應相應的短地址,就像一張表格一樣。或者說像資料庫的模式學習,一個是標題欄,一個是值,這個值是短地址,但是標題欄永遠不會變不就可以了嗎?
動手實現一下
那麼從何開始呢?我們不能亂碰啊!首先你得知道咋麼建立網路連線吧!,等等,有人說:我沒有安裝檔案,你說的z-stack2007那個玩意在哪呢?好吧,我把它放出來!TI的官網上早就沒有這個了,因為它是version2.5a的 現在的是TI的 z-stack home 是version2.6a版的,筆者比較懶,沒想用2.6a的,原因嘛~~~因為不高興再使用新的工具去調了!
分析一下自帶的zigbee的聯網
在sampleapp.c中我們來看看zigbee是如何聯網的!
afAddrType_t SampleApp_Periodic_DstAddr;
afAddrType_t SampleApp_Flash_DstAddr;
afAddrType_t 沒錯就是這個東西,不明白,沒關係,我們使用go to defintion 去看看它是如何定義的!
typedef enum
{
afAddrNotPresent = AddrNotPresent, //按照繫結表進行繫結傳輸
afAddr16Bit = Addr16Bit,// 指定目標網路地址進行單薄傳輸 16位
afAddr64Bit = Addr64Bit,
afAddrGroup = AddrGroup,// 組播傳輸
afAddrBroadcast = AddrBroadcast//廣播傳輸
} afAddrMode_t;
typedef struct
{
union
{
uint16 shortAddr;//隨機分配的短地址
ZLongAddr_t extAddr;
} addr;
afAddrMode_t addrMode;//afAddrMode_t是一個列舉型別 模式引數
uint8 endPoint; //指定的端點號 端點241—254保留端點 範圍 1-240
uint16 panId; // 加入的panid 就是在哪個網段上
} afAddrType_t;
看到我上面的註釋了吧? 哈哈,那麼我們就可以模仿它來寫我們的網路協議
回到sampleapp.c我們新增自己的對點網路。
afAddrType_t SampleApp_Periodic_DstAddr;
afAddrType_t SampleApp_Flash_DstAddr;
/**自己定義的點對點的傳輸**/
afAddrType_t SampleApp_Point_to_Point_DstAddr;
/**************/
ok了,那麼我們上面不是說了要用對映的形式 對不對?
uint16 Routing_Table[DEV_COUNT][1]={0} 定義路由表單那是必須的 你有多少個zigbee你就得用多少的DEV_COUNT
這個呢就直接放在我們點對點的傳輸定義的下面就可以了!
// Setup for the periodic message's destination address
// Broadcast to everyone
SampleApp_Periodic_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast;
SampleApp_Periodic_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
SampleApp_Periodic_DstAddr.addr.shortAddr = 0xFFFF;
// Setup for the flash command's destination address - Group 1
SampleApp_Flash_DstAddr.addrMode = (afAddrMode_t)afAddrGroup;
SampleApp_Flash_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
SampleApp_Flash_DstAddr.addr.shortAddr = SAMPLEAPP_FLASH_GROUP;
往下翻,你看到了嗎?沒錯,這個就是配置我們網路模式的函式了,可以與上面的afAddrType_t定義的內容一一對應哦!
好了 我們也可以通過自己的方法寫自己的配置模式!
// Setup for the flash command's destination address - Group 1
SampleApp_Flash_DstAddr.addrMode = (afAddrMode_t)afAddrGroup;
SampleApp_Flash_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
SampleApp_Flash_DstAddr.addr.shortAddr = SAMPLEAPP_FLASH_GROUP;
/***設定點對點的地址方案****/
SampleApp_Point_to_Point_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;//點對點模式
SampleApp_Point_to_Point_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
SampleApp_Point_to_Point_DstAddr.addr.shortAddr = 0xffff;//資料從發給全部裝置
/********************************/
找到這個函式uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events )沒錯這個函式其實是傳送處理函式。
傳送端處理
uint8 buffer[4];//存放加入網路的資料
buffer[0] = 'm';
buffer[1] = DEV_NUM;// 裝置號 你需要自己定義
buffer[2] = 1;
buffer[3] = 'g';
SampleApp_Point_to_Point_DstAddr.addr.shortAddr = 0x0000;
if ( AF_DataRequest( &SampleApp_Point_to_Point_DstAddr,
&SampleApp_epDesc,
SAMPLEAPP_ADDNET_CLUSTERID,
4,
buffer,
&SampleApp_TransID,
AF_DISCV_ROUTE | AF_ACK_REQUEST,
AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
{
#ifdef DEBUG_STAGE
HalUARTWrite(0,"Init EndPoint\n\r",sizeof("Init EndPoint\n\r"));
//HalLedSet(LED1,LED_ON);
#endif
}
else
{
// Error occurred in request to send.
}
/*****原函式被註釋
// Start sending the periodic message in a regular interval.
osal_start_timerEx( SampleApp_TaskID,
SAMPLEAPP_SEND_PERIODIC_MSG_EVT,
SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT );
*/
接收端處理
找到這個函式void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )這個是接受端的處理函式
uint8 *str = NULL;
uint8 buffer[4];//用於處理應答
uint16 shortaddr;//用來存放短地址
str = pkt->cmd.Data;
switch ( pkt->clusterId )
{
case SAMPLEAPP_ADDNET_CLUSTERID://入網處理
if(pkt->cmd.Data[0]=='m' && pkt->cmd.Data[3]=='g' && pkt->srcAddr.addr.shortAddr != 0)
{
HalLedSet(LED1,LED_ON);//協調者led1亮 表示找到了網路
shortaddr = pkt->srcAddr.addr.shortAddr;//把收到的終端的地址儲存
Routing_Table[pkt->cmd.Data[1]][pkt->cmd.Data[2]] = shortaddr; //對應的房間裝置的路由表建立
HalUARTWrite(0,&asc_16[Routing_Table[pkt->cmd.Data[1]][pkt->cmd.Data[2]]/4096],1);
HalUARTWrite(0,&asc_16[Routing_Table[pkt->cmd.Data[1]][pkt->cmd.Data[2]]%4096/256],1);
HalUARTWrite(0,&asc_16[Routing_Table[pkt->cmd.Data[1]][pkt->cmd.Data[2]]%256/16],1);
HalUARTWrite(0,&asc_16[Routing_Table[pkt->cmd.Data[1]][pkt->cmd.Data[2]]%16],1);
buffer[0] = 'r';//進行回覆
buffer[1] = 0;
buffer[2] = 0;
buffer[3] = 'a';
SampleApp_Point_to_Point_DstAddr.addr.shortAddr = shortaddr;//並把應答資訊傳送給終端 入網成功
if ( AF_DataRequest( &SampleApp_Point_to_Point_DstAddr, &SampleApp_epDesc,
SAMPLEAPP_ADDNET_CLUSTERID,
4,
buffer,
&SampleApp_TransID,
AF_DISCV_ROUTE | AF_ACK_REQUEST,
AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
{
// HalUARTWrite(0,"get searchmsg\n\r",sizeof("get searchmsg\n\r"));
// HalUARTWrite(0,"bind one end",12);
HalLedSet(LED1,LED_OFF);//協調者led1燈滅 表示曾找到網路
}
else
{
// Error occurred in request to send.
}
}
然後我們對接受到的資料資訊進行分析,有頭帶m尾g的我們就入網,且迴應協調者r00a 我收到了的意思
SAMPLEAPP_ADDNET_CLUSTERID這個又是從哪冒出來的呢? 嘿嘿就在sampleapp.c的標頭檔案裡面新增自己的輪迴任務ID
申明
如果您轉了我的文章呢,非常之感謝,但請您表明一下出處就可以了,一個連結的事情嘛~~再次感謝各位對我的支援!