遠程無線數傳系統的設計方案
摘要:筆者嘗試設計一種遠程無線數據傳輸系統,並構建了發射終端和接收終端兩個軟件,成功實現了最遠5km數據傳輸距離,為基於兩地的不同數據庫之間數據的傳輸提供了一種新的解決方案。
關鍵詞:無線數據傳輸,二次開發包
1. 項目概念
遠程無線數傳軟件開發包的軟件基於Windows操作系統,採用Delphi開發,數據庫採用SQL Server2000作為後臺數據庫。系統以簡易可行的方法實現了遠程無線數傳技術,實時數據庫的數據校驗和寫入。經過了實際的檢驗,現已成功穩定運行。
2. 遠程無線數傳軟件開發包的無線傳輸模式
3. 遠程無線數傳軟件開發包的數據流程圖
4. 無線數傳設備選型
採購深圳市科易連通訊設備有限公司生產的KYL-320I無線數傳模塊,具體參數如下:
載波頻率: 433MHz, 450MHz,470MHz,868MHz,915MHz等 ISM頻點;
多種可選的通訊接口:RS-232、TTL、 RS-485、USB;
8個通訊信道,也可根據客戶要求擴展;
傳輸數率:1200、2400、4800、9600、19200、38400bps;
數據格式:8N1/8E1/8O1(也可提供其它格式,如9位數據位);
收發一體,半雙工工作模式;
低功耗,並具有休眠功能;
工作溫度:-35℃ ~ +75℃(工業級);
天線阻抗:50Ω(標配為SMA,可定製);
供電電源: DC 5V (可根據用戶要求定製);
輸出功率: ≤500mW;(可根據用戶要求定製)
接收電流: <28mA(TTL接口);
接收靈敏度:-123dBm (1200bps) ;
-118dBm (9600bps)
發射電流: <350mA;
休眠電流: <20uA;
傳輸距離:2km 以上(BER=10-5@9600bps,標配10cm天線,空曠地,天線高度1.5m);
3Km 以上(BER=10-5@1200bps,標配10cm天線,空曠地,天線高度1.5m);
外型尺寸:80mm×45mm×20mm (不包括天線接頭 )。
模塊如下圖
5. 系統設計
系統設計包括以下主要模塊:字符信息轉換設計,發送模塊設計,接收模塊設計,信息加密設計,系統初始化設計。以下是各模塊的詳細設計
1. 字符信息轉換設計
字符信息轉換設計所要完成的工作是將字段內容信息轉換為無線電信號能夠識別的二進制信息,同時在接收端收到信息後又能準確無誤的將這些二進制信息還原成正確的字段內容信息,這部分是基礎性工作。
1 二進制十六進制相互轉換函數編寫
//把二進制串轉換成十六進制串或相反
function BinToHexEachOther(ValueA : string; Action : Boolean) : string;
var
ValueArray1 : Array [0..15] of string[4];
ValueArray2 : Array [0..15] of char;
i : shortint;
begin
//數組初始化
ValueArray1[0] := '0000'; ValueArray1[1] := '0001'; ValueArray1[2] := '0010';
ValueArray1[3] := '0011'; ValueArray1[4] := '0100'; ValueArray1[5] := '0101';
ValueArray1[6] := '0110'; ValueArray1[7] := '0111'; ValueArray1[8] := '1000';
ValueArray1[9] := '1001'; ValueArray1[10] := '1010'; ValueArray1[11] := '1011';
ValueArray1[12] := '1100'; ValueArray1[13] := '1101'; ValueArray1[14] := '1110';
ValueArray1[15] := '1111';
for i := 0 to 15 do
if i >= 10 then ValueArray2[i] := chr(65 + (i - 10))
else ValueArray2[i] := inttostr(i)[1];
Result := '';
if Action then
begin //二進制串轉換成十六進制串
if (Length(ValueA) MOD 4 <> 0) then
ValueA := stringofchar('0',Length(ValueA) MOD 4) + ValueA;
while (Length(ValueA) >= 4) do
begin
for i := 0 to 15 do
if Copy(ValueA,1,4) = ValueArray1[i] then
Result := Result + ValueArray2[i];
ValueA := Copy(ValueA,5,Length(ValueA) - 4);
end;
end
else begin //十六進制串轉換成二進制串
while (Length(ValueA) >= 1) do
begin
for i := 0 to 15 do
if Copy(ValueA,1,1) = ValueArray2[i] then
Result := Result + ValueArray1[i];
ValueA := Copy(ValueA,2,Length(ValueA) - 1);
end;
end;
end;
2 二進制與字符串互相轉換函數編寫
//把字符串轉化為二進制數
Function ConvertStrToBin(Value : string):string;
var tempHex : string[255];
i : integer;
begin
Result := '';
if trim(Value) = '' then Exit;
tempHex := '';
for i := 1 to Length(Value) do
begin
tempHex := IntToHex(Ord(Value[i]),2);//每個字符轉成兩位十六進制數
Result := Result + BinToHexEachOther(tempHex,False);//十六進制轉成二進制
end;
end;
function HexCharToInt(HexToken : char):Integer;
begin
Result:=0;
if (HexToken>#47) and (HexToken
Result:=Ord(HexToken)-48
else if (HexToken>#64) and (HexToken
Result:=Ord(HexToken)-65 + 10;
end;
//把二進制數據轉化為字符串
Function ConvertBinToStr(Value : string):string;
Var tempHex : string;
i, tempInt : integer;
begin
Result := '';
if trim(Value) = '' then Exit;
tempHex := BinToHexEachOther(Value,true);//二進制轉成十六進制
i := 0;
Repeat
begin
i := i + 1;
tempInt := HexCharToInt(tempHex[i]);
i := i + 1;
tempInt := tempInt * 16 + HexCharToInt(tempHex[i]);
//以上將兩位十六進制數轉變為一個十進制數
Result := Result + chr(TempInt); //轉成ASCII碼
end;
Until i >= length(tempHex)
end;
2. 發送模塊設計
發送模塊設計是完成將二進制信息用相應的載波頻率發送出去,分為數據監聽、無線電間隔識別碼、數據發送和數據校驗4個步驟。
1 數據監聽
//如果數據緩衝區有數據,則實時轉換2進制數據,同時完成表字段的數據校驗寫入。
procedure TForm1.ComPort1RxChar(Sender: TObject; Count: Integer);
var
Str: String;
begin
ComPort1.ReadStr(Str, Count);
Memo2.Text:=Memo2.Text+Str;
if memo2.Text <> '0' then
begin
Button5.Click;
Timer1.Enabled:=true;
end;
end;
2 無線電間隔識別碼
//將表字段對應的值轉換為2進制後發送,前2位數字為無線電間隔碼,#號符為本條記錄發送完畢識別碼。調用SendString過程發送數據。
procedure TForm1.Button6Click(Sender: TObject);
begin
SendString(ConvertStrToBin('a1')+ConvertStrToBin(edit1.Text));
SendString(ConvertStrToBin('b1')+ConvertStrToBin(edit2.Text));
SendString(ConvertStrToBin('c1')+ConvertStrToBin(edit3.Text));
SendString(ConvertStrToBin('d1')+ConvertStrToBin(edit4.Text));
SendString(ConvertStrToBin('#'));
3 end;
4 數據發送過程
//發送數據的過程。
procedure TForm1.SendString(const str: string);
var
obj:PAsync;
begin
InitAsync(obj);
try
ComPort1.WriteStrAsync(str,obj);
ComPort1.WaitForAsync(obj);
finally
DoneAsync(obj);
end;
end;
④數據校驗
//引入時鐘實時監聽,並根據回傳符號判斷數據發送是否成功。
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if (edit1.text=edit5.text) and (edit2.text=edit6.text) and (edit3.text=edit7.text) and (edit4.text=edit8.text) and (edit9.text='$') then
begin
{SendString(ConvertStrToBin('a1')+ConvertStrToBin(edit5.Text));
SendString(ConvertStrToBin('b1')+ConvertStrToBin(edit6.Text));
SendString(ConvertStrToBin('c1')+ConvertStrToBin(edit7.Text));
SendString(ConvertStrToBin('d1')+ConvertStrToBin(edit8.Text));}
SendString(ConvertStrToBin('@'));
Timer1.Enabled :=false;
Button4.Click;
memo3.Clear;
dialogs.showmessage('發送成功');
end
else
begin
SendString(ConvertStrToBin('+'));
Timer1.Enabled:=false;
Button4.Click;
memo3.Clear;
dialogs.showmessage('發送失敗!');
end;
end;
3. 接收模塊設計
接收模塊設計完成對接收的二進制信息進行解析並實時寫入數據庫保存,分為數據解析、數據寫入和數據界定3個步驟
1 數據解析
//將接收到的2進制數據轉換為字符串,並截獲出對應的字段值,即對號入座。
procedure TForm1.Button5Click(Sender: TObject);
begin
memo3.Text :=ConvertBinToStr(memo2.Text) ;
edit5.Text:= GetStr(memo3.Text,'a1','b1') ;
edit6.Text:= GetStr(memo3.Text,'b1','c1') ;
edit7.Text:= GetStr(memo3.Text,'c1','d1') ;
edit8.Text:= GetStr(memo3.Text,'d1','#') ;
edit9.Text:= RightStr(memo3.Text,1);
end;
2 數據寫入
//探測時鐘
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if AnsiContainsStr(memo3.Text, '#') then //如果時鐘探測到解析數據區收到'#'碼,則表示數據接收完畢等待寫入校驗,並同時向發送端發送校驗數據。
begin
edit5.Text:= GetStr(memo3.Text,'a1','b1') ;
edit6.Text:= GetStr(memo3.Text,'b1','c1') ;
edit7.Text:= GetStr(memo3.Text,'c1','d1') ;
edit8.Text:= GetStr(memo3.Text,'d1','#') ;
Button7.Click;
Timer1.Enabled:=false;
Button4.Click;
end;
if AnsiContainsStr(memo3.Text, '@') then //如果時鐘探測到解析數據區收到'@'碼,則表示發送端校驗數據成功通過,可以向表中寫入記錄。
begin
ADOTable1.Insert;
ADOTable1.FieldByName('name').AsString:=edit5.Text;
ADOTable1.FieldByName('code').AsString:=edit6.Text;
ADOTable1.FieldByName('mz').AsString:=edit7.Text;
ADOTable1.FieldByName('dj').AsString:=edit8.Text;
ADOTable1.Post;
DBGrid1.Refresh;
Timer1.Enabled:=false;
Button4.Click;
end;
end;
3 數據界定
//指定獲取數據界限的函數
function GetStr(StrSource,StrBegin,StrEnd:string):string;
var
in_star,in_end:integer;
begin
in_star:=AnsiPos(strbegin,strsource)+length(strbegin);
in_end:=AnsiPos(strend,strsource);
result:=copy(strsource,in_star,in_end-in_star);
end;
4. 信息加密設計
採用美國國防部軍方的MD5加密設計,對重要財務敏感信息加密發送。使用MD5加密先定義變量並作以下單元引用聲明:
var
Form1: TForm1;
md5 : TIdHashMessageDigest5;
longWordRec : T4x4LongWordRecord;
//對文本信息進行MD5加密
procedure TForm1.Button2Click(Sender: TObject);
begin
md5 := TIdHashMessageDigest5.Create;
longWordRec:=md5.HashValue(memo1.Text);
edit3.Text:= md5.AsHex(longWordRec) ;
end;
5. 測初始化設計
初始化設計包括:搜索可用的SQL服務器,建立連接,串口設置等。
//啟動SQL數據庫服務器並對接相應的表。
procedure TForm1.Button3Click(Sender: TObject);
begin
ADOConnection1.Connected:=false;
ADOConnection1.ConnectionString:='Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=test;Data Source='+ComboBox1.Text+'';
ADOConnection1.Connected:=true;
ADOConnection1.KeepConnection:=true;
ADOTable1.TableName:='Testtable';
ADOTable1.active:=true;
DBGridAutoSize(DBGrid1);
end;
//程序運行時搜索網內可以用的SQL服務器
procedure TForm1.FormShow(Sender: TObject);
var
I:integer;
x,y:oleVariant;
begin
x := CreateOleObject('SQLDMO.Application');
y := x.ListAvailableSQLServers;
ComboBox1.Clear;
for I := 1 to y.Count do
begin
ComboBox1.Items.Add(y.item(I))
end
end;
//啟動程序時自動讀取system.ini配置文件,設定串口通訊參數。
;-----------------------------------------------------
;無線傳輸通訊設置
;----------------------------------------------------
[COMM1]
ComPort=COM5---------------------打開串口5作為通訊端口
BaudRate=2400---------------------設置波特率2400
Parity=None---------------------校驗位為空
DataBits=8---------------------數據位8
StopBits=1---------------------停止位1
6. 測試程序界面
6. 系統測試
· 數傳設備:KYL-320I型無線數傳模塊
· 傳輸距離:5km(有工廠廠房阻擋及電磁干擾環境)
· 平均傳輸速度:3秒/每條數據
· 斷電續傳:有
· 正確率:100%
· 校驗:MD5加密算法校驗
7. 結論
筆者通過以上設計工作成功實現了最遠5km數據傳輸距離,為基於兩地的不同數據庫之間數據的傳輸提供了一種新的解決方案。
閱讀更多 探祕矩陣 的文章