VB读取电子秤数据问题

pittst 2009-12-26 10:31:43
电子秤是 湘平 ES-300MC
数据是自动上报的,用超级终端获取到的数据如下,用串口调试助手接收到的数据也是这样
=================
U.W. 0lb
PCS: 0 pcs
ST,GS 0.000lb
U.W. 0lb
PCS: 0 pcs
ST,GS 0.000lb
U.W. 0lb
PCS: 0 pcs
ST,GS 0.000lb
U.W. 0lb
PCS: 0 pcs
ST,GS 0.000lb
=================

网上找到的资料http://topic.csdn.net/t/20060213/11/4552895.html 3楼
试着修改它,但是还是不行...老是报错,而且根本就没显示出任何信息...
下面是我修改后的
我不是学VB的...现在做的一个小项目需要获取电子秤数据,虽然已经用JAVA解决了,但是还需要安装JRE,太麻烦了,所以想用VB写,然后发布成ActiveX插件,但现在连在VB6里显示都有问题了...T_T
==================================================================
Private Sub Command1_Click()
ClearText
With MSComm1
.InputMode = comInputModeText
.InBufferCount = 0
If Not .PortOpen Then
.PortOpen = True
End If
End With
End Sub

Private Sub Form_Load()
ClearText
With MSComm1
.CommPort = 1
.Settings = "9600,N,8,1"
.InBufferSize = 40
.InputLen = 1
End With
End Sub
Private Sub ClearText()
Text1.Text = ""
End Sub

Private Sub MSComm1_OnComm()
Timer1_Timer
ClearText
With MSComm1
If .CommEvent = comEvReceive Then
Text1.Text = MSComm1.Input '我现在只想看到电子秤的数据能在文本框里显示出来,就内牛满面了...弄这个弄了3天了啊...
.RThreshold = 1
Else
.PortOpen = False
End If
End With
End Sub

Private Sub Timer1_Timer()
Dim bDT As Boolean
Dim sPrevious As Single, sLast As Single
bDT = True
sPrevious = Timer
Do While bDT
If Timer - sPrevious >= 0.3 Then bDT = False
Loop
bDT = True
End Sub
==================================================================
厂商的说明书中提的通讯协议
========================================================================
通讯接口采用RS232C,所有数据均为ASCII码,波特率9600bps,8数据位,无校验
┏━━━━━━━━━━━━━━┓
┃.A┃,┃B┃-┃C┃,┃D┃CR┃CF┃
┗━━━━━━━━━━━━━━┛
A:2位,ST表示数据稳定,US表示数据不稳定
B:2位,NT表示净重,US表示毛重
C:7位,带小数点的重量
D:2位,单位
┏━━━━━━━━━━━━━━━┓
┃U┃.┃W┃.┃□┃A, ┃B┃CR┃CF┃
┗━━━━━━━━━━━━━━━┛
A:7位,带小数点单重
B:2位,单位
┏━━━━━━━━━━━━━━━━━━━━┓
┃P┃.C┃S┃.┃A┃B ,┃□┃P┃C┃S┃CR┃LF┃
┗━━━━━━━━━━━━━━━━━━━━┛
A:正数 □ 负数-
B:6位的数量
========================================================================
想要的数据也就在第一段里,JAVA中通过判断字符串中出现“ST”的位置和单位的位置来截取字符串
但VB写实在写不出来...看了2、3天VB,修改了别人的源码也还是一头雾水...
...全文
790 33 打赏 收藏 转发到动态 举报
写回复
用AI写文章
33 条回复
切换为时间正序
请发表友善的回复…
发表回复
少控科技 2010-11-18
  • 打赏
  • 举报
回复
对外设进行程序的基本过程。
0、对设备的了解。
1、确定接收时的数据结构关系。
2、确定数据被接收的条件
3、确定数据接收结束的条件。
4、分析数据结构和有用数据位置以及变化关系。
5、写程序。开端口。收数据。
6、调试,十次以上,一次十组数据测试。
7、完工
cbm6666 2009-12-27
  • 打赏
  • 举报
回复
电子秤我一向採用文本接收,但你这不定长度, 我还是用二进制接收, 你先试看

如不正确, 你可以暂时先加一个Listbox 将Rcvdata全部Additem 然后截图贴上来

三个数据我用 Label1 Label2 Label3


Option Explicit
Dim i&, j&, RcvData$
Dim Rx_buff() As Byte, Constop As Boolean
Private Sub Form_Load()
Call InitRs232
End Sub

Private Static Sub MSComm1_OnComm()
On Error Resume Next
If MSComm1.CommEvent = comEvReceive Then
If MSComm1.InBufferCount > 0 Then
Rx_buff = MSComm1.Input
Constop = False
For i = 0 To UBound(Rx_buff)
If Rx_buff(i) = 10 Then '0D0A为终止符 chr(13)+chr(10)
If Len(RcvData) > 5 Then Constop = True: Exit For
If Constop = False Then RcvData = "": MSComm1.PortOpen = False: MSComm1.PortOpen = True
Else
RcvData = RcvData & Chr(Val(Rx_buff(i)))
End If
Next i
If Constop Then
j = InStr(RcvData, "ST")
If j > 0 Then
Label1.Caption = CStr(Val(Mid(RcvData, 6)))
Else
j = InStr(RcvData, "U.")
If j > 0 Then
Label2.Caption = CStr(Val(Mid(RcvData, 5)))
Else
j = InStr(RcvData, "PC")
If j > 0 Then Label3.Caption = CStr(Val(Mid(RcvData, 5)))
End If
End If
If j > 0 Then RcvData = ""
End If
End If
End If
End Sub

Sub InitRs232()
On Error Resume Next
MSComm1.CommPort = 1
If MSComm1.PortOpen Then MSComm1.PortOpen = False
'*********** 端口参数
With MSComm1
.Settings = "9600,n,8,1"
.InputLen = 0
.InBufferSize = 1
.RThreshold = 1
.InputMode = comInputModeBinary
End With
If Not MSComm1.PortOpen Then MSComm1.PortOpen = True
MSComm1.InBufferCount = 0
End Sub


pittst 2009-12-27
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 cbm666 的回复:]
先给你一个思路

如果统一都是17位的话 则 RThreshold = 17 即可搞定(你可以试一下)

17 16 17 则你只能 RThreshold = 1 判断CHR(13)+CHR(10) 为界限分割

再判断前3码是 ST, 或U.W 或PCS 来决定这三笔该给那一项 要注意 大小写


[/Quote]
刚开始还不大懂你19楼说的...
实际写代码的时候才想到...如果统一17位的话,RThreshold = 17就能保证一次接收17个字节,这样只需要每次都判断前2码或前3码是不是CHR(83)+CHR(84)或者是CHR(85)+CHR(83)就得了...
现在这样的话,如果RThreshold = 17的话,即使第一次接收可以正常的得到重量数据
'53 54 2C 47 53 20 20 20 30 2E 30 30 30 6C 62 0D 0A = ST,GS 0.000lb
'55 2E 57 2E 20 20 20 20 20 20 20 30 6C 62 0D 0A 50 = U.W. 0lbP
'43 53 3A 20 20 20 20 20 20 30 20 70 63 73 0D 0A 53 = CS: 0 pcsS
但第二次就会变成
'54 2C 47 53 20 20 20 30 2E 30 30 30 6C 62 0D 0A 55 = T,GS 0.000lbU
'2E 57 2E 20 20 20 20 20 20 20 30 6C 62 0D 0A 50 43 = .W. 0lbPC
'53 3A 20 20 20 20 20 20 30 20 70 63 73 0D 0A 53 54 = S: 0 pcsST
第二次接收再用判断前2码的方法就不行了哦...
这样的话得接收100次才会循环一次... —_—b

我现在想说如果一次性接收多个字节(MSComm1.InBufferSize = 50 (17+16+17))通过判断 CHR(10)+CHR(83)+CHR(84) 和CHR(10)+CHR(85)+CHR(83)的位置来获取数据,这样应该可以吧??
不过......才刚学VB...写的代码好多错误...编译一直出问题...好不容易写好了,结果一运行就卡住了...关掉VB6后...数据没保存.........................
zdingyun 2009-12-27
  • 打赏
  • 举报
回复
Option Explicit
Dim strRec As String
Private Sub Form_Load()
With MSComm1
.CommPort = 1
.Settings = "9600,N,8,1"
.InputLen = 0
.RThreshold = 50
.PortOpen = True
End With
End Sub

Private Sub MSComm1_OnComm()
Select Case MSComm1.CommEvent
Case 2
strRec = strRec & MSComm1.Input
'数据判断代码
If Right(strRec, 2) = vbCr & vbLf And Len(strRec) = 50 Then
'写数据处理代码
Dim strSjfg() As String
strSjfg = Split(strRec, vbCrLf)
Text1 = strSjfg(0)
Text2 = strSjfg(1)
Text3 = strSjfg(2)
strRec = ""
ElseIf Len(strRec) > 50 Then
strRec = ""
End If
End Select
End Sub
cbm6666 2009-12-27
  • 打赏
  • 举报
回复
先给你一个思路

如果统一都是17位的话 则 RThreshold = 17 即可搞定(你可以试一下)

17 16 17 则你只能 RThreshold = 1 判断CHR(13)+CHR(10) 为界限分割

再判断前3码是 ST, 或U.W 或PCS 来决定这三笔该给那一项 要注意 大小写

cbm6666 2009-12-27
  • 打赏
  • 举报
回复
'53 54 2C 47 53 20 20 20 30 2E 30 30 30 6C 62 0D 0A = ST,GS 0.000lb
'55 2E 57 2E 20 20 20 20 20 20 20 30 6C 62 0D 0A = U.W. 0lb
'50 43 53 3A 20 20 20 20 20 20 30 20 70 63 73 0D 0A = PCS: 0 pcs

你这个稍微有点特殊, 因为 总重=17位 单重=16位 数量=17位 这是该秤的原厂设计者的犯错 他少了一位 干我们这一行的人来说, 应该都是要补位统一的, 而且他是同一笔分三笔来发送 这个秤的单片机设计者是个十足的大菜鸟.

太晚了,睡起来理下思路, 再帮你写代码.





pittst 2009-12-27
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 cbm666 的回复:]
你首先要了解你这台秤

有些秤的特性是:

1.没按Print或确认钮不发送数据

2.没输入单重不发送数据

在来就是你在这个程序退出Unload时要加上 If MSComm1.PortOpen Then MSComm1.PortOpen = False

在运行这个程序时, 你必需将超级终端等其它软件关掉退出

再来就是数据抓取的位置问题了

[/Quote]
这电子秤应该不需要点print或是输入单重,因为我这有一个用PowerBuilder 10.5写的程序,是别人的,他用的也是这个秤,一直很正常,而且我用他这个软件的时候也不需要再在电子秤上设置什么,把电子秤连接上,然后设备管理器里的串口参数设置一下就可以了
http://www.brsbox.com/filebox/down/fc/81bbdc63398605a2d72d2f430e4e1c15
这是那PB串口部分的源码(应该是...我是用反编译程序弄出来的...里面都自动添加注释符)
但是PB程序看不大懂...而且也不知道到底是不是这部分源码(搜索9600,也就这部分源码里出现...)

我试着添加
Private Sub Form_Unload(Cancel As Integer)
If MSComm1.PortOpen Then MSComm1.PortOpen = False
End Sub
也还是会出现上面说的那些错误(已经把除浏览器和VB6外的所有程序都关掉了...)
pittst 2009-12-27
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 zdingyun 的回复:]
VB codeOptionExplicitDim strRecAsStringPrivateSub Form_Load()With MSComm1
.CommPort=1
.Settings="9600,N,8,1"
.InputLen=0
.RThreshold=1
.PortOpen=TrueEndWithEnd ?-
[/Quote]
[Quote=引用 24 楼 zdingyun 的回复:]
Code2:
VB codeOptionExplicitDim strRecAsStringPrivateSub Form_Load()With MSComm1
.CommPort=1
.Settings="9600,N,8,1"
.InputLen=0
.RThreshold=1
.PortOpen=TrueEndWithEnd SubPrivateSub MSComm1_OnComm()SelectCase MSComm1.CommEventCase2
strRec= strRec& MSComm1.Input'数据判断代码IfRight(strRec,2)= vbCr& vbLfAndLen(strRec)>=16Then'写数据处理代码IfMid(strRec,1,3)="ST,"AndLen(strRec)=17Then
Text1= strRecElseIfMid(strRec,1,4)="U.W."AndLen(strRec)=16Then
Text2= strRecElseIfMid(strRec,1,4)="PCS:"AndLen(strRec)=17Then
Text3= strRecEndIf
strRec=""ElseIfLen(strRec)>17Then
strRec=""EndIfEndSelectEnd Sub
[/Quote]
第一段代码可以用,就是在Text1.Text里显示"ST,GS 7.480lb
U.W. 0lb
PCS: 0 pcs
"
而Text2数据一直更新(数据和Text1一样,只是一直往后加上去),Text3一直无显示
但是也同样出现运行程序后完全无反应的情况(大概5次会出现2次)
第二段代码不能用...
cbm6666 2009-12-27
  • 打赏
  • 举报
回复
你首先要了解你这台秤

有些秤的特性是:

1.没按Print或确认钮不发送数据

2.没输入单重不发送数据

在来就是你在这个程序退出Unload时要加上 If MSComm1.PortOpen Then MSComm1.PortOpen = False

在运行这个程序时, 你必需将超级终端等其它软件关掉退出

再来就是数据抓取的位置问题了
pittst 2009-12-27
  • 打赏
  • 举报
回复
3、无任何反应,不管是先放东西在电子秤上,还是先运行程序,都是显示默认,大概运行10次,有8次都是这情况

出现这情况的时候,运行超级终端,显示端口被占用
pittst 2009-12-27
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 cbm666 的回复:]
你说的问题应该是数据没有正确的接收到

你把这段代码整个换掉试看 我这边没你的硬件不好测试

Private Sub MSComm1_OnComm()
  On Error Resume Next
  If MSComm1.CommEvent = comEvReceive Then
      If MSComm1.InBufferCount > 0 Then
        Rx_buff = MSComm1.Input
        Constop = False
        For i = 0 To UBound(Rx_buff)
            If Rx_buff(i) = 10 Then '0D0A为终止符
              If Len(RcvData) > 5 Then Constop = True: Exit For
              If Constop = False Then RcvData = "": MSComm1.PortOpen = False: MSComm1.PortOpen = True
            Else
              RcvData = RcvData & Trim(Chr(Val(Rx_buff(i))))
            End If
        Next i
        If Constop Then
            If Left(RcvData, 1) = "S" Or Left(RcvData, 1) = "U" Or Left(RcvData, 1) = "P" Then
              j = InStr(RcvData, "ST")
              If j > 0 Then
                  Label1.Caption = CStr(Val(Mid(RcvData, 6)))
              Else
                  j = InStr(RcvData, "U.")
                  If j > 0 Then
                    Label2.Caption = CStr(Val(Mid(RcvData, 5)))
                  Else
                    j = InStr(RcvData, "PC")
                    If j > 0 Then Label3.Caption = CStr(Val(Mid(RcvData, 5)))
                  End If
              End If
            End If
            RcvData = ""
        End If
      End If
  End If
End Sub
[/Quote]
也还是出现这问题...
1、如果先运行程序,再在电子秤上放东西,完全没有数据显示,即显示默认的Label1,Label2,Label3
2、如果先在电子秤上放东西,再运行程序,会出现
2.1、出现数据,把东西从电子秤上拿走,数据依然保留
2.2、完全不出现数据,显示默认
2.3、显示为0,但此时电子秤上是有东西的
3、无任何反应,不过是点放东西在电子秤上,还是先运行程序,都是显示默认,大概运行10次,有8次都是这情况
cbm6666 2009-12-27
  • 打赏
  • 举报
回复
你说的问题应该是数据没有正确的接收到

你把这段代码整个换掉试看 我这边没你的硬件不好测试

Private Sub MSComm1_OnComm()
On Error Resume Next
If MSComm1.CommEvent = comEvReceive Then
If MSComm1.InBufferCount > 0 Then
Rx_buff = MSComm1.Input
Constop = False
For i = 0 To UBound(Rx_buff)
If Rx_buff(i) = 10 Then '0D0A为终止符
If Len(RcvData) > 5 Then Constop = True: Exit For
If Constop = False Then RcvData = "": MSComm1.PortOpen = False: MSComm1.PortOpen = True
Else
RcvData = RcvData & Trim(Chr(Val(Rx_buff(i))))
End If
Next i
If Constop Then
If Left(RcvData, 1) = "S" Or Left(RcvData, 1) = "U" Or Left(RcvData, 1) = "P" Then
j = InStr(RcvData, "ST")
If j > 0 Then
Label1.Caption = CStr(Val(Mid(RcvData, 6)))
Else
j = InStr(RcvData, "U.")
If j > 0 Then
Label2.Caption = CStr(Val(Mid(RcvData, 5)))
Else
j = InStr(RcvData, "PC")
If j > 0 Then Label3.Caption = CStr(Val(Mid(RcvData, 5)))
End If
End If
End If
RcvData = ""
End If
End If
End If
End Sub
pittst 2009-12-27
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 cbm666 的回复:]
电子秤我一向採用文本接收,但你这不定长度, 我还是用二进制接收, 你先试看

如不正确, 你可以暂时先加一个Listbox 将Rcvdata全部Additem 然后截图贴上来

三个数据我用 Label1 Label2 Label3


Option Explicit
Dim i&, j&, RcvData$
Dim Rx_buff() As Byte, Constop As Boolean
Private Sub Form_Load()
  Call InitRs232
End Sub

Private Static Sub MSComm1_OnComm()
  On Error Resume Next
  If MSComm1.CommEvent = comEvReceive Then
      If MSComm1.InBufferCount > 0 Then
        Rx_buff = MSComm1.Input
        Constop = False
        For i = 0 To UBound(Rx_buff)
            If Rx_buff(i) = 10 Then '0D0A为终止符 chr(13)+chr(10)
              If Len(RcvData) > 5 Then Constop = True: Exit For
              If Constop = False Then RcvData = "": MSComm1.PortOpen = False: MSComm1.PortOpen = True
            Else
              RcvData = RcvData & Chr(Val(Rx_buff(i)))
            End If
        Next i
        If Constop Then
            j = InStr(RcvData, "ST")
            If j > 0 Then
              Label1.Caption = CStr(Val(Mid(RcvData, 6)))
            Else
              j = InStr(RcvData, "U.")
              If j > 0 Then
                  Label2.Caption = CStr(Val(Mid(RcvData, 5)))
              Else
                  j = InStr(RcvData, "PC")
                  If j > 0 Then Label3.Caption = CStr(Val(Mid(RcvData, 5)))
              End If
            End If
            If j > 0 Then RcvData = ""
        End If
      End If
  End If
End Sub

Sub InitRs232()
  On Error Resume Next
  MSComm1.CommPort = 1
  If MSComm1.PortOpen Then MSComm1.PortOpen = False
  '*********** 端口参数
  With MSComm1
      .Settings = "9600,n,8,1"
      .InputLen = 0
      .InBufferSize = 1
      .RThreshold = 1
      .InputMode = comInputModeBinary
  End With
  If Not MSComm1.PortOpen Then MSComm1.PortOpen = True
  MSComm1.InBufferCount = 0
End Sub



[/Quote]
数据为什么会递减到0呢?
比如我放一个10磅的东西在电子秤上,然后运行程序,上面显示10,然后以很快的速度递减到0,然后再不会显示了,不管你放什么东西上去,除非是把程序关掉再运行
而且有时候会显示,有时候则无显示(显示默认的“Label”)
还有就是,有时候只显示小数点后面的数字,比如说10.234磅,它却只显示.234
zdingyun 2009-12-27
  • 打赏
  • 举报
回复
Code2:
Option Explicit
Dim strRec As String
Private Sub Form_Load()
With MSComm1
.CommPort = 1
.Settings = "9600,N,8,1"
.InputLen = 0
.RThreshold = 1
.PortOpen = True
End With
End Sub

Private Sub MSComm1_OnComm()
Select Case MSComm1.CommEvent
Case 2
strRec = strRec & MSComm1.Input
'数据判断代码
If Right(strRec, 2) = vbCr & vbLf And Len(strRec) >= 16 Then
'写数据处理代码
If Mid(strRec, 1, 3) = "ST," And Len(strRec) = 17 Then
Text1 = strRec
ElseIf Mid(strRec, 1, 4) = "U.W." And Len(strRec) = 16 Then
Text2 = strRec
ElseIf Mid(strRec, 1, 4) = "PCS:" And Len(strRec) = 17 Then
Text3 = strRec
End If
strRec = ""
ElseIf Len(strRec) > 17 Then
strRec = ""
End If
End Select
End Sub
pittst 2009-12-27
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 zdingyun 的回复:]
LZ:按文本接收
但你的通信协议描述不太清晰,无法提供接收代码中数据判断的算法.
[/Quote]
这样啊...我以为只要判断ST和单位(kg,lb)的位置就行了...
还有...我14楼出现的那问题是什么原因呢??
pittst 2009-12-27
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 cbm666 的回复:]
你这个是 零件计数秤

电子秤的串口数据接收 可以说几乎全部是字符串的发送 没必要去考虑Binary方式接收 每一笔的长度都是固定的,


你用我的软件运行截图吧,看了图片我就可以替你写正确的代码了.

1.下载 http://cbm666.com/sscom32.rar 并运行

2.设置好端口号(红线匡起来的)

3.将Hex打勾, 看得比较清楚.

4.截图与我的图一样, 发上来




[/Quote]
麻烦你了...
zdingyun 2009-12-27
  • 打赏
  • 举报
回复
Option Explicit
Dim strRec As String
Private Sub Form_Load()
With MSComm1
.CommPort = 1
.Settings = "9600,N,8,1"
.InputLen = 0
.RThreshold = 1
.PortOpen = True
End With
End Sub

Private Sub MSComm1_OnComm()
Select Case MSComm1.CommEvent
Case 2
strRec = strRec & MSComm1.Input
Text2 = strRec
'数据判断代码
If Right(strRec, 2) = vbCr & vbLf And Len(strRec) = 50 Then
Text1.Text = strRec
'写数据处理代码
strRec = ""
ElseIf Len(strRec) > 50 Then
strRec = ""
End If
End Select
End Sub
gzhjic 2009-12-26
  • 打赏
  • 举报
回复
不要用定时器控件,也就是那个小时钟,把Private Sub Timer1_Timer()改成delaytime()等函数名,上面调用的也改成delaytime。
gzhjic 2009-12-26
  • 打赏
  • 举报
回复
.InputMode = comInputModeBinary ''设置数据接收模式为二进制形式 试试。
zdingyun 2009-12-26
  • 打赏
  • 举报
回复
LZ:按文本接收
但你的通信协议描述不太清晰,无法提供接收代码中数据判断的算法.
加载更多回复(13)

1,451

社区成员

发帖
与我相关
我的任务
社区描述
VB 控件
社区管理员
  • 控件
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧