You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
東 海 大 學 資 訊 工 程 與 科 學 系<br />
畢 業 專 題 成 果 競 賽<br />
< Zigbee 定 位 與 智 慧 型 行 動 購 物 導 覽 應 用 ><br />
專 題 實 驗 報 告 書<br />
指 導 教 授 : 石 志 雄<br />
專 題 組 員 :963849 謝 佳 峻<br />
中 華 民 國 九 十 九 年 十 二 月 十 八 日<br />
1
目 次<br />
一 、 摘 要 ……………………………………………………………………………3<br />
二 、 前 言 與 文 獻 回 顧 ………………………………………………………………4<br />
三 、 設 計 原 理 分 析 …………………………………………………………………5<br />
3-1. 伺 服 器 接 收 RSSI 產 生 定 位 資 訊 的 方 式 …………………………………5<br />
3-2. 伺 服 端 與 客 戶 端 …………………………………………………………7<br />
3-3. 裝 置 與 主 機 的 通 訊 方 式 …………………………………………………8<br />
3-4. 伺 服 端 與 客 戶 端 的 通 訊 方 式 ……………………………………………9<br />
3-5. 客 戶 端 顯 示 的 相 關 資 訊 …………………………………………………10<br />
3-6. 確 認 圖 形 介 面 的 運 作 正 常 ………………………………………………10<br />
3-7. 最 短 路 徑 的 表 示 …………………………………………………………11<br />
四 、 軟 硬 體 系 統 說 明 ………………………………………………………………12<br />
五 、 團 隊 分 工 合 作 方 式 ……………………………………………………………15<br />
六 、 成 果 與 討 論 ……………………………………………………………………15<br />
七 、 結 論 ……………………………………………………………………………20<br />
八 、 參 考 文 獻 ………………………………………………………………………20<br />
九 、 附 錄 ……………………………………………………………………………21<br />
2
一 、 摘 要<br />
ZigBee 是 一 種 新 的 短 距 離 無 線 通 訊 標 準 , 具 有 統 一 感 測 器 、 致 動 器 、 設 備 、 資 產 追<br />
蹤 設 備 的 資 料 通 訊 方 法 的 可 能 。 它 利 用 電 池 供 電 設 備 的 低 資 料 率 和 低 負 載 週 期 , 提 供<br />
構 建 可 靠 但 成 本 可 承 受 的 網 路 骨 幹 , 可 以 用 在 很 多 應 用 中 , 如 工 業 自 動 化 、 公 用 事 業<br />
計 量 、 大 樓 控 制 甚 至 是 玩 具 。ZigBee 協 定 目 前 的 版 本 採 用 IEEE802.15.4 短 距 離 無 線 通 訊<br />
標 準 , 而 上 層 網 路 層 和 應 用 支 援 層 則 透 過 ZigBeeAlliance 來 制 定 , 應 用 層 則 有 一 Profile<br />
來 規 範 , 由 於 低 成 本 、 低 耗 電 的 優 勢 , 使 得 ZigBee 在 國 內 外 市 場 的 接 收 度 與 普 及 率<br />
日 漸 提 高 , 根 據 Siemens 的 RokeManorResearch 分 析 , ZigBee 應 用 會 在 家 庭 建 築 物 自<br />
動 化 、 個 人 感 測 網 路 、 醫 療 照 護 、 工 業 感 測 網 路 、 導 航 控 制 等 應 用 上 。<br />
Zigbee 可 以 利 用 電 池 供 電 設 備 的 低 載 、 低 頻 率 在 負 擔 得 起 的 成 本 下 建 構 網 路 骨 幹 。<br />
透 過 Zigbee 的 傳 輸 協 定 , 可 以 汲 取 出 所 接 收 到 信 號 的 強 度 ( RSSI ) , 藉 此 推 斷 訊 號<br />
源 ( reference tag ) 與 讀 取 器 ( reader tag ) 之 間 的 距 離 , 導 出 訊 號 源 所 在 的 座 標 位 置 ,<br />
這 種 定 位 的 方 式 相 對 於 GPS 能 夠 提 供 小 範 圍 的 準 確 定 位 。 那 麼 基 於 Zigbee 的 無 線 傳<br />
輸 與 定 位 , 是 否 可 以 提 供 小 範 圍 的 導 覽 服 務 , 以 幫 助 使 用 者 快 速 找 出 想 要 到 達 的 地<br />
點 與 方 式 呢 ?<br />
透 過 實 作 的 結 果 可 以 將 Zigbee 原 本 的 目 的 , 也 就 是 無 線 感 測 所 蒐 集 到 的 資 料 整<br />
合 成 資 訊 再 傳 輸 給 每 個 使 用 者 , 手 邊 具 有 結 合 Zigbee 行 動 裝 置 的 使 用 者 就 可 以 立 即<br />
了 解 身 邊 的 環 境 資 訊 , 以 達 到 方 便 的 目 的 。<br />
3
二 、 前 言 與 文 獻 回 顧<br />
此 份 計 劃 的 原 型 為 使 用 10~15 個 Zigbee 感 測 器 建 構 雛 形 無 線 定 位 骨 幹 網 絡 , 兩 個<br />
次 領 域 各 有 六 個 固 定 位 置 參 考 感 測 器 (Zigbee reference tag) 對 稱 地 布 置 其 中 , 有 一 固 定<br />
位 置 讀 取 器 (Reader tag) 佈 置 於 會 場 中 央 , 各 以 正 方 形 及 菱 型 代 表 之 。 固 定 讀 取 器 負 責 與<br />
所 有 參 考 感 測 器 及 一 閘 道 器 (gateway) 建 立 通 訊 。 中 央 與 一 筆 電 相 連 之 固 定 感 測 器 即 為<br />
閘 道 器 。 當 使 用 者 推 著 配 戴 Zigbee tag 之 購 物 車 在 工 作 空 間 中 漫 遊 時 , 系 統 即 開 始 經<br />
由 此 一 骨 幹 網 路 進 行 活 動 tag 位 置 之 計 算 , 隨 時 更 新 其 位 置 並 儲 存 於 筆 電 server 中 之<br />
資 料 庫 。<br />
當 智 慧 型 購 物 車 針 對 使 用 者 之 選 購 需 求 作 出 反 應 , 如 使 用 者 點 選 某 食 譜 , 即 會<br />
觸 發 request 指 令 向 database server 索 取 該 食 譜 所 屬 群 組 中 所 有 成 份 食 材 之 目 前 位 置 ,<br />
並 在 連 接 至 該 智 慧 型 購 物 車 之 嵌 入 式 LCD 顯 示 成 員 位 置 ( 在 各 次 領 域 之 相 對 位 置 ) 另<br />
一 圖 七 顯 示 該 智 慧 型 購 物 車 移 至 另 一 區 域 時 之 情 景 。User A,B 之 位 置 同 時 出 現 在 次<br />
領 域 2 之 購 物 車 LCD 螢 幕 內 。<br />
實 際 上 由 於 場 地 與 設 備 的 限 制 , 實 地 測 試 以 PC 機 房 為 測 試 環 境 , 並 將 蒐 集 感 測<br />
器 的 位 置 讀 取 器 縮 減 為 3 個 ,Database server 以 PC 機 房 中 的 一 台 主 機 代 替 , 以 開 發 板<br />
連 接 讀 取 器 代 替 可 以 四 處 移 動 的 智 慧 型 購 物 車 。 透 過 Database server 所 取 得 的 定 位 資<br />
訊 以 及 使 用 者 所 期 望 的 目 的 地 導 引 出 到 達 目 的 地 的 路 徑 , 並 且 隨 時 更 新 定 位 資 訊 以<br />
表 現 出 Zigbee 在 小 範 圍 定 位 以 及 Zigbee 傳 遞 資 訊 的 可 行 性 。<br />
4
三 、 設 計 原 理 分 析<br />
這 份 專 題 包 含 整 合 定 位 資 訊 的 伺 服 器 端 與 表 現 定 位 結 果 的 客 戶 端 。 其 中 伺 服 器 端<br />
必 須 處 理 各 個 位 置 接 受 器 所 讀 取 到 的 RSSI 轉 換 成 參 考 感 測 器 所 在 的 位 置 , 並 且 將 位<br />
置 資 訊 透 過 Zigbee 傳 遞 給 相 應 的 客 戶 端 。 而 客 戶 端 則 將 伺 服 器 端 所 傳 來 的 資 訊 顯 示 ,<br />
並 透 過 使 用 者 的 選 擇 表 示 出 相 應 的 路 徑 。<br />
3-1. 伺 服 器 接 收 RSSI 產 生 定 位 資 訊 的 方 式<br />
方 法 一 :<br />
透 過 讀 取 參 考 感 測 器 與 多 個 位 置 讀 取 器 的 RSSI , 直 接 將 RSSI 轉 換 成 距 離 關 係 ,<br />
藉 此 求 出 參 考 感 測 器 的 位 置 資 訊 。<br />
( 圖 片 : 三 點 定 位 )<br />
首 先 , 先 算 出 位 置 讀 取 器 之 間 的 距 離 , 再 利 用 位 置 讀 取 器 之 間 的 距 離 與 RSSI 的<br />
關 係 導 出 參 考 感 測 器 與 位 置 讀 取 器 的 距 離 , 以 及 必 須 的 參 數 。 分 別 是 R1, R2, R3, sin( a<br />
), sin( b ), sin( c ), cos( a ), cos( b ), cos( c )。<br />
利 用 公 式 :<br />
5
藉 由 旋 轉 矩 陣 , 將 向 量 旋 轉 再 以 此 為 單 位 長 度 向 量 計 算 : 。<br />
利 用 求 出 的 三 條 向 量 所 取 得 的 三 個 座 標 做 平 均 , 藉 此 推 算 出 參 考 感 測 器 的 位 置 。<br />
但 是 這 項 定 位 法 的 缺 點 在 於 ,RSSI 容 易 受 環 境 變 動 所 影 響 , 所 以 推 算 出 的 位 置 也 會<br />
有 所 誤 差 。<br />
方 法 二 :<br />
利 用 建 立 高 斯 模 組 的 方 式 推 算 參 考 感 測 器 的 位 置 。 高 斯 模 組 的 建 立 是 以 RSSI 蒐<br />
集 約 100 ~ 1000 筆 產 生 的 平 均 值 與 標 準 差 , 進 而 透 過 公 式 導 出 參 考 感 測 器 的 位 置 。<br />
6
利 用 公 式 :<br />
帶 入 先 前 蒐 集 所 推 算 的 平 均 值 μ 、 標 準 差 σ 以 及 每 個 位 置 讀 取 器 所 蒐 集 到 的 平<br />
均 RSSI 來 求 出 每 一 個 節 點 出 現 參 考 感 測 器 的 機 率 值 , 而 機 率 值 最 高 的 節 點 就 被 定 為<br />
參 考 感 測 器 所 在 的 位 置 。<br />
3-2. 伺 服 端 與 客 戶 端<br />
Zigbee 原 本 的 功 能 就 在 於 建 立 低 成 本 的 網 路 骨 幹 , 所 以 在 使 用 Zigbee 作 為 定 位<br />
用 途 時 也 同 時 可 以 利 用 Zigbee 作 為 訊 息 傳 遞 的 方 式 。 在 這 次 的 專 題 中 所 採 用 的 Zigbee<br />
網 路 設 備 為 Helicomm 的 EZ-Tracer, EZ-Tracer 包 含 負 責 接 收 定 位 資 訊 的 Master, 以<br />
及 建 構 網 路 骨 幹 並 作 為 位 置 接 收 器 的 Reader, 還 有 作 為 定 位 目 標 的 Tag。<br />
在 專 題 實 驗 的 環 境 中 , 以 伺 服 端 銜 接 Master 負 責 接 收 每 一 個 Reader 所 回 傳 的 定<br />
位 資 訊 演 算 後 由 改 寫 過 的 EZ-Tracer Demo Utility 進 行 演 算 再 將 演 算 的 結 果 回 傳 給<br />
Reader 。 而 銜 接 Reader 的 客 戶 端 收 到 Master 所 傳 送 來 的 演 算 結 果 , 透 過 自 行 撰 寫 的<br />
GTK+ 圖 形 介 面 顯 示 資 訊 。<br />
7
3-3. 裝 置 與 主 機 的 通 訊 方 式<br />
helicomm EZ-Tracer 所 提 供 的 Master 為 USB 介 面 , 而 Reader 則 是 RS232 介 面 。 雖<br />
然 在 介 面 上 有 所 差 異 , 但 在 使 用 上 都 能 以 Serial Programming 的 方 式 來 操 作 。 以 Linux<br />
的 devfs 為 例 , 當 Master 接 上 主 機 時 會 自 動 產 生 /dev/ttyUSB0 的 節 點 , 而 Reader 則 是<br />
使 用 /dev/ttyS0 來 存 取 。<br />
當 程 式 要 使 用 到 裝 置 時 需 要 透 過 Linux 的 System calls, 一 般 來 說 透 過 open( ) ,<br />
close( ),read( ),write( ) 就 可 以 對 裝 置 進 行 簡 單 的 控 制 , 但 實 際 上 在 使 用 前 必 須 透 過<br />
termios 針 對 設 定 相 應 的 baudrate 以 及 通 訊 屬 性 與 標 準 , 以 避 免 資 料 在 傳 輸 時 產 生 意<br />
外 的 錯 誤 。<br />
當 程 式 在 使 用 Zigbee 裝 置 做 資 料 傳 輸 是 透 過 open( ) 所 取 得 的 檔 案 描 述 子 以 write(<br />
) 將 Zigbee 的 Frame 寫 入 , 裝 置 接 收 到 來 自 主 機 的 Frame 再 將 Frame 送 出 。 而 裝 置 接<br />
收 到 Frame 時 透 過 read( ) 取 得 接 收 到 的 Frame。<br />
Control Header<br />
Link Quality<br />
Destination<br />
Payload Length<br />
Payload<br />
XOR Checksum<br />
(1)<br />
Indicator<br />
Address<br />
(1)<br />
(0 ~ 97)<br />
(1)<br />
(1)<br />
(2)<br />
根 據 Zigbee 的 標 準 Zigbee Frame 的 型 態 分 為 兩 類 四 種 , 以 Control Header 的 前 4<br />
個 bits 所 決 定 , 而 Frame 的 參 數 有 上 述 六 種 。 如 果 直 接 在 程 式 中 直 接 以 陣 列 表 示 出<br />
Frame 不 免 喪 失 一 些 程 式 的 可 讀 性 以 及 維 護 性 。 是 故 , 當 程 式 在 存 取 裝 置 時 不 是 直 接<br />
產 生 Frame 而 是 透 過 以 下 的 型 態 與 函 式 存 取 Frame。<br />
typedef enum {<br />
CMD_REQUEST,<br />
CMD_RESPONSE,<br />
DATA_REQUEST,<br />
DATA_ACK<br />
}FrameType;<br />
typedef struct {<br />
unsigned short smac;<br />
8
int deviceFd;<br />
}zb_Reader;<br />
typedef struct {<br />
unsigned char data[ZIGBEE_FRAME_SIZE];<br />
}zb_Frame;<br />
int zb_initReader( );<br />
int zb_releaseReader( );<br />
int zb_send( );<br />
int zb_recv( );<br />
int zb_setFrameType( );<br />
int zb_setFrameDestSmac( );<br />
int zb_setFrameData( );<br />
FrameType zb_getFrameType( );<br />
unsigned short zb_getFrameSrcSmac( );<br />
int zb_getFrameData( );<br />
3-4. 伺 服 端 與 客 戶 端 的 通 訊 方 式<br />
透 過 上 述 所 定 義 的 函 式 , 伺 服 端 可 以 不 斷 接 收 各 個 Reader 所 接 收 到 的 RSSI 以 及<br />
送 出 新 的 定 位 資 訊 , 而 客 戶 端 在 接 收 到 則 更 新 目 前 所 顯 示 的 資 訊 , 之 間 的 通 訊 是 以<br />
類 似 UDP 的 方 式 傳 遞 。 以 客 戶 端 的 使 用 為 例 :<br />
if(!reader_connected) {<br />
reader_connected = zb_initReader(&reader, ZB_TTY);<br />
}<br />
while(reader_connected) {<br />
if(zb_recv(&reader, &frame)) {<br />
zb_getFrameData(&frame, data);<br />
infoAnalysis(data);<br />
}<br />
}<br />
透 過 這 樣 的 流 程 使 客 戶 端 接 收 來 自 伺 服 端 的 定 位 資 訊 。<br />
9
3-5. 客 戶 端 顯 示 的 相 關 資 訊<br />
在 這 個 專 題 中 以 PXA255 開 發 版 作 為 客 戶 端 , 來 貼 近 一 個 合 併 購 物 車 的 行 動 裝 置 。<br />
透 過 PXA255 的 螢 幕 可 以 顯 示 出 環 境 的 地 圖 以 及 目 前 所 在 的 位 置 , 為 了 要 讓 PXA255<br />
可 以 顯 示 出 這 些 資 訊 或 是 接 收 使 用 者 的 輸 入 , 必 須 使 用 一 些 圖 形 函 式 庫 來 達 成 。<br />
華 亨 科 技 的 PXA255 開 發 版 所 使 用 的 圖 形 介 面 函 式 庫 為 GTK+ 1.2 , 而 GTK+ 有<br />
一 項 關 聯 的 產 物 Glade ,Glade 是 一 項 透 過 圖 形 介 面 來 產 生 圖 形 介 面 的 程 式 。 透 過<br />
Glade 可 以 快 速 的 產 生 程 式 介 面 的 雛 型 以 及 自 動 引 用 GTK+ 圖 形 介 面 函 式 庫 , 使 得 在<br />
編 寫 圖 形 程 式 只 要 專 注 於 程 式 的 邏 輯 , 以 及 回 應 圖 形 介 面 的 事 件 。<br />
以 客 戶 端 的 程 式 來 說 ; 程 式 的 邏 輯 就 是 接 收 來 自 伺 服 端 的 定 位 資 訊 , 顯 示 出 目<br />
前 所 在 的 位 置 , 以 及 更 新 最 短 路 徑 的 狀 態 ; 而 來 自 使 用 者 的 請 求 則 是 透 過 圖 形 介 面<br />
的 按 鈕 觸 發 事 件 , 更 改 程 式 的 狀 態 。 程 式 的 邏 輯 以 一 個 refresh( ) 的 函 式 完 成 , 經 由<br />
GTK+ 的 gtk_idle_add( ) 由 gtk_main( ) 在 圖 形 介 面 閒 置 時 不 斷 呼 叫 , 使 程 式 具 有 類 似<br />
多 工 的 功 能 來 更 新 資 訊 。<br />
當 以 Glade 完 成 介 面 的 設 計 時 會 產 生 幾 份 C 程 式 碼 檔 案 , 分 別 是 callbacks.c/.h 、<br />
interface.c/.h、support.c/.h、main.c , 以 及 autogen.sh 。 透 過 修 改 這 些 文 件 就 可 以 回 應 事 件<br />
觸 發 的 行 為 , 以 及 指 定 makefile 所 產 出 的 執 行 檔 平 台 。<br />
3-6. 確 認 圖 形 介 面 的 運 作 正 常<br />
當 程 式 完 成 時 必 須 透 過 開 發 板 的 bootloader 以 及 開 發 環 境 的 tftp server 進 行 燒 錄 的<br />
動 作 , 如 果 圖 形 介 面 不 如 預 期 所 運 作 就 必 須 修 改 並 重 新 燒 錄 , 這 樣 的 動 作 十 分 瑣 碎<br />
而 且 一 燒 就 是 二 十 分 鐘 。 事 實 上 透 過 Linux 搭 配 GTK+ 套 件 就 可 以 在 開 發 環 境 中 呈 獻<br />
出 圖 形 介 面 運 作 的 樣 子 , 在 開 發 環 境 中 測 試 完 成 才 透 過 cross-compiler 產 生 開 發 板 所<br />
使 用 的 程 式 。<br />
以 目 前 的 Linux 發 行 板 來 說 , 幾 乎 沒 有 提 供 GTK+ 1.2 以 及 Glade 0.6 的 套 件 讓 使<br />
10
用 者 下 載 安 裝 , 所 以 必 須 自 行 到 GTK+ & Glade 的 官 方 網 站 下 載 。 經 過 編 譯 三 部 曲<br />
(./configure && make && make install) 就 可 以 在 開 發 環 境 使 用 。<br />
3-7. 最 短 路 徑 的 表 示<br />
程 式 在 接 收 到 目 前 的 所 在 位 置 以 及 使 用 者 所 選 擇 的 目 的 地 時 , 必 須 表 示 出 一 條<br />
到 達 目 的 地 的 最 短 路 徑 。 在 此 專 題 中 是 以 Dijkstra 的 演 算 法 來 求 出 最 短 路 徑 ,Dijkstra<br />
演 算 法 的 時 間 複 雜 度 為 O(|E| + |V|log|V| ) , 所 以 在 表 示 路 徑 時 只 會 以 少 量 的 頂 點 連 線<br />
顯 示 出 空 間 中 主 要 的 幹 道 , 當 目 的 地 或 是 所 在 位 置 更 新 時 會 選 取 附 近 的 最 近 頂 點 作<br />
為 終 點 或 是 起 點 。<br />
11
四 、 軟 硬 體 系 統 說 明<br />
上 圖 是 硬 體 配 置 的 大 概 架 構 , 透 過 Server 連 接 Master 裝 置 可 以 向 週 遭 的 Reader<br />
索 取 RSSI 並 且 傳 輸 定 位 結 果 給 裝 有 Reader 的 Client, 而 中 間 的 協 定 是 Zigbee。<br />
上 圖 是 實 際 運 作 的 硬 體 配 置 , 前 端 的 主 機 為 收 集 RSSI 運 算 定 位 資 訊 的 Server,<br />
而 擺 在 後 方 椅 子 上 的 為 接 收 位 置 資 訊 的 開 發 板 以 及 裝 置 。<br />
12
上 圖 表 示 Server 與 Client 之 間 的 通 訊 架 構 。<br />
上 圖 表 示 Server 透 過 Master 向 Reader 汲 取 RSSI。<br />
上 圖 表 示 Server 傳 遞 位 置 給 Client 的 流 程 。<br />
13
上 圖 為 程 式 在 開 發 平 台 測 試 , 左 上 角 的 紅 點 為 起 始 位 置 , 右 下 角 的 綠 點 為 目 的<br />
位 置 , 兩 者 皆 是 透 過 選 取 產 生 , 而 程 式 自 動 根 據 起 始 點 與 目 的 地 附 近 的 節 點 求 出 最<br />
短 的 路 徑 。<br />
五 、 團 隊 分 工 合 作 方 式<br />
由 於 這 份 專 題 只 有 一 人 處 理 , 所 以 大 部 分 的 協 助 都 是 來 自 石 志 雄 教 授 以 及 梁 博<br />
丞 學 長 。 架 構 上 的 問 題 與 學 長 討 論 過 後 再 向 教 授 詢 問 可 行 性 , 然 後 才 由 我 修 改 程 式 。<br />
下 文 的 結 果 也 是 由 於 學 長 的 幫 助 完 成 場 地 高 斯 模 組 的 建 置 , 才 得 以 取 得 定 位 的 結 果 。<br />
14
六 、 成 果 與 討 論<br />
上 圖 是 整 體 裝 置 的 照 片 , 左 方 的 開 發 板 透 過 RS232 跳 線 連 接 至 右 上 方 的 Reader<br />
以 接 收 來 自 Server 的 位 置 資 訊 , 而 Reader 下 方 則 是 散 布 定 位 資 訊 的 Tag。<br />
在 開 發 版 上 可 以 接 收 來 自 Server 的 位 置 資 訊 並 顯 示 , 以 及 根 據 目 的 地 產 生 一 條<br />
最 短 路 徑 , 除 了 用 來 廣 播 RSSI 的 Tag 外 還 放 置 了 Reader 供 開 發 版 使 用 。<br />
上 圖 為 當 時 所 在 的 位 置 。<br />
15
從 相 對 的 一 角 觀 看 。<br />
16
經 過 移 動 之 後 , 新 的 位 置 資 訊 傳 入 並 更 新 最 短 路 徑 。<br />
而 該 時 的 位 置 於 該 處 。<br />
17
透 過 視 窗 下 方 的 按 鈕 可 以 由 使 用 者 決 定 目 的 地 , 以 幫 助 使 用 者 了 解 最 短 路 徑 。<br />
上 圖 為 使 用 者 點 擊 Worst seat 的 按 鈕 所 指 出 的 路 徑 。<br />
上 圖 為 使 用 者 點 擊 Best seat 的 按 鈕 所 指 出 的 路 徑 。<br />
18
即 使 位 置 改 到 別 處 也 可 以 更 新 從 該 位 置 到 達 目 的 地 的 最 短 路 徑 。<br />
上 圖 是 Worst seat 更 新 過 的 路 徑 。<br />
上 圖 是 Best seat 更 新 過 的 路 徑 。<br />
19
七 、 結 論<br />
雖 然 在 定 位 上 仍 然 有 所 差 異 但 是 透 過 一 種 無 線 協 定 就 可 以 擁 有 網 路 通 訊 以 及 定<br />
位 的 功 能 , 加 上 Zigbee 具 有 低 成 本 的 優 勢 , 雖 然 wifi 也 可 以 透 過 訊 號 衰 減 來 達 成 定<br />
位 效 果 , 但 是 wifi 在 環 境 監 控 的 部 份 就 比 不 上 Zigbee。 專 題 的 結 果 印 證 了 Zigbee 與<br />
購 物 車 結 合 的 可 行 性 , 從 而 達 到 購 物 車 的 定 位 效 果 以 提 供 簡 易 導 覽 。<br />
八 、 參 考 文 獻<br />
GTK+ Reference Manual<br />
Linux 程 式 設 計 教 學 手 冊 第 四 版 ,ISBN :978-986-181-549-7<br />
Serial Programming HOWTO<br />
ZigBee 開 發 手 冊 ,ISBN:978-957-216-924-7<br />
戴 弘 棋 , 基 於 高 斯 混 合 模 型 系 統 之 室 內 定 位 系 統 設 計 與 實 作 。<br />
20
九 、 附 錄<br />
Zigbee 通 訊 實 作 zigbee.c:<br />
#include "zigbee.h"<br />
#include <br />
#include <br />
#include <br />
#include <br />
#include <br />
#include <br />
#include <br />
#include <br />
#include <br />
#include <br />
#include <br />
static void dumpMem(unsigned char * ptr, int lineLen, int<br />
dumpLen)<br />
{<br />
int i;<br />
for(i = 0; i < dumpLen; i++) {<br />
printf("%2X ", ptr[i]);<br />
if((i%lineLen == lineLen-1)||(i == dumpLen-1)) puts("");<br />
}<br />
}<br />
static int zb_setChecksum(zb_Frame * frame)<br />
{<br />
/* dataLength + (ctrlHeader(1) + LQI(1) + destSmac(2) +<br />
dataLengthLength(1)) */<br />
int frameLength = frame->data[4] + 5;<br />
unsigned char xorChecksum = 0;<br />
for(int i = 0; i < frameLength; i++) {<br />
xorChecksum ^= frame->data[i];<br />
}<br />
frame->data[frameLength] = xorChecksum;<br />
return true;<br />
}<br />
static int zb_frameCheck(zb_Frame * frame)<br />
{<br />
int frameLength = frame->data[4] + 5;<br />
21
unsigned char xorChecksum = 0;<br />
for(int i = 0; i data[i];<br />
}<br />
return 0 == xorChecksum;<br />
}<br />
static int nonBlockingRead(int fd, void * buf, size_t size<br />
) /* ioctl implementation */<br />
{<br />
int nread;<br />
ioctl(fd, FIONREAD, &nread);<br />
if((nread
puts("open failed.");<br />
success = false;<br />
}<br />
if(success) puts("open finish.");<br />
if(success) {<br />
struct termios fd_opt;<br />
tcgetattr(fd, &fd_opt);<br />
cfsetospeed(&fd_opt, B38400);<br />
cfsetispeed(&fd_opt, B38400);<br />
fd_opt.c_iflag &= ~(INPCK | PARMRK | IXON | IXOFF);<br />
fd_opt.c_iflag |= (IGNPAR);<br />
fd_opt.c_cflag &= ~(CSIZE | CSTOPB | PARENB);<br />
fd_opt.c_cflag |= (CS8 | CREAD);<br />
fd_opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);<br />
fd_opt.c_cc[VTIME] = 1;<br />
fd_opt.c_cc[VMIN] = 0;<br />
tcflush(fd, TCIFLUSH);<br />
int result;<br />
result = tcsetattr(fd, TCSANOW, &fd_opt);<br />
if(-1 == result) {<br />
while(-1 != close(fd));<br />
puts("set_attr failed.");<br />
success = false;<br />
}<br />
}<br />
if(success) puts("set_attr finish.");<br />
if(success) {<br />
zb_Frame loFrame;<br />
zb_Frame readFrame;<br />
unsigned char frameData[] = {0x8B};<br />
zb_setFrameType(&loFrame, CMD_REQUEST);<br />
zb_setFrameDestSmac(&loFrame, 0xFFFE);<br />
zb_setFrameData(&loFrame, frameData, 1);<br />
zb_setChecksum(&loFrame);<br />
completelyWrite(fd, loFrame.data, 7);<br />
success = false;<br />
for(int i = 0; i < 100; i++) {<br />
23
if(read(fd, readFrame.data, ZIGBEE_FRAME_SIZE)) {<br />
puts("recv data");<br />
dumpMem(readFrame.data, 8, 16);<br />
if(zb_frameCheck(&readFrame)) {<br />
reader->smac = ((unsigned short)readFrame.data[2]<br />
deviceFd = fd;<br />
success = true;<br />
}<br />
break;<br />
}<br />
}<br />
}<br />
if(!success) {<br />
close(fd);<br />
}<br />
return success;<br />
}<br />
int zb_releaseReader(zb_Reader * reader)<br />
{<br />
close(reader->deviceFd);<br />
}<br />
int zb_send(zb_Reader * reader, zb_Frame * frame)<br />
{<br />
return completelyWrite(reader->deviceFd, frame->data,<br />
ZIGBEE_FRAME_SIZE);<br />
}<br />
int zb_recv(zb_Reader * reader, zb_Frame * frame)<br />
{<br />
nonBlockingRead(reader->deviceFd, frame->data,<br />
ZIGBEE_FRAME_SIZE);<br />
return zb_frameCheck(frame);<br />
}<br />
int zb_setFrameType(zb_Frame * frame, FrameType type)<br />
{<br />
switch(type) {<br />
case CMD_REQUEST :<br />
frame->data[0] &= 0x0F;<br />
24
frame->data[0] |= 0x80;<br />
break;<br />
case CMD_RESPONSE :<br />
frame->data[0] &= 0x0F;<br />
frame->data[0] |= 0xC0;<br />
break;<br />
case DATA_REQUEST :<br />
frame->data[0] &= 0x0F;<br />
frame->data[0] |= 0xA0;<br />
break;<br />
case DATA_ACK :<br />
frame->data[0] &= 0x0F;<br />
frame->data[0] |= 0xE0;<br />
break;<br />
default :<br />
return false;<br />
}<br />
return true;<br />
}<br />
int zb_setFrameDestSmac(zb_Frame * frame, unsigned short smac<br />
)<br />
{<br />
frame->data[2] = (unsigned char)(smac >> 8);<br />
frame->data[3] = (unsigned char)(smac % 0x00FF);<br />
return true;<br />
}<br />
int zb_setFrameData(zb_Frame * frame, const void * data,<br />
size_t dataLength)<br />
{<br />
if(dataLength > 96) {<br />
return false;<br />
} else {<br />
frame->data[4] = dataLength;<br />
memcpy(&frame->data[5], data, dataLength);<br />
}<br />
return true;<br />
}<br />
FrameType zb_getFrameType(zb_Frame * frame)<br />
25
{<br />
switch (frame->data[0] & 0xF0) {<br />
case 0x80 :<br />
return CMD_REQUEST;<br />
case 0xC0 :<br />
return CMD_RESPONSE;<br />
case 0xA0 :<br />
return DATA_REQUEST;<br />
case 0xE0 :<br />
return DATA_ACK;<br />
default :<br />
return -1;<br />
}<br />
}<br />
unsigned short zb_getFrameSrcSmac(zb_Frame * frame)<br />
{<br />
unsigned short smac;<br />
smac = ((unsigned short)frame->data[2] data[3];<br />
return smac;<br />
}<br />
int zb_getFrameData(zb_Frame * frame, void * dest, size_t *<br />
dataLength)<br />
{<br />
size_t srcLength = frame->data[4];<br />
*dataLength = srcLength;<br />
memcpy(dest, &frame->data[5], srcLength);<br />
return true;<br />
}<br />
26