我需要接收下位机上传过来的数据,每条数据最长不超过32个字节,但是每条数据每隔20ms上传一次,所以我接收到数据后再处理保存需要在20ms内完成。但是我现在使用下边的代码接收数据,发现一条数据没有接收完整就进行了保存(一条数据被分成2次保存起来),现在请论坛的朋友帮我看看我的代码在什么地方需要改进,能够等一条数据全部进来以后在进行保存啊?
Select Case MSComm1.CommEvent
Case comEvReceive
MSComm1.RThreshold = 0 '禁止在处理数据时再触发OnComm事件,而干扰了数据处理
inByte = MSComm1.Input
For i = 0 To UBound(inByte)
If Len(Hex(inByte(i))) = 1 Then
str1 = 0 & Hex(inByte(i))
Else
str1 = Hex(inByte(i))
End If
strData = strData & str1
Next
MSComm1.InBufferCount = 0 '清空缓冲区数据,避免下次通信出错。
Text6 = strData
MSComm1.RThreshold = 1 '恢复每次读一个触发一次OnComm事件
End Select
sqlinsert = "insert into [客车列尾运行数据] ([主机编号]) values ('" + Text6.Text + "')"
Dim rs_suminsert As New ADODB.Recordset
rs_suminsert.CursorLocation = adUseClient
rs_suminsert.Open sqlinsert, conn, adOpenKeyset, adLockPessimisticMSComm1控件的属性设置如下:
With MSComm1
.CommPort = 1
.Settings = "9600,n,8,1"
.InBufferCount = 0
.InputLen = 0
.RThreshold = 1
.InputMode = comInputModeBinary '以2进制接收
.PortOpen = True
Select Case MSComm1.CommEvent
Case comEvReceive
MSComm1.RThreshold = 0 '禁止在处理数据时再触发OnComm事件,而干扰了数据处理
inByte = MSComm1.Input
For i = 0 To UBound(inByte)
If Len(Hex(inByte(i))) = 1 Then
str1 = 0 & Hex(inByte(i))
Else
str1 = Hex(inByte(i))
End If
strData = strData & str1
Next
MSComm1.InBufferCount = 0 '清空缓冲区数据,避免下次通信出错。
Text6 = strData
MSComm1.RThreshold = 1 '恢复每次读一个触发一次OnComm事件
End Select
sqlinsert = "insert into [客车列尾运行数据] ([主机编号]) values ('" + Text6.Text + "')"
Dim rs_suminsert As New ADODB.Recordset
rs_suminsert.CursorLocation = adUseClient
rs_suminsert.Open sqlinsert, conn, adOpenKeyset, adLockPessimisticMSComm1控件的属性设置如下:
With MSComm1
.CommPort = 1
.Settings = "9600,n,8,1"
.InBufferCount = 0
.InputLen = 0
.RThreshold = 1
.InputMode = comInputModeBinary '以2进制接收
.PortOpen = True
解决方案 »
- 多次随机抽奖
- (求助)请问我想打开文件,生成新文件1,再打开新文件1生成新文件2,如此反复生成10份新文件,应该怎样做,自己编程实现不了,请高手指教。
- 一个奇怪的错误提示
- the rowset is not bookmarkable这个错误提示是怎么回事
- 俺新入门,请问VB用数据库第一手必要问题!谢谢,100分
- 100+100=200分:有过word方面编程的朋友请过来帮我理理思路,现场解答,现场给分!
- 如何可以實現對excel文件名的檢測驗証功能????急件﹗﹗﹗﹗
- 把数据写入内存的API是什么啊???
- vb 如何调用其他语言的DLL 如Delphi? 反之Delphi 如何调VB写的DLL文件?
- showwindow shell 第三方程序隐藏
- winsock 问题
- VB 同时打开两个数据库
事件触发后用MSComm1.RThreshold = 0关闭事件触发似没有必要,你一次最多32字节,也是32个事件,要不了多长时间。
用一个静态变量(static icount)或全局变量,来累计次数,icount为32时,保存并清0.你可以试一下,时间是否够用。如果不够用可设置.RThreshold = 32,也就是说32字节一触发事件,事件触发后读了数据就直接存盘。
Select Case MSComm1.CommEvent
Case comEvReceive
MSComm1.RThreshold = 0
t = Timer
While Timer - t < 0.01 '从0.01到0.02(20sm)做延时,自己调试
Wend
inByte = MSComm1.Input
For i = 0 To UBound(inByte)
strData = strData + Format(Hex(inByte(i)), "00")
Next
Text6 = strData
MSComm1.RThreshold = 1 '恢复每次读一个触发一次OnComm事件
End Select
Select Case MSComm1.CommEvent
Case comEvReceive
MSComm1.RThreshold = 0
Sleep 10
inByte = MSComm1.Input
For i = 0 To UBound(inByte)
strData = strData + Format(Hex(inByte(i)), "00")
Next
Text6 = strData
MSComm1.RThreshold = 1 '恢复每次读一个触发一次OnComm事件
End Select
把strData定义为全局的,此外你需要对你接收到的数据(strData的内容)进行分解,寻找起始,再寻找结束的,把这个字符串截取出来,存入数据库,余下的内容等待下一次触发了OnComm事件后,在处理
Select Case MSComm1.CommEvent
Case comEvReceive
MSComm1.RThreshold = 0
Sleep 10 '延迟10ms,等待数据接收
inByte = MSComm1.Input
For i = 0 To UBound(inByte)
strData = strData + Format(Hex(inByte(i)), "00")
Next
Text6 = strData
MSComm1.RThreshold = 1 '恢复每次读一个触发一次OnComm事件
End Select
End Sub
'数据存储处理过程
Sub subSaveString()
Dim strP As String
Dim intStart As String
Dim intEnd As String
intStart = InStr(1, strData, "1002") '查找起始字符串的位置
intEnd = InStr(1, strData, "1003") '查找结束字符串的位置
If intStart > 0 And intEnd > 0 And intEnd > intStart Then
strP = Mid(strData, intStart, intEnd - intStart + 5) 'strP就是你要保存的一条数据,起始是1002 结束是 1003
Replace strData, strP, "", intStart, 1, vbTextCompare '将strdata中的strP去掉
End If
End Sub
为你做了一个模拟程序,程序结构大体如下,自己改改即可:Option Explicit
Dim iStr As StringPrivate Sub Command1_Click()
ss Val(Text1) '模拟mscomm一次传送一字节
End SubSub ss(a As Byte) '模拟OnComm
Static num As Integer
Static start As String
If num <= 1 Then
start = start + Format(Hex(a), "00")
Text2 = start '调试用,此句可删除
num = num + 1
ElseIf num = 2 And start = "1002" Then
iStr = iStr + Format(Hex(a), "00")
Text3 = iStr '调试用,此句可删除
If InStr(iStr, "1003") Then
iStr = Left(iStr, Len(iStr) - 4)
Text2 = Text2 + "1003" '调试用,此句可删除
Text3 = iStr '调试用,此句可删除
num = 0
start = ""
MsgBox iStr '这里调用数据存盘程序。istr不包含字头(1002)与字尾(1003)
End If
Else
num = 0
start = ""
Text1 = "" '调试用,此句可删除
Text2 = "" '调试用,此句可删除
End If
End Sub
但是有的时候就会在数据的后边多了一个1
100255F90806272AA7DB1123452FFA10031'数据存储处理过程
Sub subSaveString()
Dim strP As String
Dim intStart As String
Dim intEnd As String
intStart = InStr(1, strData, "1002") '查找起始字符串的位置
intEnd = InStr(1, strData, "1003") '查找结束字符串的位置
If intStart > 0 And intEnd > 0 And intEnd > intStart Then
strP = Mid(strData, intStart, intEnd - intStart + 5) 'strP就是你要保存的一条数据,起始是1002 结束是 1003
Replace strData, strP, "", intStart, 1, vbTextCompare '将strdata中的strP去掉
End If
End Sub