第三章系統設計
第三章系統設計 1-16
3.1 通訊串口 2
3.1.1 引入類別 2
3.1.2 直接加入SearialPort 3
3.1.3 開啟串口 4
3.1.4 關閉串口 4
3.1.5 SearialPort類別屬性 4
3.1.6 公用方法 6
3.1.7 其它選項屬性 6
3.1.8 資料傳輸模擬 7
3.2 傳輸模擬 7
3.2.1 介面設計 8
3.2.2 工作程式簡介 9
3.2.3 IP-Link 傳輸模擬 10
3.3.1 傳送資料 10
3.3.2 接收資料 11
3.3.3 常用數系轉換函數 11
3.4 自動接收資料 13
3.5 IP-Link指令測試 15
3.5.1 DI測試 15
3.5.2 DO測試 15
3.5.3 Tag定位測試 15
3.5.4 數位儀器資料感測 16
第三章系統設計
本章將以 VB 語言當作系統發展工具,依序介紹無線感測網路系統設計之 介面設計原理與技巧。設計重點摘述如下:
通訊串口-RS232 ComPort 通訊屬性設定
資料傳送與接收 數系轉換
CheckSum 演算法
3.1 通訊串口-RS232 Comport
介 面 設 計 之 首 要 工 作 , 必 須 在 專 案 表單 內 加 入 一 個 通 訊 串 口 (RS232 ComPort),設定相關通訊屬性後,接著才可以和 ZigBee 元件串接以收送資料。 通 訊串口之加入方式有兩種:引入類別並實作 RS232 物件,或是在表單內直接加 入 RS232 控制項。
3.1.1 引入類別
請依下列步驟來實作 RS232 物件:
Step 1. 進入表單程式碼編輯模式 Step 2.在前置處理區引入下述類別
Imports System.IO.Ports Imports System.Text Imports System.IO
Step 3. 在表單程式碼公用區宣告一個物件變數-RS232,語法如下:
Dim RS232 As SerialPort
Step 4. 在表單之 Form Load 事件程序區設定串口屬性 Dim mBaudRate As Integer
Dim mParity As Parity Dim mDataBit As Integer Dim mStopbit As StopBits Dim mPortName As String
mPortName = cmbCOM.SelectedItem.ToString '取得欲開啟的通訊埠 mBaudRate = 38400 '指定通訊速度
mParity = Parity.None '設定同位位元檢查設定
mDataBit = 8 '指定資料位元 ↑H
mStopbit = StopBits.One '指定停止位元 '建立一個通訊埠物件
RS232 = New SerialPort(mPortName, mBaudRate, mParity, mDataBit, mStopbit) '設定編碼方式
'設定為Unicode時,則能顯示中文 RS232.Encoding = Encoding.Default '設定資料逾時,單位為miliseconds RS232.ReadTimeout = 1000
3.1.2 直接加入 SearialPort 控制項
請依下列步驟來加入 RS232 控制項:
Step 1. 進入表單介面設計模式 Step 2. 開啟工具箱
Step 3. 點選 SearialPort 控制項並加入表單 工作畫面如下圖
加入表單後改 名為RS232 加入表單後改
名為RS232
圖 3.1 加入 SearialPort 示意圖 Step 4. 點取 RS232 控制項並開啟屬性視窗
工作畫面如下圖,請依序設定相關屬性
圖 3.2 RS232 類別屬性列表
↑H
串口屬性也可由使用者在系統運作時自行設定,請在專案加入一個屬性設 定表單,如下圖所示,設定相關屬性後,由主表單來讀取屬性表單之設定值,最 後將讀取值依 3.1.1 節之方式設定通訊串口。
圖 3.3 串口屬性設定表單
3.1.3 開啟串口
If Not RS232.IsOpen Then '尚未開啟 RS232.Open() '開啟通訊埠 Else
MsgBox("通訊埠開啟錯誤(可能通訊埠已被開啟)") End If
3.1.4 關閉串口
If RS232 Is Nothing OrElse Not RS232.IsOpen Then '未開啟則無法關閉 MsgBox("通訊埠尚未開啟")
Else
RS232.Close() End If
3.1.5 SearialPort 類別屬性
SearialPort 類別其它重要屬性請參閱下表說明。
↑H
表 3.1 SearialPort 類別重要屬性
屬性名稱 說明
BaseStream 取得 SearialPort 物件之基礎 Stream BaudRate 取得或設定傳輸速率
BreakState 取得或設定中斷信號狀態 BytesToRead 取得接收緩衝區資料位元組數 BytesToWrite 取得傳送緩衝區資料位元組數 CDHolding 取得連接埠載波線路狀態
Container 取得包含 Component 的 IContainer(繼承至 Component)
CtsHolding 取得 Clear-To-Send 線路狀態
DataBits 取得或設定每一位元組資料標準長度
DiscardNull 取得或設定連接埠和接收緩衝區傳資料時是否忽略 null 位元 組
DsrHolding 取得 Data Set Ready (DSR)線路狀態
DtrEnable 取得或設定是否啟用 Data Terminal Ready (DTR)信號 Encoding 取得或設定傳輸資料之編碼方式
Handshake 取得或設定傳輸資料之交握通訊協定
IsOpen 取得通訊埠之開啟狀態
NewLine 取得或設定,用於解釋 ReadLine 和 WriteLine 之結尾方式
Parity 取得或設定同位檢查通訊協定
ParityReplace 取得或設定位元組,當發生同位檢查錯誤時,取代資料流中 錯誤字元
PortName 取得或設定通訊埠口
ReadBufferSize 取得或設定輸入緩衝區大小
ReadTimeout 取得或設定讀取作業位完成時之逾時毫秒數 ReceivedBytes
Threshold
取得或設定 dataReceived 事件發生前內部緩衝區允許位元組 數
RtsEnable 取得或設定是否啟用 Request To Send (RTS)信號 Site 取得或設定 Component 的 ISite(繼承至 Component)
StopBits 取得或設定每一位元組之停止位元標準數目
WriteBufferSize 取得或設定輸出緩衝區大小
WriteTimeout 取得或設定寫入作業位完成時之逾時毫秒數
↑H
3.1.6 公用方法
表 3.2 SearialPort 類別公用方法
名稱 說明
Close 關閉串口
CreateObjRef 建立包含所有相關資訊的物件 DiscardInBuffer 捨棄接收緩衝區資料
DiscardOutBuffer 捨棄傳輸緩衝區資料
Dispose 釋放 SearialPort 物件所使用之 Unmanaged 資源
Equals 判段倆個物件是否相等
GetHashCode 做為特定型別之雜湊函數
GetLifetimeService 擷取控制執行物件工作期之服務物件 GetPortNames 取得電腦之串列埠口列表
GetType 取得執行個體之型態
InitiualizeLifetimeService 起始化執行物件工作期之服務物件
Open 開啟通訊埠
Read 從輸入緩衝區讀取資料
ReadByte 從輸入緩衝區非同步讀取一個位元組資料
ReadChar 從輸入緩衝區非同步讀取一個位元組字元
ReadExisting 依編碼方式讀取輸入緩衝區所有位元組
ReadLine 讀取輸入緩衝區 NewLine 前所有資料
ReadTo 讀取輸入緩衝區指定 Value 前所有字元
ReferenceEquals 判段指定之 Object 是否相同執行個體
ToString 傳回字串
Write 將資料寫入串列輸出緩衝區
WriteLine 將指定字串加上 NewLIne 寫入輸出緩衝區
3.1.7 其它選項屬性 表 3.3 Parity 屬性表
成員名稱 說明
Even 設定偶同位元檢查
Mark 將同位元檢查保持為 1
None 不做同位元檢查
Odd 設定奇同位元檢查
Space 將同位元檢查保持為 0
↑H
表 3.4 StopBits 屬性表
成員名稱 說明
None 不使用停止位元
One 使用一個停止位元
OnePointFive 使用 1.5 停止位元
Two 使用兩個停止位元
表 3.5 Encoding 屬性表
成員名稱 說明
ASCII 可將 Unicode 字元編碼成 ASCII UTF7 使用 UTF-7 編碼為 Unicode 字元 UTF8 使用 UTF-8 編碼為 Unicode 字元 Unicode 使用 UTF-16 編碼為 Unicode 字元,
同時支援 Little-Endian 和 Bige-Endia UTF32 使用 UTF-32 編碼為 Unicode 字元
同時支援 Little-Endian 和 Bige-Endia
Default 使用作業系統目前 ANSI 字碼頁的編碼方式
3.1.8 通訊埠列表
可使用下列程式碼取得電腦之通訊埠列表,其中 cmbCOM 為表單下拉方塊 控制項:
For Each sp As String In SerialPort.GetPortNames cmbCOM.Items.Add(sp)
Next
cmbCOM.Sorted = True '排序
cmbCOM.SelectedIndex = 0 '第一個是預設選項 3.2 資料傳輸模擬
本節介紹一個簡單的資料傳輸模擬實驗,首先請使用一條兩端均有端子之信號 線,依下圖將電腦端之串口(公頭)Pin2 和 Pin3 連結。此項食驗亦可使用兩台 電腦,但必須有兩條具有公母頭之 RS232 傳輸線,然後使用一個 Null Modem 連 接兩條傳輸線。串口之 9 支 Pin 用途如下表說明。
↑H
1 2 3 4 5
6 7 8 9
1 2 3 4 5
6 7 8 9
圖 3.4 串口接線示意圖
表 3.6 RS232 Pin 用途說明表 Pin No 簡寫 用途
1 CD Carrier Detect 2 RXD Receive 3 TXD Transmit
4 DTR Data Terminal Ready 5 GND Ground
6 DSR Data Set Ready
7 RTS Request To Send 8 CTS Clear To Send 9 RI Ring Indicator
3.2.1 介面設計
請依下表之表列控制項,設計一傳輸實驗工作表單,工作畫面如下圖:
表 3.7 介面控制項列表
序 控制項類型 名稱 用途
1 Label lblPort 提示通訊埠
2 ComboBox cmbCom 串口列表 3 Button Button1 開啟串口 4 Button Button2 關閉串口
5 Button Button3 開啟設定屬性表單 6 Label lblSenddata 提示傳送的資料
7 TextBox txtSend 多行文字方塊,用於輸入傳送的資料 8 Button Button4 用於傳送資料
9 Label lblRecv 提示接收的資料
10 TextBox txtRecv 多行文字方塊,用於提示接收的資料 11 Button Button5 用於接收資料
↑H
圖 3. 5 系統工作畫面 3.2.2 傳輸模擬
請依下述步驟進行傳輸模擬:
Step 1. 設定串口屬性
Step 2. 在傳送資料文字方塊輸入待傳送資料 Step 3. 點擊傳送按鈕
Step 4. 點擊接收按鈕
Step 5. 將接收資料列示在接收資料文字方塊 Step 6. 比對傳送與接收資料是否相同
3.2.3 工作程式簡介 A. 字串型資料 傳送資料
RS232.Write(txtSend.Text) 接收資料
RS232.ReadTimeout = 1000
txtRecv.Text = RS232.ReadExisting()
B. 二進制資料 傳送資料
Dim l As Integer, s As String = ""
Dim buf As Byte()
s = txtSend.Text ↑H
l = Len(s)
buf = Encoding.ASCII.GetBytes(s) RS232.Write(buf, 0, l )
接收資料
Dim str As String Dim daBUF() As Byte
Dim n As Integer, i As Integer RS232.ReadTimeout = 1000 n = RS232.BytesToRead If n > 0 Then
ReDim daBUF(n - 1)
n = RS232.Read(daBUF, 0, RS232.BytesToRead) ‘// 以下列函數將取得之陣列資料轉為字串格式 str = Encoding.ASCII.GetString(daBUF)
‘// 或使用下列程序將取得之陣列資料轉為字串格式 str = ""
For i = 0 To n - 1
str = str & Chr(Val(daBUF(i))) Next
‘// 提示資料 txtRecv.Text = str
End If
3.3 IP-Link 傳輸模擬
因為 Helicomm IP-Link 系列產品是採用 Binary 模式來傳送資料,相關指令 格式則採十六進制表示,因此輸入傳送資料時必須以十六進制表示,特別提醒讀 者一點,十六進制資料是以兩個字元表示 1Byte,因此在轉換資料時,不能使用 前節之傳送方法。此外,IP-Link 指令傳送前,必須加上 CheckSum,本節也會針 對 CheckSum 演算法做說明。
3.3.1 傳送資料 Dim buf() As Byte
Dim si As Integer, l As Integer, s As String = ""
Dim i As Integer
s = txtSend.Text.Trim()
l = Len(s) / 2 ‘//兩個字元表示1Byte ↑H
ReDim buf(l - 1) For i = 1 To l
buf(i - 1) = CByte(Val("&H" + Mid$(s, i * 2 - 1, 2)))
‘// 每次取兩個字元,然後將字組轉成Binary Next
‘// 以下程式用於計算CheckSum
l = l + 1 ‘// 增加 1Byte 用來存放CheckSum 值 ReDim Preserve data_buf(l)
buf(l) = 0 ‘//預設CheckSum 值 0 For si = 0 To l - 1
buf(l) = buf(l) Xor buf(si) ‘//使用 Xor運算子來計算 CheckSum Next
RS232.Write(data_buf, 0, l + 1) ‘//傳送資料 '// 參數必須設為l+1 (含CheckSum), 表實際長度 3.3.2 接收資料
Dim buf() As Byte Dim str As String Dim daBUF() As Byte
Dim n As Integer, i As Integer n = RS232.BytesToRead If n > 0 Then
ReDim daBUF(n - 1)
n = RS232.Read(daBUF, 0, RS232.BytesToRead) str = ""
For i = 0 To n - 1
str = str & BinToHex(daBUF(i))
‘//BinToHex 為自定函數,可將傳入之位元組資料轉換為十六進制 Next
txtRecv.Text = str End If
由於接收資料會包含一位元組之CheckSum,此位元組必須捨棄。若讀者需 要驗證接收資料是否正確,可將前 n-1 位元組資料予以重算 CheckSum,再與 收到之CheckSum比對,若兩者相同,代表收到的資料是正確的。
3.3.3 常用數系轉換函數
為便於讀者使用 IP-Link系列產品指令,本節提供一些常用的數系轉換函 數。 ↑H
二進制轉十六進制 - BinToHex
Private Function BinToHex(ByVal b As Byte) As String BinToHex = Hex$(b)
If Len(BinToHex) = 1 Then BinToHex = "0" + BinToHex End If
End Function
十六進制轉二進制 - HexToBin
Public Sub HexToBin(ByVal s As String, buf() As Byte) Dim l As Integer
l = Len(s) / 2 ReDim buf(l - 1) For i = 1 To l
buf(i - 1) = CByte(Val("&H" + Mid$(s, i * 2 - 1, 2))) Next
End Sub
十六進制轉十進制數值 - HexToDec
Public Function HexToDec(ByVal s As String) As Long Dim l As Integer, i As Integer
l = Len(s) HexToDec = 0 For i = 1 To l
HexToDec = HexToDec + Val("&H" & Mid(s, i, 1)) * 16 ^ (l - i) Next
End Function
字串轉十六進制 - TxtToHex
Public Function TxtToHex(ByVal s As String) As String Dim sstr As String, l As Integer, ss As String
sstr = ""
For l = 1 To Len(s)
ss = Hex(Asc(Mid(s, l, 1))) If Len(ss) = 1 Then ss = "0" & ss sstr = sstr & ss
Next
TxtToHex = sstr
End Function ↑H
字串轉十六進制雙位元組 - TxtToDblHex
Public Function TxtToDblHex(ByVal s As String) As String Dim sstr As String, l As Integer, ss As String
sstr = ""
For l = 1 To Len(s)
ss = Hex(Asc(Mid(s, l, 1))) If Len(ss) = 3 Then
ss = "0" & ss Else
If Len(ss) = 2 Then ss = "00" & ss Else
If Len(ss) = 1 Then ss = "000" & ss End If
End If End If
sstr = sstr & ss Next
TxtToDblHex = sstr End Function
3.4 自動接收資料
VB介面有兩種自動接收資料方法,其一是使用 Timer 控制項,其二是使 RS232類別之 DataReceived 事件,以下說明兩種方法之設計技巧。
3.4.1 Timer 控制項
Step 1. 首先在表單加入一個 Timer 控制項並取名為 “Timer1”,然後在開啟串 口按鈕程序區段加入下列程序:
Timer1.Enabled = True
Timer1.Interval = 100 ‘//預設間隔致動時間, 以milisecond為單位
Step 2. 點開Timer1之Tick 事件,然後在事件區加入接收資料程序,如下述:
Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
'// 接收資料程序加在此處 End Sub
Step 3.在關閉串口按鈕程序區段加入下列程序: ↑H
Timer1.Enabled = False ‘//用於關閉 Timer 3.4.2 DataReceived 事件
Step 1. 首先在開啟串口按鈕程序區段設定Rs232物件之待接收資料位元組數- ReceivedBytesThreshold 為 1 Byte,語法如下:
RS232. ReceivedBytesThreshold = 1
‘//表示只要有一位元組資料到達即觸發此事件。
Step 2. 點開RS232物件之DataReceived 事件,然後在事件區加入接收資料程 序,如下述:
Private Sub RS232_DataReceived(ByVal sender As Object, ByVal e As
System.IO.Ports.SerialDataReceivedEventArgs) Handles RS232.DataReceived
'// 接收資料程序加在此處
End Sub
由於RS232物件之DataReceived 事件是使用多執行緒方式處理,它與表單主 程序使用不同的執行緒,原來接收資料程序段之 “txtRecv.Text = str”是以跨執行 緒方式處理,因而會產生錯誤,此錯誤必須改用代理程式來解決,工作原理為在 表單程序公用區宣告一公用代理程式,然後在接收資料事件區叫用代理程式來顯 示資料。處理方式簡述如下:
Step 1. 宣告代理程式-在表單程序公用區宣告
Delegate Function DelShowData(ByVal str As String) As String Step 2. 定義叫用代理工作程式-在表單內部程序定義區宣告
Private Sub DisplayData(ByVal str As String) If Me.txtRecv.InvokeRequired Then
Dim d As New DelShowData(AddressOf ShowData)
‘// 宣告一個代理人 d 並委派 ShowData程序來顯示資料
‘// ShowData 為真正顯示資料工作程式 Me.Invoke(d, New Object() {str})
End If End Sub
Step 3. 叫用代理工作程式-在DataReceived事件程序區最後 str = “接收資料”
Call DisplayData(str)
Step 4. 真正顯示資料工作程式-在表單內部程序定義區宣告 Private Sub ShowData(ByVal str As String)
txtReceive.Text = str
End Sub ↑H
3.5 IP-Link指令測試
本節示範一些IP-Link常用指令,測試節點使用節點1,LQI指數預設為7F,
封包序號均使用1。
3.5.1 DI測試
指令:817F000102AC05
回授:C17F000103AC0001(成功執行時)
說明:搭配一組磁簧開關來試驗,將開關之一端接在節點 IGO Port 之 I Pin,
另端接在 G Pin,請依序分合開關,再使用上述指令測試節點腳位狀態。
3.5.2 DO測試
指令:817F000103AD0401 /817F000103AD0400 回授:C17F000102AD00(成功執行時)
說明:搭配一個蜂鳴器來試驗,將蜂鳴器之一端接在節點 IGO Port 之 O Pin,
另端接在 G Pin,請依序執行上述兩到指令,並觀察蜂鳴器是否響想停停。
3.5.3 Tag定位測試 指令:817F000001AB
回授:C100000067AB 00417ECDFE5A 004271CAEA59 FFFFFFFFFFFF FFFFFFFFFFFF FFFFFFFFFFFF FFFFFFFFFFFF FFFFFFFFFFFF FFFFFFFFFFFF FFFFFFFFFFFF FFFFFFFFFFFF FFFFFFFFFFFF FFFFFFFFFFFF FFFFFFFFFFFF FFFFFFFFFFFF FFFFFF FFFFFF FFFFFFFFFFFF FFFFFFFFFFFF (成功執行時)
說明:此指令用於追蹤節點0所在位置之Tag,回應之Tag分別是代號65和66。回 授資料剖析:一道AB指令可取回17組Tag資訊,每組Tag資訊長6Bytes, 分 別表示 Tag-No、LQI、RSSI、IO及ADC之讀取值。
若同時對多個目標節點送出 AB 指令,利用三角定位法以 RSSI 之讀取值 來求算 Tag 之座標位置,即可標示出 Tag 之概略位置。三角定位法工作原理如 下圖所示。
↑H
Reader
Reader
Reader Tag
Tag
Tag Tag
Tag
Tag
Tag
Tag Reader
Reader
Reader Tag
Tag
Reader
Reader Reader Tag
Tag
Tag Tag
Tag Tag
Tag TagTag
Tag
Tag Tag
Tag Tag
圖 3.6 三角定為法
3.5.4 數位儀器資料感測
本節示範與數位儀器串接以讀取環境監測資料,示範儀器為溫溼度計,其 資料格式如下表。
溫溼度計資料格式表 位元組序 字組 說明
D15 02 前導字元,十六進制
D14 4 十進制
D13 1/2 1: 使用 Upper Display Data, 2: 使用 Lower Display Data D12, D11 01: ℃, 02: 0F, 08: m/s, 09: Knot, 10: Km/h, 11: ft/min, 12: mile/h D10 0/1 0: Positive, 1: Negative
D9 Decimal Point, 0: No, 1: ~ 3 : 小數為數
D8 to D1 D8高位元, D1低位元, EX: 數1234將表示為00001234(D8 to D1)
D0 0D 結束字元,十六進制
儀器串口屬性
屬性名 屬性值
BaudRate 9600 Parity No Data Bits 8
Stop Bits 1
以下舉三個範例說明感測資料之接收和讀取,所有範例均使用Upper Display Data模式。
範例1:若現在溫度為23.5℃,則ZigBee節點之接收資料格式為:
0234313031303130303030303233350D 資料長度為32個字元 範例2:若現在溫度為-120F,則ZigBee節點之接收資料格式為:
0234313032313030303030303031320D 資料長度為32個字元 範例3:若現在風速為2.5m/s,則ZigBee節點之接收資料格式為:
0234313038303130303030303032350D 資料長度為32個字元 接收到資料後,可依儀器規格還原為原來之讀數。
上述儀器亦可改用電腦模擬來自動產生感測資料,然後送給串接之節點,
最後再透過網路送至Master Node,傳送指令格式如下:
A17F0000100234313031303130303030303233350D A27F0000100234313032313030303030303031320D A37F0000100234313038303130303030303032350D
↑H