发表于:2005/4/29 21:03:00
#0楼
有一个无线网络仪器,能够和若干个仪器组成分组网,每个仪器本身也有IP地址,同时组成的网络里面也有网关地址什么的,当发送报文时仪器本身会在发出报文后自动发给包含刚才发出去的报文数据的网络ID,如果目的仪器收到发送方发过来的数据后就会给发送方一个确认信息,发送方根据这个包含网络ID的确认信息给发送方终端软件一个确认数据帧,
如发送的数据:
C0 32 0 0 1E 14 12 0 0 FF 11 18 7F FE 0 0 1 FE 0 0 2 31 32 33 0 0 C0 其中C0是帧头标志,第二个C0是结尾标志,32是命令字,0 0 是服务类型,1E是总长度,14 12 是用户自定义的报文ID,仪器会根据这个数生成一个随机的仪器网络ID, 0 0 是分片偏移,FF是生存期,11 是协议类型,18 7F 是前边十个Byte的校验和,Fe 0 0 1 是发送源IP,Fe 0 0 2 是目的IP,31 32 33 是要发送的数据 123,0 0 是发送时间,C0是帧尾
.
发送完数据后仪器会马上把自身生成的ID号信息传送过来,格式为:
C0 61 6 14 12 0 0 4 0 C0 同样两个C0是帧头帧尾,61是命令字,14 12 就是刚才发出去数据的用户ID,0 0 表示时间,4 0 是仪器生成的网络ID.
接收方收到发送方发出的数据后就会返回确认信息,发送方接收到这个确认信息后就给终端软件发一串表示对方已经正常接收的确认数据:C0 62 2 4 0 C0 两个C0同样是帧头帧尾,62是命令字,2 是数据长度, 4 0是仪器生成的网络ID
如果对方多长时间没有给发送方回执的话,发送方会自动给终端软件一个确认失败,对方没有受到的信息
C0 63 2 4 0 C0 两个C0同样是帧头帧尾,63是命令字,2 是数据长度, 4 0是仪器生成的网络ID
mscomm的属性如下:
settings=9600,n,8,1
handshaking=comRTS
rthhold=1
inputlen=0
我采取在On_Comm中启动计时器接收的方法,在一个一个单个发送数据的时候没有什么问题,返回确认信息的正确率很高,但是在间隔1秒钟自动发送的情况下就很糟糕,收到的返回确认信息要缺少好多,用串口调试助手接收没有问题,确认信息全能收到,排除了仪器本身的问题,我不知道这是为什么,在这里把源代码给出来,大家交流一下.我怀疑产生丢帧的原因是每次取数据的时候取得有问题,也怀疑是因为定时器的时间间隔有问题,但是具体什么原因我还是没有搞明白,不知道怎么解决才好,希望各位高手能指点一下.我得QQ号码:42294060,如果有什么想法大家可以交流一下(晚上9点后在线)
源代码如下(发送事件从略,就是mscomm.output一下就好)
'每次接收接受到一个字符时候就产生一次ON_comm事件,在ON_comm事件中把定时接收打开,定时器的interval是200ms,但是在实际运行过程中却出现丢数据帧的情况,我所要的数据是C0 .....C0之间的数据.
Public Sub MSComm_OnComm()
Select Case MSComm.CommEvent
Case 2
If RecFlag = False Then
'MSComm.RTSEnable = False
'MSComm.DTREnable = False
TmrDealRec.Enabled = True '打开定时器
End If
End Select
End Sub
Private Sub TmrDealRec_Timer()
Dim midInbuffer() As Byte '每次产生On_Comm事件时接收到的数据存入该数组中
Dim midBound As Integer
ReDim midInbuffer(0) As Byte
Dim ReadLoop As Integer
Dim rec As String
Dim B() As Byte '中间数组,把收到的数据存入到该数组中,该数组作为中转数组
Dim timeout As Double ' 定义超时时间
Dim MyArray() As Byte '把中转数组B()中的数据存入该数组
timeout = 0.07 '定义超时时间
midBound = 0
Dim i As Integer
Dim j As Integer
Start = Timer
TmrDealRec.Enabled = False '关闭定时器
Do While Timer < Start + timeout
If MSComm.InBufferCount > 0 Then
B = MSComm.Input
ReDim Preserve midInbuffer(midBound + UBound(B) - LBound(B) + 1)
For iBoundLoop = LBound(B) + 1 To UBound(B) + 1 Step 1
midInbuffer(midBound + iBoundLoop) = B(iBoundLoop - 1)
rec = rec + Hex(midInbuffer(midBound + iBoundLoop)) + Chr(32)
Next
midBound = UBound(midInbuffer)
End If
DoEvents
Loop
FrmRec.Text1.Text = FrmRec.Text1.Text + rec + vbNewLine '把收到的数据放入text控件中,但是显示结果缺少若干数据帧
'从数组中选出整帧的数据'即C0 ......C0
j = 1
For i = 2 To UBound(midInbuffer)
If midInbuffer(i) = 192 And midInbuffer(i - 1) <> 192 Then
ReDim MyArray(i - j)
For j = j To i
MyArray(i - j) = midInbuffer(j)
Next
Call DealData1(MyArray) '调用处理程序处理整帧的数据
j = i + 1
End If
Next
'Else
'MsgBox " buquan' "
'End If
' Erase midInbuffer
' MSComm.RThreshold = 1
'MSComm.DTREnable = True
recbuf = ""
'下面代码本来是想存储没有帧尾的数据的,但是好像不起什么作用
Dim k As Integer
Dim position As Integer
Dim StartArray() As Byte
Dim EndArray() As Byte
If midInbuffer(LBound(midInbuffer)) <> &HC0 Then
For k = LBound(midInbuffer) To UBound(midInbuffer)
If midInbuffer(k) = &HC0 Then
positon = k
Exit For
End If
Next
ReDim StartArray(0 To position)
For k = LBound(midInbuffer) To position
StartArray(k) = midInbuffer(k)
Next
ElseIf midInbuffer(UBound(midInbuffer)) <> &HC0 Then
For k = UBound(midInbuffer) To 1 Step -1
If midInbuffer(k) = &HC0 Then
position = k
Exit For
End If
Next
ReDim EndArray(0 To UBound(midInbuffer) - position)
For k = position To UBound(midInbuffer)
EndArray(k - position) = midInbuffer(k)
Debug.Print EndArray(k - position)
Next
End If
End Sub
处理一帧一帧的数据
Private Sub DealData1(A() As Byte)
Dim strxuyao(1 To 300) As Byte '存储接收到的所有数据
Dim fanhui As String
Dim ChuShiIP As String '定义初IP地址
Dim count As Integer '用于存放有几个需要替换的DBDC DBDD,总共替换了多少次
ReDim B(0 To UBound(A))
Dim RowCount As Integer '记录当前总共有已发出的数据
Dim DTENetID As String '记录用户生成的网络ID
Dim PruNetID As String '记录仪器本身生成的网络ID
Dim PruFanID As String '记录仪器本身确认信息的网络ID
For i = 0 To UBound(A)
B(i) = A(UBound(A) - i)
Next
If UBound(C) > 3 Then
B(0) = &HC0 And B(1) = &H62 Then
For i = 0 To UBound(B)
Next
DTENetID = Hex(Val(B(3))) & Hex(Val(B(4))) '记录用户生成的网络ID
PruNetID = Val(B(7)) & Val(B(8)) '记录仪器自身生成的网络ID
For RowCount = 1 To MSFlexGrid2.Rows - 1
If MSFlexGrid2.TextMatrix(RowCount, 1) = DTENetID Then MSFlexGrid2.TextMatrix(RowCount, 9) = PruNetID
Next
ElseIf B(0) = &HC0 And B(1) = &H62 Then
PruFanID = Val(C(3)) & Val(C(4))
For RowCount = 1 To MSFlexGrid2.Rows - 1
If MSFlexGrid2.TextMatrix(RowCount, 9) = PruFanID Then
MSFlexGrid2.TextMatrix(RowCount, 2) = "成功"
MSFlexGrid2.TextMatrix(RowCount, 7) = Time
End If
Next
ElseIf B(0) = &HC0 And B(1) = &H63 Then
PruFanID = Val(B(3)) & Val(B(4))
For RowCount = 1 To MSFlexGrid2.Rows - 1
If MSFlexGrid2.TextMatrix(RowCount, 9) = PruFanID Then
MSFlexGrid2.TextMatrix(RowCount, 2) = "失败"
MSFlexGrid2.TextMatrix(RowCount, 7) = Time
End If
Next
End If
End If
End Sub
如发送的数据:
C0 32 0 0 1E 14 12 0 0 FF 11 18 7F FE 0 0 1 FE 0 0 2 31 32 33 0 0 C0 其中C0是帧头标志,第二个C0是结尾标志,32是命令字,0 0 是服务类型,1E是总长度,14 12 是用户自定义的报文ID,仪器会根据这个数生成一个随机的仪器网络ID, 0 0 是分片偏移,FF是生存期,11 是协议类型,18 7F 是前边十个Byte的校验和,Fe 0 0 1 是发送源IP,Fe 0 0 2 是目的IP,31 32 33 是要发送的数据 123,0 0 是发送时间,C0是帧尾
.
发送完数据后仪器会马上把自身生成的ID号信息传送过来,格式为:
C0 61 6 14 12 0 0 4 0 C0 同样两个C0是帧头帧尾,61是命令字,14 12 就是刚才发出去数据的用户ID,0 0 表示时间,4 0 是仪器生成的网络ID.
接收方收到发送方发出的数据后就会返回确认信息,发送方接收到这个确认信息后就给终端软件发一串表示对方已经正常接收的确认数据:C0 62 2 4 0 C0 两个C0同样是帧头帧尾,62是命令字,2 是数据长度, 4 0是仪器生成的网络ID
如果对方多长时间没有给发送方回执的话,发送方会自动给终端软件一个确认失败,对方没有受到的信息
C0 63 2 4 0 C0 两个C0同样是帧头帧尾,63是命令字,2 是数据长度, 4 0是仪器生成的网络ID
mscomm的属性如下:
settings=9600,n,8,1
handshaking=comRTS
rthhold=1
inputlen=0
我采取在On_Comm中启动计时器接收的方法,在一个一个单个发送数据的时候没有什么问题,返回确认信息的正确率很高,但是在间隔1秒钟自动发送的情况下就很糟糕,收到的返回确认信息要缺少好多,用串口调试助手接收没有问题,确认信息全能收到,排除了仪器本身的问题,我不知道这是为什么,在这里把源代码给出来,大家交流一下.我怀疑产生丢帧的原因是每次取数据的时候取得有问题,也怀疑是因为定时器的时间间隔有问题,但是具体什么原因我还是没有搞明白,不知道怎么解决才好,希望各位高手能指点一下.我得QQ号码:42294060,如果有什么想法大家可以交流一下(晚上9点后在线)
源代码如下(发送事件从略,就是mscomm.output一下就好)
'每次接收接受到一个字符时候就产生一次ON_comm事件,在ON_comm事件中把定时接收打开,定时器的interval是200ms,但是在实际运行过程中却出现丢数据帧的情况,我所要的数据是C0 .....C0之间的数据.
Public Sub MSComm_OnComm()
Select Case MSComm.CommEvent
Case 2
If RecFlag = False Then
'MSComm.RTSEnable = False
'MSComm.DTREnable = False
TmrDealRec.Enabled = True '打开定时器
End If
End Select
End Sub
Private Sub TmrDealRec_Timer()
Dim midInbuffer() As Byte '每次产生On_Comm事件时接收到的数据存入该数组中
Dim midBound As Integer
ReDim midInbuffer(0) As Byte
Dim ReadLoop As Integer
Dim rec As String
Dim B() As Byte '中间数组,把收到的数据存入到该数组中,该数组作为中转数组
Dim timeout As Double ' 定义超时时间
Dim MyArray() As Byte '把中转数组B()中的数据存入该数组
timeout = 0.07 '定义超时时间
midBound = 0
Dim i As Integer
Dim j As Integer
Start = Timer
TmrDealRec.Enabled = False '关闭定时器
Do While Timer < Start + timeout
If MSComm.InBufferCount > 0 Then
B = MSComm.Input
ReDim Preserve midInbuffer(midBound + UBound(B) - LBound(B) + 1)
For iBoundLoop = LBound(B) + 1 To UBound(B) + 1 Step 1
midInbuffer(midBound + iBoundLoop) = B(iBoundLoop - 1)
rec = rec + Hex(midInbuffer(midBound + iBoundLoop)) + Chr(32)
Next
midBound = UBound(midInbuffer)
End If
DoEvents
Loop
FrmRec.Text1.Text = FrmRec.Text1.Text + rec + vbNewLine '把收到的数据放入text控件中,但是显示结果缺少若干数据帧
'从数组中选出整帧的数据'即C0 ......C0
j = 1
For i = 2 To UBound(midInbuffer)
If midInbuffer(i) = 192 And midInbuffer(i - 1) <> 192 Then
ReDim MyArray(i - j)
For j = j To i
MyArray(i - j) = midInbuffer(j)
Next
Call DealData1(MyArray) '调用处理程序处理整帧的数据
j = i + 1
End If
Next
'Else
'MsgBox " buquan' "
'End If
' Erase midInbuffer
' MSComm.RThreshold = 1
'MSComm.DTREnable = True
recbuf = ""
'下面代码本来是想存储没有帧尾的数据的,但是好像不起什么作用
Dim k As Integer
Dim position As Integer
Dim StartArray() As Byte
Dim EndArray() As Byte
If midInbuffer(LBound(midInbuffer)) <> &HC0 Then
For k = LBound(midInbuffer) To UBound(midInbuffer)
If midInbuffer(k) = &HC0 Then
positon = k
Exit For
End If
Next
ReDim StartArray(0 To position)
For k = LBound(midInbuffer) To position
StartArray(k) = midInbuffer(k)
Next
ElseIf midInbuffer(UBound(midInbuffer)) <> &HC0 Then
For k = UBound(midInbuffer) To 1 Step -1
If midInbuffer(k) = &HC0 Then
position = k
Exit For
End If
Next
ReDim EndArray(0 To UBound(midInbuffer) - position)
For k = position To UBound(midInbuffer)
EndArray(k - position) = midInbuffer(k)
Debug.Print EndArray(k - position)
Next
End If
End Sub
处理一帧一帧的数据
Private Sub DealData1(A() As Byte)
Dim strxuyao(1 To 300) As Byte '存储接收到的所有数据
Dim fanhui As String
Dim ChuShiIP As String '定义初IP地址
Dim count As Integer '用于存放有几个需要替换的DBDC DBDD,总共替换了多少次
ReDim B(0 To UBound(A))
Dim RowCount As Integer '记录当前总共有已发出的数据
Dim DTENetID As String '记录用户生成的网络ID
Dim PruNetID As String '记录仪器本身生成的网络ID
Dim PruFanID As String '记录仪器本身确认信息的网络ID
For i = 0 To UBound(A)
B(i) = A(UBound(A) - i)
Next
If UBound(C) > 3 Then
B(0) = &HC0 And B(1) = &H62 Then
For i = 0 To UBound(B)
Next
DTENetID = Hex(Val(B(3))) & Hex(Val(B(4))) '记录用户生成的网络ID
PruNetID = Val(B(7)) & Val(B(8)) '记录仪器自身生成的网络ID
For RowCount = 1 To MSFlexGrid2.Rows - 1
If MSFlexGrid2.TextMatrix(RowCount, 1) = DTENetID Then MSFlexGrid2.TextMatrix(RowCount, 9) = PruNetID
Next
ElseIf B(0) = &HC0 And B(1) = &H62 Then
PruFanID = Val(C(3)) & Val(C(4))
For RowCount = 1 To MSFlexGrid2.Rows - 1
If MSFlexGrid2.TextMatrix(RowCount, 9) = PruFanID Then
MSFlexGrid2.TextMatrix(RowCount, 2) = "成功"
MSFlexGrid2.TextMatrix(RowCount, 7) = Time
End If
Next
ElseIf B(0) = &HC0 And B(1) = &H63 Then
PruFanID = Val(B(3)) & Val(B(4))
For RowCount = 1 To MSFlexGrid2.Rows - 1
If MSFlexGrid2.TextMatrix(RowCount, 9) = PruFanID Then
MSFlexGrid2.TextMatrix(RowCount, 2) = "失败"
MSFlexGrid2.TextMatrix(RowCount, 7) = Time
End If
Next
End If
End If
End Sub