vb mscomm 接收不到数据

tornado_dai 2013-07-28 11:18:26

Private Sub Form_Load()
Dim i As Integer
If MSComm1.PortOpen = True Then
MSComm1.PortOpen = False
End If '先判断串口是否关闭,如果打开则关闭
MSComm1.CommPort = 5 'COM端口
MSComm1.Settings = "115200,n,8,1"
MSComm1.InputLen = 0 '读取接收缓冲区的所有字符
MSComm1.InputMode = comInputModeBinary '采用二进制传输
MSComm1.InBufferSize = 1024 '接受缓冲区为1024字节
MSComm1.OutBufferSize = 2048 '发送缓冲区位2048字节
MSComm1.InBufferCount = 0 '清空接受缓冲区
MSComm1.OutBufferCount = 0 '清空传输缓冲区
MSComm1.SThreshold = 0 '禁止发送事件
MSComm1.RThreshold = 1 '产生MSComm事件
Command2.Enabled = False '初始化时设置“关闭”按钮不可用
End Sub

Private Sub MSComm1_OnComm()

Dim inbyte() As Byte '存储接收串口数据
Dim buffer As String '存储处理后的串口数据
Dim lenbuffer As Integer '存储处理后的串口数据长度
Dim i As Integer '设置循环变量

Select Case MSComm1.CommEvent
Case comEvReceive
inbyte = MSComm1.Input
For i = LBound(inbyte) To UBound(inbyte)

If Len(Hex(inbyte(i))) = 1 Then
buffer = buffer + "0" + Hex(inbyte(i)) + Chr(32)
Else
buffer = buffer + Hex(inbyte(i)) + Chr(32)
End If

lenbuffer = Len(Replace(Trim(buffer), " ", ""))

Select Case lenbuffer
Case Is = 14
If CByte("&H" & (Mid(Replace(buffer, " ", ""), 1, 2))) = &HAA _
And "&H" & (Mid(Replace(buffer, " ", ""), 14 - 4 + 1, 2)) = &H42 _
And "&H" & (Mid(Replace(buffer, " ", ""), 14 - 2 + 1, 2)) = &H42 Then
If "&H" & (Mid(Replace(buffer, " ", ""), 14 - 12 + 1, 2)) = &H55 Then

If "&H" & (Mid(Replace(buffer, " ", ""), 14 - 10 + 1, 2)) = &H43 _
And "&H" & (Mid(Replace(buffer, " ", ""), 14 - 8 + 1, 2)) = &H47 _
And "&H" & (Mid(Replace(buffer, " ", ""), 14 - 6 + 1, 2)) = &H8A Then
Text2.Text = "测试通过"
End If

End If
End If

case is = 18
....... 省略

End Select
Next i
End Sub


想问下,为什么上位机接收不到数据???
...全文
655 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
tornado_dai 2013-08-06
  • 打赏
  • 举报
回复
引用 23 楼 zhao4zhong1 的回复:
推荐使用portmon软件辅助串口通讯调试。
不错,好用
赵4老师 2013-08-02
  • 打赏
  • 举报
回复
推荐使用portmon软件辅助串口通讯调试。
tornado_dai 2013-08-01
  • 打赏
  • 举报
回复
引用 21 楼 myjian 的回复:
我一般的做法是,收到数据先检查长度,再与已存储的长度相加,看看是不是已经达到我要求的长度. 如果达到或超过,就进入处理流程. 处理流程里会找到有效数据的头与尾,并清空尾部数据以前的数据,保证未处理的数据是在缓冲区开头. 如此周而复始.
多谢分享
嗷嗷叫的老马 2013-07-31
  • 打赏
  • 举报
回复
我一般的做法是,收到数据先检查长度,再与已存储的长度相加,看看是不是已经达到我要求的长度. 如果达到或超过,就进入处理流程. 处理流程里会找到有效数据的头与尾,并清空尾部数据以前的数据,保证未处理的数据是在缓冲区开头. 如此周而复始.
zdingyun 2013-07-30
  • 打赏
  • 举报
回复
引用 19 楼 zdingyun 的回复:
接收数据是固定字节长度的话,由于可以设置MSComm1.RThreshold为固定字节长度,buffer定义于为过程变量,接收代码照你原先的是没问题的。 而接收不定长的字节,只能设置MSComm1.RThreshold = 1,而COM口硬件原因,大于8字节以上的数据到达COM口会多次触发OnComm事件,buffer定义于为过程变量会导致接收字节不完整有丢数据现象,所以buffer定义于为全局变量。
大于8字节以上是我这儿COM口硬件测试结果,LZ接收”aa 55 43 47 8a 42 42“7字节有丢字节现象,我这儿没遇见过。或许LZ的环境电磁干扰或上下位机波特率差异等因素导致。
zdingyun 2013-07-30
  • 打赏
  • 举报
回复
接收数据是固定字节长度的话,由于可以设置MSComm1.RThreshold为固定字节长度,buffer定义于为过程变量,接收代码照你原先的是没问题的。 而接收不定长的字节,只能设置MSComm1.RThreshold = 1,而COM口硬件原因,大于8字节以上的数据到达COM口会多次触发OnComm事件,buffer定义于为过程变量会导致接收字节不完整有丢数据现象,所以buffer定义于为全局变量。
tornado_dai 2013-07-30
  • 打赏
  • 举报
回复
多谢zdingyun , 将buffer定于为全局变量的方法可以接收到完整数据,接收到下一组数据时,之前的数据还在,需做一下清空处理; 可不可以讲解一下我之前接收数据丢失以及用这钟方法的缘由?
tornado_dai 2013-07-29
  • 打赏
  • 举报
回复
Private Sub Command1_Click() '打开串口 On Error GoTo Err MSComm1.CommPort = CInt(Mid(C1.Text, 4, 1)) '选择端口号 If MSComm1.PortOpen = False Then MSComm1.PortOpen = True Text1.Text = "串口打开" Command1.Enabled = False '设置“打开”按钮变灰 Command2.Enabled = True Exit Sub End If Err: MsgBox "端口被占用或无", vbCritical, "错误警告" End Sub 串口打开代码如上,上面的按你说的改过试了,还是不能接收到数据。。。
zdingyun 2013-07-29
  • 打赏
  • 举报
回复
从代码看COM口没打开。 OnComm事件代码缺 End Select Next i位置错误

Private Sub Form_Load()
    Dim i As Integer
    If MSComm1.PortOpen = True Then
        MSComm1.PortOpen = False
    End If
    MSComm1.CommPort = 1
    MSComm1.Settings = "115200,n,8,1"
    MSComm1.InputLen = 0
    MSComm1.InputMode = comInputModeBinary
    MSComm1.InBufferSize = 1024
    MSComm1.OutBufferSize = 2048
    MSComm1.InBufferCount = 0
    MSComm1.OutBufferCount = 0
    MSComm1.SThreshold = 0
    MSComm1.RThreshold = 1
    MSComm1.PortOpen = True '打开COM口
    Command2.Enabled = False
End Sub

Private Sub MSComm1_OnComm()
    Dim inbyte() As Byte
    Dim buffer As String
    Dim lenbuffer As Integer
    Dim i As Integer
    Select Case MSComm1.CommEvent
        Case comEvReceive
            inbyte = MSComm1.Input
            For i = LBound(inbyte) To UBound(inbyte)
                If Len(Hex(inbyte(i))) = 1 Then
                    buffer = buffer + "0" + Hex(inbyte(i)) + Chr(32)
                Else
                    buffer = buffer + Hex(inbyte(i)) + Chr(32)
                End If
            Next i
            
            lenbuffer = Len(Replace(Trim(buffer), " ", ""))
            Select Case lenbuffer
                Case Is = 14
                    If CByte("&H" & (Mid(Replace(buffer, " ", ""), 1, 2))) = &HAA _
                       And "&H" & (Mid(Replace(buffer, " ", ""), 14 - 4 + 1, 2)) = &H42 _
                       And "&H" & (Mid(Replace(buffer, " ", ""), 14 - 2 + 1, 2)) = &H42 Then
                           If "&H" & (Mid(Replace(buffer, " ", ""), 14 - 12 + 1, 2)) = &H55 Then
                               If "&H" & (Mid(Replace(buffer, " ", ""), 14 - 10 + 1, 2)) = &H43 _
                                    And "&H" & (Mid(Replace(buffer, " ", ""), 14 - 8 + 1, 2)) = &H47 _
                                    And "&H" & (Mid(Replace(buffer, " ", ""), 14 - 6 + 1, 2)) = &H8A Then
                                    Text2.Text = "????"
                               End If
                           End If
                    End If
             End Select
    End Select
End Sub
zdingyun 2013-07-29
  • 打赏
  • 举报
回复
将buffer定义为窗体变量
Option Explicit
    Dim buffer As String
    
Private Sub Form_Load()
    Dim i As Integer
    If MSComm1.PortOpen = True Then
        MSComm1.PortOpen = False
    End If
    MSComm1.CommPort = 1
    MSComm1.Settings = "115200,n,8,1"
    MSComm1.InputLen = 0
    MSComm1.InputMode = comInputModeBinary
    MSComm1.InBufferSize = 1024
    MSComm1.OutBufferSize = 2048
    MSComm1.InBufferCount = 0
    MSComm1.OutBufferCount = 0
    MSComm1.SThreshold = 0
    MSComm1.RThreshold = 1
    MSComm1.PortOpen = True '打开COM口
    Command2.Enabled = False
End Sub
 
Private Sub MSComm1_OnComm()
    Dim inbyte() As Byte
    Dim lenbuffer As Integer
    Dim i As Integer
    Select Case MSComm1.CommEvent
        Case comEvReceive
            inbyte = MSComm1.Input
            For i = LBound(inbyte) To UBound(inbyte)
                If Len(Hex(inbyte(i))) = 1 Then
                    buffer = buffer + "0" + Hex(inbyte(i)) + Chr(32)
                Else
                    buffer = buffer + Hex(inbyte(i)) + Chr(32)
                End If
            Next i
            Text1 = buffer
            lenbuffer = Len(Replace(Trim(buffer), " ", ""))
            Select Case lenbuffer
                Case Is = 14
                    If CByte("&H" & (Mid(Replace(buffer, " ", ""), 1, 2))) = &HAA _
                       And "&H" & (Mid(Replace(buffer, " ", ""), 14 - 4 + 1, 2)) = &H42 _
                       And "&H" & (Mid(Replace(buffer, " ", ""), 14 - 2 + 1, 2)) = &H42 Then
                           If "&H" & (Mid(Replace(buffer, " ", ""), 14 - 12 + 1, 2)) = &H55 Then
                               If "&H" & (Mid(Replace(buffer, " ", ""), 14 - 10 + 1, 2)) = &H43 _
                                    And "&H" & (Mid(Replace(buffer, " ", ""), 14 - 8 + 1, 2)) = &H47 _
                                    And "&H" & (Mid(Replace(buffer, " ", ""), 14 - 6 + 1, 2)) = &H8A Then
                                    Text2.Text = "????"
                               End If
                           End If
                    End If
             End Select
    End Select
End Sub
tornado_dai 2013-07-29
  • 打赏
  • 举报
回复
因为上位机需要处理的数据只有7字节和20字节两种情况,我修改成
 
Select Case MSComm1.CommEvent         
Case comEvReceive        
 '***********************************         
Do While MSComm1.InBufferCount <> 7 And MSComm1.InBufferCount <> 20            
   DoEvents            
    Loop         
inbyte = MSComm1.Input         
'***********************************
接收的数据就是完整的了,还是不解原来的为何数据丢失。。。如上修改后如果期间发送了不是7字节和20字节的数据,发送字节小于7,则是缓存数据到了7字节或20字节,才能收到数据,若是发送了一个2字节内容,再发送那个20字节的回复数据,就不能正确响应case事件了,显示收不到数据,因为加上缓存数据的2字节,此时为22字节,就直接不能处理了
tornado_dai 2013-07-29
  • 打赏
  • 举报
回复
因为上位机需要处理的数据只有7字节和20字节两种情况,我修改成[code=vb][/ Select Case MSComm1.CommEvent Case comEvReceive '*********************************** Do While MSComm1.InBufferCount <> 7 And MSComm1.InBufferCount <> 20 DoEvents Loop inbyte = MSComm1.Input '***********************************]接收的数据就是完整的了,还是不解原来的为何数据丢失。。。如上修改后如果期间发送了不是7字节和20字节的数据,发送字节小于7,则是缓存数据到了7字节或20字节,才能收到数据,若是发送了一个2字节内容,再发送那个20字节的回复数据,就不能正确响应case事件了,显示收不到数据,因为加上缓存数据的2字节,此时为22字节,就直接不能处理了
tornado_dai 2013-07-29
  • 打赏
  • 举报
回复
把[code=vb][/ For i = LBound(inbyte) To UBound(inbyte) If Len(Hex(inbyte(i))) = 1 Then buffer = buffer + "0" + Hex(inbyte(i)) + Chr(32) Else buffer = buffer + Hex(inbyte(i)) + Chr(32) End If Next i] 改为[code=vb][/buffer = buffer + Hex(inbyte(i)) + Chr(32)] 还是丢失数据,发送aa 55 43 47 8a 42 42 只收到55 43 47 8a 42 42
yachong 2013-07-29
  • 打赏
  • 举报
回复
前几年有一次写一个小串口程序放到客户某机器上面接收一小段数据,也是楼主这个现象 后来丢掉MSCOMM,网上找了一段api读写串口的代码就没问题了。再后来也没再研究这个事。
of123 2013-07-29
  • 打赏
  • 举报
回复
应该是上位机代码屏蔽掉了一些数据。 如果你要调试接收是否正常,把你那些判断条件什么的都注释掉,把接收到的所有数据都显示出来。
tornado_dai 2013-07-29
  • 打赏
  • 举报
回复
引用 9 楼 myjian 的回复:
把收到的数据全部输出来显示,再与发送的数据相比较,看看到底是完全不对,还是顺序不对,还是有缺失,再进行下一步排查.
显示出来看了,数据有缺失, 发送aa 43 47 8A 42 42的时候,只显示43 47 8A 42 42;发送aa 55 89 00 31 32 30 35 33 36 32 31 33 36 37 39 0f 05 42 42的时候,只显示89 00 31 32 30 35 33 36 32 31 33 36 37 39 0f 05 42 42,是哪里出问题了?
嗷嗷叫的老马 2013-07-29
  • 打赏
  • 举报
回复
另外,代码写在[code=vb]这里[/code <---此处还有一个]
嗷嗷叫的老马 2013-07-29
  • 打赏
  • 举报
回复
把收到的数据全部输出来显示,再与发送的数据相比较,看看到底是完全不对,还是顺序不对,还是有缺失,再进行下一步排查.
tornado_dai 2013-07-29
  • 打赏
  • 举报
回复
引用 7 楼 zdingyun 的回复:
[quote=引用 6 楼 daiyuankai 的回复:] 不好意思,我表述有误,情况是收到数据不对,上位机不能正确响应,下位机每次发送的数据和上位机收到的数据不一致
请降低波特率调试代码,或许USB转RS232线质量有问题导致。[/quote] 确定USB转串口线没有问题,波特率调低试过,也是收到的数据不对,还有其他原因吗?是不是要判断一下数据有没有接收完成还是怎样的
zdingyun 2013-07-29
  • 打赏
  • 举报
回复
引用 6 楼 daiyuankai 的回复:
不好意思,我表述有误,情况是收到数据不对,上位机不能正确响应,下位机每次发送的数据和上位机收到的数据不一致
请降低波特率调试代码,或许USB转RS232线质量有问题导致。
加载更多回复(4)
随着元宇宙概念兴起与虚拟数字人技术快速发展,虚拟主播、在线教育虚拟助教、元宇宙社交等应用场景对实时动作表情驱动系统提出更高需求。当前主流动作捕捉方案多依赖专业光学动捕设备或深度相机,设备成本高昂、部署复杂,难以在普通用户场景普及。本研究设计并实现一套基于普通单目摄像头的虚拟数字人实时动作表情驱动系统,旨在降低数字人内容生产门槛。系统采用Unity作为主开发引擎,结合Blender进行数字人模型构建与BlendShape表情系统制作,使用MediaPipe框架实现人脸关键点检测与人体姿态估计,通过C#脚本完成实时数据处理与渲染控制。系统包含五个关键模块:人脸关键点检测(MediaPipe Face Mesh提取468个关键点)、人体姿态估计(MediaPipe Pose识别33个骨骼关键点)、表情迁移映射、动作平滑优化(卡尔曼滤波与贝塞尔曲线插值消除抖动)、实时渲染(60fps流畅渲染,支持直播推流与视频录制)。实验结果表明,系统在普通笔记本上可实现60fps实时驱动,人脸关键点检测准确率达98.7%,人体姿态估计平均误差小于5像素,表情迁移相似度达92.3%。 【课程报告内容】 摘要 第1章 绪论 第2章 相关技术与理论基础 第3章 系统架构设计 第4章 关键模块设计与实现 第5章 实验与结果分析 第6章 总结与展望 参考文献
内容概要:本文提出了一种基于蒙特卡洛模拟与拉格朗日松弛法的分散式优化策略,用于解决电动汽车充电站在分时电价机制下的有序充电调度问题。通过蒙特卡洛方法模拟电动汽车充电行为的随机性,生成多样化负荷场景,构建以降低电网负荷波动和用户充电成本为目标的优化模型;采用拉格朗日松弛法对耦合约束进行解耦,实现分布式求解,在保障用户隐私的同时提升计算效率。文中设计了详细的仿真场景,系统分析了该调度策略对电网负荷特性和用户经济性的影响,验证了所提方法在实际应用中的有效性与可行性。; 适合人群:具备电力系统运行、优化算法理论及Matlab编程能力的研究生、科研人员以及从事智能电网与电动汽车相关领域的工程技术人员。; 使用场景及目标:①应用于城市规模化充电站集群的有序充电管理,实现电网“削峰填谷”;②为电力公司制定科学合理的分时电价政策提供量化分析工具;③支撑智能电网中需求侧资源的分布式协同优化调度研究与系统设计。; 阅读建议:建议结合提供的Matlab代码深入理解算法实现流程,重点掌握蒙特卡洛场景生成机制与拉格朗日松弛迭代求解过程,可通过调整参数设置复现不同工况下的仿真结果,以深化对分散式优化机制与调度效果之间关系的理解。
内容概要:本文研究了基于阶跃响应的V-Tiger自动增益调整PID控制器优化方法,并提供了完整的Matlab代码实现。通过深入分析PID控制的核心性能指标与V-Tiger控制器的动态特性,提出了一种融合阶跃响应特征提取与多目标协同优化的自动整定方案,设计了具备自适应迭代校正能力的优化机制,有效提升了控制系统的响应速度、稳定性和抗干扰能力。文中系统阐述了整定原理、算法架构设计及性能验证流程,通过仿真实验充分验证了该方法在复杂工业控制场景下实现高精度参数自整定的可行性与优越性,为智能PID控制提供了可复现、可拓展的技术路径。; 适合人群:具备自动控制理论基础和Matlab编程能力,从事控制工程、自动化、电气工程等领域研究的研发人员及高校研究生。; 使用场景及目标:①应用于需要高精度PID参数整定的工业控制系统中,如电机驱动、温度控制、电力电子变换器等;②为科研人员提供一种可复现、可扩展的智能PID整定方法,用于提升系统动态性能与鲁棒性;③作为教学案例帮助学生理解PID整定原理与现代优化算法的融合应用。; 阅读建议:建议读者结合文中的Matlab代码逐模块运行与调试,重点关注阶跃响应特征提取与增益优化策略的实现逻辑,同时可尝试将其应用于实际控制系统中进行对比验证,以深化对自动整定机制的理解。

1,453

社区成员

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

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