【project】基於ZigBee/ARM的無線環境監測網路(+原始碼)
要求打通這樣的一條通訊鏈路:感測器 ⇌ ZigBee網路 ⇌ ARM閘道器 ⇌ 伺服器 ⇌ Internet網路 ⇌ 使用者。存檔並分享原始碼。
文章目錄
01-設計篇
最後效果: Client開啟應用程式(C/S模式),傳送命令請求資料,Server服務多個Client,接到Client命令然後封裝傳送給ARM閘道器,ARM閘道器負責與ZigBee協調器串列埠通訊轉發命令,ZigBee協調器根據命令進行廣播/單播請求資料,ZigBee終端收到資料包後採集資料,原路返回直到給Client顯示。
感測器 ⇌ ZigBee網路
使用ZigBee協議棧進行資料採集和傳輸,實際上是ZigBee終端(帶感測器)與ZigBee協調器的通訊,終端負責感測器資料採集和資料包傳輸,協調器負責組網,連線多個終端,最後負責轉發資料包(資料包可能是ARM閘道器的命令),不作任何資料處理。
ZigBee網路 ⇌ ARM閘道器
使用串列埠通訊,ARM閘道器與ZigBee協調器相連,從底層的ZigBee網路轉換為Internet網路,ZigBee協調器負責上報資料和接收ARM閘道器下發的命令,ARM閘道器則負責接收資料和發出命令(命令來自伺服器)
ARM閘道器 ⇌ 伺服器
使用socket的TCP程式設計進行連線,ARM閘道器中執行Linux系統,配置網絡卡進行Internet聯網,與特定IP的socket(伺服器)進行連線,同時保持與ZigBee協調器的串列埠通訊。ARM閘道器負責接收伺服器的命令和上報資料,伺服器則負責接收資料和下發命令(命令來自使用者)。
伺服器 ⇌ Internet網路⇌ 使用者
使用socket的TCP程式設計進行資料報的傳送和接收,採用C/S傳輸模式,提供一個PC的終端客戶程式,程式會主動與指定的伺服器連線,並在PC介面下接收使用者命令,經過封裝後通過Internet網路傳送給伺服器。使用者主要訪問伺服器的資料庫以及請求實時資料,伺服器主要作資料庫儲存和資料幀處理。
02-硬體篇
使用到的一些ZigBee節點和ARM以及一些驅動器
名稱 | 用途 | 通訊介面 |
---|---|---|
ZigBee終端 | 感測器資料採集 | ZigBee協議棧 |
ZigBee協調器 | 組網、轉發資料 | ZigBee協議棧、串列埠 |
ARM(nano) | 資料轉換、轉發資料 | socket、串列埠 |
各種驅動器(如繼電器、電機等) | 實現遠端開關 | 普通IO |
各種電器(小風扇、水泵等) | 被遠端控制 | 普通IO |
上文並沒有說應用,因為目的只是打通一條鏈路,至於後期的應用,可以是農業大棚、養殖戶、小花園等等。
03-軟體篇
分為3部分:ZigBee協議棧程式設計、ARM-Linux程式設計和Linux-socket程式設計
ZigBee協議棧程式設計
使用的ZigBee節點是CC2530這一款,協議棧版本是ZStack-CC2530-2.5.1a,開發基於Sample例程。
出廠商附帶了很多感測器的使用例程,稍加修改就可以直接使用,最後對協議棧的串列埠、資料傳送AF_DataRequest和資料處理SampleApp_MessageMSGCB進行詳細程式設計即可,感測器資料在終端處就要進行資料格式封裝處理,自定義的資料格式如下:
更多的ZigBee協議棧程式設計可以直接下載文末的原始碼檢視。
ARM-Linux程式設計
小白使用的是友善之臂的nano-PC,板載Linux系統,雖然文件不多,裸機程式設計比較困難,但是直接使用Linux程式設計就可以了
對於ARM的操作,主要是操作串列埠通訊、管理員輸入操作和伺服器請求,這3個IO的併發操作使用Linux的檔案集進行,等待檔案集中描述符的變動,以響應某個動作,以下是檔案集的相關操作:
void FD_Init(void)
{
/*將檔案描述符加入讀描述符集合*/
FD_ZERO(&fds); //清0
FD_SET(scanf_fd,&fds); //加入鍵盤輸入檔案描述符
FD_SET(serial_fd,&fds); //加入串列埠檔案描述符
FD_SET(server_sockfd,&fds);//加入伺服器檔案描述符
/* 超時1秒0毫秒 */
timeout.tv_sec = 1;
timeout.tv_usec = 0;
}
/*----鍵盤輸入IO-----*/
if(FD_ISSET(scanf_fd,&fds))
{
……
}
/*----串列埠輸入IO-----*/
if(FD_ISSET(serial_fd,&fds))
{
……
}
/*----伺服器請求IO-----*/
if(FD_ISSET(server_sockfd,&fds))
{
……
}
Linux-socket程式設計
比較重要的就是socket程式設計了,先在ARM板載Linux上啟動應用程式,使用檔案集等待Server的連線,在一臺伺服器的Linux系統上執行Server,socket連線ARM,同時等待Client的接入,以下是Server等待Client的相關程式碼:
//等待客戶端連線請求到達
struct sockaddr_in remote_addr = *client_addr; //客戶端網路地址結構體
if((client_sockfd=accept(server_sockfd,(struct sockaddr *)&remote_addr,&sin_size))<0)
{
perror("[FLASE] Server accepting\n");
return -1;
}
else
{
*client_addr = remote_addr;
//IP地址獲取
char addr[20] = {0};
struct sockaddr* t = (struct sockaddr*)&remote_addr; //強制轉換地址
inet_ntop(AF_INET, (void *)t, addr, sizeof(addr)); //網路位元組順序IP地址->點分IP
//資料庫操作
char str_sql[128] = {0};
connectDB();
sprintf(str_sql,"INSERT INTO client (login_time,IP,contrl_time,contrl_action) VALUES (datetime('now'),'%s',datetime('now'),'logo_in');",addr);
sqlite_ret = sqlite3_exec(db, str_sql, callback, 0, &zErrMsg);
if( sqlite_ret != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
return false;
}
else
printf("[OK] Successfully records insert for client\n");
closeDB();
//提示資訊
printf("[OK] Server accept client %d\n",remote_addr.sin_addr.s_addr);
printf("[OK] IP=%s\n",addr);
printf("[OK] Server accepting\n");
return client_sockfd;
}
04-測試篇
因為小白需要用賬號密碼登陸上網,不能直接連線ARM,可以藉助使用雲伺服器,小白就偷懶不用了,因此只在區域網內進行測試。
以下是小白錄製的桌面視訊的縮減版(暫時不支援插入視訊,用GIF代替)
網盤連結
最後分享所有的原始碼和文件: 百度網盤 密碼: 2u7z