由于每个串口所连接的设备数量和型号相同,所以,我写一个类模块,对单个串口所连接的设备进行通讯和数据处理。然后在主程序中创建10个类实例(其中内部参数不同)。
但是问题是,运行程序的时候,我感觉电脑慢了下来,我不知道实例化10个类的时候,这个主程序是不是还是单线程的,这10个类实例运行的时候还是占用这一个单线程的队列,如果我把这10个类写成10个exe程序,然后再运行的话是不是会好些,这是我的想法。
我觉得慢下来应该是单线程满负荷或者是超负荷运行造成的,各位大侠,请给点意见,绝不吝啬分。
16 个解决方案
#1
VB 是单线程的,感觉满是因为串口本身慢。做成ActiveEXE 的话会好点。
建议使用支持多线程的开发工具。
建议使用支持多线程的开发工具。
#2
http://www.iocomp.com
控件
控件
#3
好多的设备啊,10几个串口,每个串口10个设备,合起来有100多个设备,真牛啊 :)
是单线程运行的
你可以试试将串口封装为 activex.exe,工程属性中设置为多线程运行,并且要使用事件回调技术(如果使用等待,用户端则会在调用返回前被挂起)
是单线程运行的
你可以试试将串口封装为 activex.exe,工程属性中设置为多线程运行,并且要使用事件回调技术(如果使用等待,用户端则会在调用返回前被挂起)
#4
类事件封装成activeexe吗?可否介绍一下实现方法或者例子之类,感激
#5
最根本的问题是,串口通讯的速度与 PC 代码的运行速度相差好多数量级。当你的程序以阻塞方式一一与之通讯时,如果设备很多,当然会感觉到慢。
1 既然是 RS485 总线,发送命令可以考虑广播方式。
2 即使是逐台设备发送命令,也不要立即读取应答。因为这需要等待设备处理完成,累积的时间也很可观。你把通讯分成两轮次,即命令轮次和应答轮次。当你回到第一台设备取应答时,它已经利用了你向其他设备发送命令的时间来进行处理。
3 不要用 VB 中的 MSComm 控件来做 RS485 操作,最好用 VC++ 写 API DLL 调用。因为控件在地址模式和数据模式之间相互切换时,需要先禁用,再切换,再启用,会很慢。两者的差距很大。
4 其实可以只用一个串口,通过 RS485 Hub 级联的方式把设备都连进来。因为 PC 上的串口并不具备自动缓存数据和命令以自行操作的功能,多了也并不快。如果你能用单片机自己搞一种代理接口,让它来自动与设备交互,然后把缓存的数据传给你,那就值得用多个串口。就好比你只管理十几个工头,让他们去管理工人。
1 既然是 RS485 总线,发送命令可以考虑广播方式。
2 即使是逐台设备发送命令,也不要立即读取应答。因为这需要等待设备处理完成,累积的时间也很可观。你把通讯分成两轮次,即命令轮次和应答轮次。当你回到第一台设备取应答时,它已经利用了你向其他设备发送命令的时间来进行处理。
3 不要用 VB 中的 MSComm 控件来做 RS485 操作,最好用 VC++ 写 API DLL 调用。因为控件在地址模式和数据模式之间相互切换时,需要先禁用,再切换,再启用,会很慢。两者的差距很大。
4 其实可以只用一个串口,通过 RS485 Hub 级联的方式把设备都连进来。因为 PC 上的串口并不具备自动缓存数据和命令以自行操作的功能,多了也并不快。如果你能用单片机自己搞一种代理接口,让它来自动与设备交互,然后把缓存的数据传给你,那就值得用多个串口。就好比你只管理十几个工头,让他们去管理工人。
#6
ActiveX EXE 是与主程序运行与不同进程的部件,两者运行基本上互不影响,并且可以使用事件或者回调函数向调用者反馈信息,建议你仔细看一下vb的帮助文件,里面很仔细的讲了如何创建ActiveX EXE部件,你只要按照他说的做一遍,就知道是怎么回事了。
#7
请介绍一下广播方式的实现方法,因为设备的地址和现场的实际情况,网络结构不能更改了,而且我现在还只对VB的MScomm熟悉一点,请介绍下通讯广播的方法,使用MSCOMM怎么实现?谢谢,
#8
是这样,封装成activex exe
详细你要看MADN,里面有个使用回调的控制咖啡炉的例子,讲的很详细
#9
MSDN
#10
广播需要设备能支持广播,你要看设备是否能接受广播,广播就是发送0地址数据。
Modbus协议是一种应答式协议,主机发出功能及参数,从机马上应答;在一条总线上,一个时刻,主机只能一台从机通信,应该不适合使用广播。
#11
对于VB而言,不管你是10个串口,还是1个串口,不管你是1个下位机还是100个下位机,你每次都只能通信一个对象,原因有二。
1、VB是单线程的
2、Moudle Bus通信每次只能读取一个下位机。
再发表一点不成熟的看法,像楼主这样的情况,不管有多少个串口,我们就管计算机连接的下位机数量,共计100个以上的下位机,如果每个下位机通信占用20ms,那么读完一次也是2s时间,实际时间开销会比这大,建议楼主将串口通信代码放到Timer中,且区别对待,对不精要的数据读取时间间隔放宽些,减少通信时间开销,此外,不要采用OnComm方式通信,发送了命令后等待的方式,并且在等待的循环体中添加DoEvents来释放CPU资源,这样可以有效的防止程序界面“假死”的现象。
再者,在硬件上,你可以考虑减少串口,采用 RS485 HUB,把下位机数据缓存在HUB上,这样也能有效的提高通信效率。这样处理,时效性会大幅提高,但成本可能也会提高不少。
1、VB是单线程的
2、Moudle Bus通信每次只能读取一个下位机。
再发表一点不成熟的看法,像楼主这样的情况,不管有多少个串口,我们就管计算机连接的下位机数量,共计100个以上的下位机,如果每个下位机通信占用20ms,那么读完一次也是2s时间,实际时间开销会比这大,建议楼主将串口通信代码放到Timer中,且区别对待,对不精要的数据读取时间间隔放宽些,减少通信时间开销,此外,不要采用OnComm方式通信,发送了命令后等待的方式,并且在等待的循环体中添加DoEvents来释放CPU资源,这样可以有效的防止程序界面“假死”的现象。
再者,在硬件上,你可以考虑减少串口,采用 RS485 HUB,把下位机数据缓存在HUB上,这样也能有效的提高通信效率。这样处理,时效性会大幅提高,但成本可能也会提高不少。
#12
我用的是MOXA的串口服务器,以太网接口至计算机的,一个服务器带16个串口,通讯程序试过很多方式,感觉凭借代码的优化不能显著提高程序的整体运行速度。
另外,发送之后等待的方式我也试过,但是每个串口设备的通讯指令不同,有的是读,有的是写,每个循环也不是相同的,我只能在返回的buff中找出具体的数据段和数据标记。
这里感谢各位参与讨论的兄弟,明天早上结贴,如有必要再开一贴讨论,感谢分再结。
另外,发送之后等待的方式我也试过,但是每个串口设备的通讯指令不同,有的是读,有的是写,每个循环也不是相同的,我只能在返回的buff中找出具体的数据段和数据标记。
这里感谢各位参与讨论的兄弟,明天早上结贴,如有必要再开一贴讨论,感谢分再结。
#13
这个对数据处理的区分就非常重要了,可已定义布尔变量来标记写,比如对地址是10的下位机要写,那么设置标记下位机10写的布尔变量为True,这样在Timer中就能判断并写。
此外,你可以把Timer 的时间间隔设置为50ms,或者更低,大致的格式如下:
Option Explicit
Dim bolWrite(0 To 99) As Boolean '写下位机标志变量,分别对应1~100个下位机
Dim intReadNo As Integer '读取下位机的标识,0~99,分别对应1~100下位机
Private Sub Timer1_Timer()
Dim intP As Integer
For intP = 0 To 99
If bolWrite(intP) Then
'写下位机
End If
Next intP
'读下位机
ReadXiaWeiji (intReadNo)
intReadNo = (intReadNo + 1) Mod 100 '这个是关键,更新读取对象
End Sub
#14
intReadNo = (intReadNo + 1) Mod 100
这一句不错,循环,我用的是:
A=iif(A=100,1,A+1)
兄弟你的思路我知道的,很感谢,通讯设备有一些是自定义的协议,大部分是Modbus,弄起来比较麻烦,现在通讯还算是畅通的,没什么别的问题,就是VB的单线程把程序速度拖慢了,我实例化了10个通讯的类模块,其实还是单线程,只是操作起来方便了些而已。所以我想换个方式来实现
这一句不错,循环,我用的是:
A=iif(A=100,1,A+1)
兄弟你的思路我知道的,很感谢,通讯设备有一些是自定义的协议,大部分是Modbus,弄起来比较麻烦,现在通讯还算是畅通的,没什么别的问题,就是VB的单线程把程序速度拖慢了,我实例化了10个通讯的类模块,其实还是单线程,只是操作起来方便了些而已。所以我想换个方式来实现
#15
我记得Moxa 的串口服务器 可以设置为TCP Server 模式,你就可以直接用网络访问了。
#16
我也遇到同样的问题,不太理解用mscomm控件的oncomm事件在初始化的时候如何设置
InputLen,InBufferCount,RThreshold的参数,触发oncomm后接收数据放在timer里面还是在oncomm()里面处理呢,我是用timer1自动发送请求指令轮询8个串口,每个串口下面有三个设备,如何用timer2来判断数据是否接受完毕呢?
InputLen,InBufferCount,RThreshold的参数,触发oncomm后接收数据放在timer里面还是在oncomm()里面处理呢,我是用timer1自动发送请求指令轮询8个串口,每个串口下面有三个设备,如何用timer2来判断数据是否接受完毕呢?
#1
VB 是单线程的,感觉满是因为串口本身慢。做成ActiveEXE 的话会好点。
建议使用支持多线程的开发工具。
建议使用支持多线程的开发工具。
#2
http://www.iocomp.com
控件
控件
#3
好多的设备啊,10几个串口,每个串口10个设备,合起来有100多个设备,真牛啊 :)
是单线程运行的
你可以试试将串口封装为 activex.exe,工程属性中设置为多线程运行,并且要使用事件回调技术(如果使用等待,用户端则会在调用返回前被挂起)
是单线程运行的
你可以试试将串口封装为 activex.exe,工程属性中设置为多线程运行,并且要使用事件回调技术(如果使用等待,用户端则会在调用返回前被挂起)
#4
类事件封装成activeexe吗?可否介绍一下实现方法或者例子之类,感激
#5
最根本的问题是,串口通讯的速度与 PC 代码的运行速度相差好多数量级。当你的程序以阻塞方式一一与之通讯时,如果设备很多,当然会感觉到慢。
1 既然是 RS485 总线,发送命令可以考虑广播方式。
2 即使是逐台设备发送命令,也不要立即读取应答。因为这需要等待设备处理完成,累积的时间也很可观。你把通讯分成两轮次,即命令轮次和应答轮次。当你回到第一台设备取应答时,它已经利用了你向其他设备发送命令的时间来进行处理。
3 不要用 VB 中的 MSComm 控件来做 RS485 操作,最好用 VC++ 写 API DLL 调用。因为控件在地址模式和数据模式之间相互切换时,需要先禁用,再切换,再启用,会很慢。两者的差距很大。
4 其实可以只用一个串口,通过 RS485 Hub 级联的方式把设备都连进来。因为 PC 上的串口并不具备自动缓存数据和命令以自行操作的功能,多了也并不快。如果你能用单片机自己搞一种代理接口,让它来自动与设备交互,然后把缓存的数据传给你,那就值得用多个串口。就好比你只管理十几个工头,让他们去管理工人。
1 既然是 RS485 总线,发送命令可以考虑广播方式。
2 即使是逐台设备发送命令,也不要立即读取应答。因为这需要等待设备处理完成,累积的时间也很可观。你把通讯分成两轮次,即命令轮次和应答轮次。当你回到第一台设备取应答时,它已经利用了你向其他设备发送命令的时间来进行处理。
3 不要用 VB 中的 MSComm 控件来做 RS485 操作,最好用 VC++ 写 API DLL 调用。因为控件在地址模式和数据模式之间相互切换时,需要先禁用,再切换,再启用,会很慢。两者的差距很大。
4 其实可以只用一个串口,通过 RS485 Hub 级联的方式把设备都连进来。因为 PC 上的串口并不具备自动缓存数据和命令以自行操作的功能,多了也并不快。如果你能用单片机自己搞一种代理接口,让它来自动与设备交互,然后把缓存的数据传给你,那就值得用多个串口。就好比你只管理十几个工头,让他们去管理工人。
#6
ActiveX EXE 是与主程序运行与不同进程的部件,两者运行基本上互不影响,并且可以使用事件或者回调函数向调用者反馈信息,建议你仔细看一下vb的帮助文件,里面很仔细的讲了如何创建ActiveX EXE部件,你只要按照他说的做一遍,就知道是怎么回事了。
#7
请介绍一下广播方式的实现方法,因为设备的地址和现场的实际情况,网络结构不能更改了,而且我现在还只对VB的MScomm熟悉一点,请介绍下通讯广播的方法,使用MSCOMM怎么实现?谢谢,
#8
是这样,封装成activex exe
详细你要看MADN,里面有个使用回调的控制咖啡炉的例子,讲的很详细
#9
MSDN
#10
广播需要设备能支持广播,你要看设备是否能接受广播,广播就是发送0地址数据。
Modbus协议是一种应答式协议,主机发出功能及参数,从机马上应答;在一条总线上,一个时刻,主机只能一台从机通信,应该不适合使用广播。
#11
对于VB而言,不管你是10个串口,还是1个串口,不管你是1个下位机还是100个下位机,你每次都只能通信一个对象,原因有二。
1、VB是单线程的
2、Moudle Bus通信每次只能读取一个下位机。
再发表一点不成熟的看法,像楼主这样的情况,不管有多少个串口,我们就管计算机连接的下位机数量,共计100个以上的下位机,如果每个下位机通信占用20ms,那么读完一次也是2s时间,实际时间开销会比这大,建议楼主将串口通信代码放到Timer中,且区别对待,对不精要的数据读取时间间隔放宽些,减少通信时间开销,此外,不要采用OnComm方式通信,发送了命令后等待的方式,并且在等待的循环体中添加DoEvents来释放CPU资源,这样可以有效的防止程序界面“假死”的现象。
再者,在硬件上,你可以考虑减少串口,采用 RS485 HUB,把下位机数据缓存在HUB上,这样也能有效的提高通信效率。这样处理,时效性会大幅提高,但成本可能也会提高不少。
1、VB是单线程的
2、Moudle Bus通信每次只能读取一个下位机。
再发表一点不成熟的看法,像楼主这样的情况,不管有多少个串口,我们就管计算机连接的下位机数量,共计100个以上的下位机,如果每个下位机通信占用20ms,那么读完一次也是2s时间,实际时间开销会比这大,建议楼主将串口通信代码放到Timer中,且区别对待,对不精要的数据读取时间间隔放宽些,减少通信时间开销,此外,不要采用OnComm方式通信,发送了命令后等待的方式,并且在等待的循环体中添加DoEvents来释放CPU资源,这样可以有效的防止程序界面“假死”的现象。
再者,在硬件上,你可以考虑减少串口,采用 RS485 HUB,把下位机数据缓存在HUB上,这样也能有效的提高通信效率。这样处理,时效性会大幅提高,但成本可能也会提高不少。
#12
我用的是MOXA的串口服务器,以太网接口至计算机的,一个服务器带16个串口,通讯程序试过很多方式,感觉凭借代码的优化不能显著提高程序的整体运行速度。
另外,发送之后等待的方式我也试过,但是每个串口设备的通讯指令不同,有的是读,有的是写,每个循环也不是相同的,我只能在返回的buff中找出具体的数据段和数据标记。
这里感谢各位参与讨论的兄弟,明天早上结贴,如有必要再开一贴讨论,感谢分再结。
另外,发送之后等待的方式我也试过,但是每个串口设备的通讯指令不同,有的是读,有的是写,每个循环也不是相同的,我只能在返回的buff中找出具体的数据段和数据标记。
这里感谢各位参与讨论的兄弟,明天早上结贴,如有必要再开一贴讨论,感谢分再结。
#13
这个对数据处理的区分就非常重要了,可已定义布尔变量来标记写,比如对地址是10的下位机要写,那么设置标记下位机10写的布尔变量为True,这样在Timer中就能判断并写。
此外,你可以把Timer 的时间间隔设置为50ms,或者更低,大致的格式如下:
Option Explicit
Dim bolWrite(0 To 99) As Boolean '写下位机标志变量,分别对应1~100个下位机
Dim intReadNo As Integer '读取下位机的标识,0~99,分别对应1~100下位机
Private Sub Timer1_Timer()
Dim intP As Integer
For intP = 0 To 99
If bolWrite(intP) Then
'写下位机
End If
Next intP
'读下位机
ReadXiaWeiji (intReadNo)
intReadNo = (intReadNo + 1) Mod 100 '这个是关键,更新读取对象
End Sub
#14
intReadNo = (intReadNo + 1) Mod 100
这一句不错,循环,我用的是:
A=iif(A=100,1,A+1)
兄弟你的思路我知道的,很感谢,通讯设备有一些是自定义的协议,大部分是Modbus,弄起来比较麻烦,现在通讯还算是畅通的,没什么别的问题,就是VB的单线程把程序速度拖慢了,我实例化了10个通讯的类模块,其实还是单线程,只是操作起来方便了些而已。所以我想换个方式来实现
这一句不错,循环,我用的是:
A=iif(A=100,1,A+1)
兄弟你的思路我知道的,很感谢,通讯设备有一些是自定义的协议,大部分是Modbus,弄起来比较麻烦,现在通讯还算是畅通的,没什么别的问题,就是VB的单线程把程序速度拖慢了,我实例化了10个通讯的类模块,其实还是单线程,只是操作起来方便了些而已。所以我想换个方式来实现
#15
我记得Moxa 的串口服务器 可以设置为TCP Server 模式,你就可以直接用网络访问了。
#16
我也遇到同样的问题,不太理解用mscomm控件的oncomm事件在初始化的时候如何设置
InputLen,InBufferCount,RThreshold的参数,触发oncomm后接收数据放在timer里面还是在oncomm()里面处理呢,我是用timer1自动发送请求指令轮询8个串口,每个串口下面有三个设备,如何用timer2来判断数据是否接受完毕呢?
InputLen,InBufferCount,RThreshold的参数,触发oncomm后接收数据放在timer里面还是在oncomm()里面处理呢,我是用timer1自动发送请求指令轮询8个串口,每个串口下面有三个设备,如何用timer2来判断数据是否接受完毕呢?