VBGood网站全文搜索 Google

搜索VBGood全站网页(全文搜索)

VB爱好者乐园(VBGood)

 找回密码
 立即注册
搜索
查看: 3610|回复: 10

[经验技巧] MSComm控件接收数据乱码问题

[复制链接]
 楼主| 发表于 2010-12-2 17:45:26 | 显示全部楼层 |阅读模式
本帖最后由 zz0612 于 2010-12-2 20:38 编辑


Option Explicit
Dim inbyte1() As Byte   

Dim inf As String

---------------------------------------------------
Private Sub Form_Load()
MSComm1.CommPort = 1
MSComm1.Settings = "9600,n,8,1"
MSComm1.RThreshold = 9
MSComm1.InBufferSize = 512
MSComm1.InputMode = comInputModeBinary
MSComm1.InputLen =0
If MSComm1.PortOpen = False Then
   MSComm1.PortOpen = True
End If
Timer1.Interval = 1000
Timer1.Enabled = True
End Sub
---------------------------------------------------------
Private Sub MSComm1_OnComm()
If MSComm1.PortOpen = False Then
   MSComm1.PortOpen = True
End If
Select Case MSComm1.CommEvent
Case comEvReceive
inf = MSComm1.Input
inbyte1() = Mid(inf, 1, 9)
If inbyte1 (0) = "A" Then
Text1.Text = Chr(inbyte1(0))& Chr(inbyte1(1)) & Chr(inbyte1(2)) & Chr(inbyte1(3)) & Chr(inbyte1(4))&Chr(inbyte1(5)) & Chr(inbyte1(6)) & Chr(inbyte1(7)) & Chr(inbyte1(8))
Else
Text1.Text =""
End If
End Select
End Sub

---------------------------------------------------------
Private Sub Timer1_Timer()     '  触发信号
Dim send_byte(0 To 2) As Byte
send_byte(0) = 122
send_byte(1) = 99
send_byte(2) = 90
If MSComm1.PortOpen = True Then
MSComm1.Output = send_byte
End If
End Sub
-------------------------------------------

功能是接收从PLC发过来的ASCII码,标示码是A,当判断inbyte1 (0) = "A" 时,把后面的数据转换成ASCII码显示出来。数据PLC一直发送,接收端收到的数据会丢失和顺序错位。  
请帮忙分析一下怎么解决这个问题。谢谢!
发表于 2010-12-2 20:03:00 | 显示全部楼层
本帖最后由 zdingyun 于 2010-12-2 21:08 编辑

LZ应该详细描述你的PLC的通信协议.

  1. Private Sub Form_Load()
  2.     MSComm1.CommPort = 1
  3.     MSComm1.Settings = "9600,n,8,1"
  4.     MSComm1.RThreshold = 9
  5.     MSComm1.InBufferSize = 512
  6.     MSComm1.InputMode = comInputModeBinary
  7.     MSComm1.InputLen = 0
  8.     If MSComm1.PortOpen = False Then
  9.         MSComm1.PortOpen = True
  10.     End If
  11.     Timer1.Interval = 1000
  12.     Timer1.Enabled = True
  13. End Sub
  14. Private Sub MSComm1_OnComm()
  15.     Dim inbyte1() As Byte
  16.     Select Case MSComm1.CommEvent
  17.         Case comEvReceive
  18.             If MSComm1.PortOpen = False Then
  19.                MSComm1.PortOpen = True
  20.             End If
  21.             inbyte1 = MSComm1.Input
  22.             If inbyte1(0) = 65 Then
  23.                 Text1.Text = Chr(inbyte1(0)) & Chr(inbyte1(1)) & Chr(inbyte1(2)) & Chr(inbyte1(3)) & Chr(inbyte1(4)) & Chr(inbyte1(5)) & Chr(inbyte1(6)) & Chr(inbyte1(7)) & Chr(inbyte1(8))
  24.             Else
  25.                 Text1.Text = ""
  26.             End If
  27.     End Select
  28. End Sub
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-12-2 20:37:05 | 显示全部楼层
PLC通讯是西门子自由口协议,  波特率等相关设置与  9600,n,8,1 是相同的   感觉设置上应该没有问题

PLC是在检测到控制字符后延时发送“A0000,123”对应的ASCII码,发送完毕后等待PC再次发送控制字符这样循环进行

PC发送给PLC的时候PLC能够准确接收

我主要是觉得PC这边程序可能写的有些问题,才导致PC接受出现故障

因为对控件的使用还不是特别熟悉
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-12-2 20:55:28 | 显示全部楼层
Chr(inbyte1(0))& Chr(inbyte1(1)) & Chr(inbyte1(2)) & Chr(inbyte1(3)) & Chr(inbyte1(4))&Chr(inbyte1(5)) & Chr(inbyte1(6)) & Chr(inbyte1(7)) & Chr(inbyte1(8))
对应的是“A0000,123”
但是收到的数据  效果比较差  主要是顺序有些混乱还有丢失一两个的情况  

有点挣扎了

希望会的人帮看看

觉得程序很短 另外也思路也不是很混乱~

谢谢!
回复 支持 反对

使用道具 举报

发表于 2010-12-2 20:58:23 | 显示全部楼层
本帖最后由 zdingyun 于 2010-12-2 21:11 编辑

如果PLC返回的数据是诸如:"A0000,123",那完全可按文本方式接收,无须从字节转换为ASCII字符.

MSComm1.InputMode = comInputModeText


  1. Option Explicit
  2. Private Sub Form_Load()
  3.     MSComm1.CommPort = 1
  4.     MSComm1.Settings = "9600,n,8,1"
  5.     MSComm1.RThreshold = 9
  6.     MSComm1.InBufferSize = 512
  7.     MSComm1.InputMode = comInputModeText
  8.     MSComm1.InputLen = 0
  9.     If MSComm1.PortOpen = False Then
  10.         MSComm1.PortOpen = True
  11.     End If
  12.     Timer1.Interval = 1000
  13.     Timer1.Enabled = True
  14. End Sub
  15. Private Sub MSComm1_OnComm()
  16.     Dim strSj As String
  17.     Select Case MSComm1.CommEvent
  18.         Case comEvReceive
  19.             If MSComm1.PortOpen = False Then
  20.                MSComm1.PortOpen = True
  21.             End If
  22.             strSj = MSComm1.Input
  23.             If Mid(strSj, 1, 1) = "A" And Len(strSj) = 9 Then
  24.                 Text1.Text = strSj
  25.             Else
  26.                 Text1.Text = ""
  27.             End If
  28.     End Select
  29. End Sub

复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-12-2 21:04:25 | 显示全部楼层
本帖最后由 zz0612 于 2010-12-2 21:05 编辑

设置过使用  MSComm1.InputMode = comInputModeText  但是好像没有太大改善

另外PLC是使用XMT指令  (XMT  VB9)  ITA转换后发送过来的就是ASCII码 分别存储在VB11-VB18里面对用0/0/0/0/,/1/2/3对用的ASCII码  XMT指令  从PORT口发送出去  发送的字符数是9 (包括一个标志为A在VB10中)     其实这个程序的功能就是把PLC采集的模拟量转换后发送给PC显示,  我主要是怀疑VB代码上编写有问题

第一次使用     主要是没有信心
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-12-2 21:11:23 | 显示全部楼层
“  If MSComm1.PortOpen = False Then

               MSComm1.PortOpen = True

            End If”


是不是说接收事件触发后可能引起COM口关闭


我想版主说的还是有些道理的

我改一改试验试验
回复 支持 反对

使用道具 举报

发表于 2010-12-2 21:14:41 | 显示全部楼层
见5楼的代码.
串口属于字符设备.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-12-2 22:19:02 | 显示全部楼层
本帖最后由 zz0612 于 2010-12-2 22:20 编辑

非常感谢帮主~

我是初学VB  很多都挺肤浅的

谢谢 指导  谢谢指点


我会好好研究研究的

======================
对于串口是字符设备 我还不是太理解 不过我会好好体会 体会的
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-12-3 11:52:37 | 显示全部楼层
效果很好 谢谢版主帮忙

OY
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

文字版|手机版|小黑屋|VBGood  

GMT+8, 2022-6-29 21:50

VB爱好者乐园(VBGood)
快速回复 返回顶部 返回列表