1. 程式人生 > >【project】基於ZigBee/ARM的無線環境監測網路(+原始碼)

【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,可以藉助使用雲伺服器,小白就偷懶不用了,因此只在區域網內進行測試。

在這裡插入圖片描述

ZigBee協調器和ARM閘道器
ZigBee終端

  以下是小白錄製的桌面視訊的縮減版(暫時不支援插入視訊,用GIF代替)

網盤連結

  最後分享所有的原始碼和文件: 百度網盤 密碼: 2u7z

在這裡插入圖片描述

PPT簡略圖

在這裡插入圖片描述

work簡略圖
原始碼簡略圖