------
协议我这边定好了,也知道发过来的哪条数据是哪台仪器的,我想问的是我用什么方法来循环访问所有的仪器比较合理而且省时间又比较稳定。我用timer事件来控制相邻两次访问两台仪器的时间间隔是否合理。
------
timer事件显然是不合理的,时间长了可能丢失数据,时间短了浪费资源,可以用异步方式或开一个线程监视数据的到来。
------
为什么要循环接收?你还要按顺序接收数据?
我们公司也做这样的,就是让设备自动发,我这边等着收就是了。
硬件设备通讯应该都有规约协议的
设备也会有唯一的地址,除非你广播发数据。
如果是设备发送数据,那它们应该有个心跳时间,间隔多长时间给主机发一次,
那你就能算出你Timer的间隔时间了,设个数据缓冲区,接收设备发的数据
定时读数据和清理缓冲区。
如果你是给设备发请求数据,再让设备发回来,那就不用这么麻烦了吧。
------
怎么开线程监视数据的到来?我得先发送请求命令,仪器才给我发数据的。我得从第一台开始依次发请求命令依次接收数据,到最后
一台接收完毕后,此次循环才算结束。在给某一台仪器发完请求命令后,需等待几百毫秒再读取接收到的数据,从而获得此仪器的测
量数据。我不知道怎么用线程监视数据是否发过来了。以前还没用线程,所以一点概念都没有。
------
不用线程的话,做个数据缓冲区。
给表发数据
等待表回发数据(等待时间设个合理的时间,根据通讯速率)
判断缓冲区的数据,是否有数据
没有,再发N次,超过N次跳出。
有数据,判定数据是否正确。
发下一个表的数据
------
您说的做个数据缓冲区,不太明白您的意思。我在timer事件里发命令接收数据等等和您说的基本差不多。
------
就是暂时存设备发过来的数据的地方,你要不用线程,先这么做吧。
------
485?你是要从串口读数据吧,用timer的话,如果超时的话,可能会丢失数据的
------
最好统一输入,用485全都用485.用IP或COM线.就全用某一种.
你这一半,那一半,估计调试的时候够呛,你调试完全部,有空再调试一半是这,一半是那,也来得及.
用TIMER可行的.但不好,TIMER时间短的话,你的程序跟死机一个样,人家想用机器也不行.
你还是用线程好,调试好接收的时间间隔,就不停的收集数据,然后收集数据后,做好规则,再显示.
最好就是可以扔数据,就是坏数据,直接扔掉不要....不然就要修正数据.
------
你这个情况就象我上次做的温度采集差不多,不过我的只有十几台设备。由于水平有限,采用循环发收,稳定性一直不好,偶尔会丢数据,就放弃了。等着看看你的成功方案~~我觉得设备多了用同步通讯方式肯定不行的,但异步操作我还是没有搞清WINDOWS下的机理。
------
我这128台仪器是串联的,每个都有个485的接口,然后把仪器两两串联起来,到最后一台仪器就把它的485接口和电脑连上就行了。其实都是485的串口,没涉及其他的。但是每台仪器发送接收数据不能同时,因为同时就造成数据流阻塞了。如果用线程具体该怎么写程序啊?请哪位高手说详细点!
------
485通讯的时候,每个设备都是有个地址的,每个设备都不能同时发送消息,但是作为程序,你不需要管他,应为这是硬件实现的
,你只需要把数据读出,保存在你自己的缓冲区里就可以了,建议还是做个线程吧,线程读取到数据后,填充到一个队列里,然后通知主程序,主程序从队列里取出数据,处理。
线程的例子,你网上查一下,很多的,也蛮简单的
------
您有相关的例子吗?网上搜的例子,我一点都看不懂,而且还不知道是不是针对我的这个编程软件的。
------
------
不要用定时器,建立一个辅助线程,在其中创建一个"异步"模式的串口,设置好事件屏蔽字,然后等待发生事件.可以最快地响应串口接收任务.
------
不要用线程,
用485/MODBUS最简单:
1.用485串行通迅;
2。总线式,协议用支持多端口的MODBUS协议;
但你的每台单片机如果不支持此协议就麻烦了,
因为用总线式,如果主机发命令,每台机都会
收到相同的命令串,所以,要支持多端口的软协议;
------
485/总线式一定要是主/从式的,
电脑是主,仪器是从,否则,仪器各顾各的发,总线上就乱了套;
电脑不发命令,仪器就不能发数据,
电脑发的取数命令中包含是哪一个节点的编号,这样,对方就响应,
电脑只要按顺序一个一个发,每个节点就依次乖乖的发数据;
这个最好的协义就是 MODBUS;
------
用mscomm控件,将接受的数据先缓存然后用线程处理数据,这时候就要注意临界区问题了。使用std::vector<BYTE>。接收mscomm的数据,发送当然可以使用timer,主要是发送和处理数据的时间间隔点。
------
拴在一根绳上的蚂蚱,串在一起了
只能一个一个的处理,如果时间太长,就分两根"绳子",每根上拴64个,依次类推
如果是一根"绳子",用不用线程无所谓
如果是多根绳子,线程或许有些改善
------
最好不要用Timer,因为Timer是占用的主线程时间,如果主线程非常忙的时候,Timer就不会进去,也就有可能延时,不会是实时 的接收到数据,建议用线程
在线程里面用Sleep函数来控制接收时间
------
一个主线程负责收发调度,一个读线程,一个写线程,最好不要用窗口线程的TIMER事件处理调度和收发,效率不高,而且对界面有影响,一般象这种慢速的读写最好开个单独线程,有数据到了可以直接向窗口发消息,要写数据可以直接向写线程发送线程消息!
------
你们说了这么多建议,真的很感谢!可是我还是对线程一点都不了解!能不能给个例子呢?我现在最主要是连线程是什么,怎么用都不知道啊!
------
楼主啊。。你连线程都没有碰过,做这个项目是不是有点牵强啊。。。。
我也做过类似的项目,不过我只需要和最多13个单片机通信,我的通信时间间隔是200MS,通信方式是这样的:
1.上位机每隔 200MS 发送一个字节,代表“通道号”,比如发送“02”。
2.这时候,下面 13 个单片机全部都会收到这个字节,即“02”
3.每个单片机检查自己的通道号是否是“02”,如果是,则把自己的规定内容发给上位机,如果不是,则不做任何动作。(当然,单片机各自的通道号是不能重复的)
4.上位机收到从单片机“02”发来的数据进行处理。完成后从步骤1开始重复,发出下一个通道号“03”。
这样循环下去,依次将通道号发送给每个单片机。。
你那 128 台单片机就可以使用这种方式来通信,简单,高效。。。。。。。
你记住,应该由上位机来决定“谁给我数据”,而不是由单片机想发就发,或者自己定义时序来发,这样的话,你根本就无法控制数据的流量和准确性。。。。切记,切记
------
楼主啊。。你连线程都没有碰过,做这个项目是不是有点牵强啊。。。。
我也做过类似的项目,不过我只需要和最多13个单片机通信,我的通信时间间隔是200MS,通信方式是这样的:
1.上位机每隔 200MS 发送一个字节,代表“通道号”,比如发送“02”。
2.这时候,下面 13 个单片机全部都会收到这个字节,即“02”
3.每个单片机检查自己的通道号是否是“02”,如果是,则把自己的规定内容发给上位机,如果不是,则不做任何动作。(当然,单片机各自的通道号是不能重复的)
4.上位机收到从单片机“02”发来的数据进行处理。完成后从步骤1开始重复,发出下一个通道号“03”。
这样循环下去,依次将通道号发送给每个单片机。。
你那 128 台单片机就可以使用这种方式来通信,简单,高效。。。。。。。
你记住,应该由上位机来决定“谁给我数据”,而不是由单片机想发就发,或者自己定义时序来发,这样的话,你根本就无法控制数据的流量和准确性。。。。切记,切记
------
使用定时器是可以的, 200ms 的间隔, 但是485总线上能挂满128个设备, 这个问题还有待验证.
我们现在称与485总线上的设备通讯一次的过程叫做轮询.
必须要保证在任何时刻, 电脑只与485总线上的一台设备通讯, 并且一定要等待设备返回了数据之后才能轮询下一个485设备.
可以把128个设备地址, 建成一个队列, 用一个定时器每200ms 一次一个一个的与设备通讯
它的过程就是
PC->串口->PC发送的数据->485总线->设备1->设备返回的数据->485总线->PC串口->PC
PC->串口->PC发送的数据->485总线->设备2->设备返回的数据->485总线->PC串口->PC
PC->串口->PC发送的数据->485总线->设备3->设备返回的数据->485总线->PC串口->PC
PC->串口->PC发送的数据->485总线->设备1->设备返回的数据->485总线->PC串口->PC
假设有3个设备接在485总线上, 上面的过程就演示了整个轮询的过程
------
Mark
------
------
------
恩。。。怕出问题是正常的。。
说实话,我不太信任 485(CAN 总线)。。。
一个最主要的原因就是,他容易受干扰。。。。。。
至于多长时间间隔去通信一次,这个要看你下面的单片机执行的具体任务和耗费的时间,不同的单片机和其执行代码,所消耗的时间是不同的,这个你应该和你们搞单片机的人多沟通(我就是的)。。。
我这个项目最长碰到的问题就是:
1.通信被干扰,导致数据不对。(我们的解决办法:对数据进行 CRC 校验)
2.单片机故障,导致某一个单片机卡死,独占整个 CAN 总线,其他单片机都无法通信(找你们那个做单片机的人解决吧)。。。。
3.内存泄露(多由串口通信引起),如果你的上位机运转时间很长的话,请你在实验室的时候多多观察其内存,我写的上位机程序,最长可以在别人的工厂里面连续不停得开机 2 个月,没出过问题
最后,128路单片机确实有点多。。。。
------
好像只能是127路吧,其中第一路是广播地址用的。参见modbus协议。
------
另开线程吧
------
回帖是一种美德!
------
开一个工作线程就行了,采用轮询方式访问硬件设备
读写的话我建议使用异步方式访问串口,对于不同的设备或者是协议,可以设置不同的延时参数
定时器不够稳定
------
非阻塞读写串口线程这么写
0如果线程未结束就继续执行循环
1判断主线程是否改变了状态。
2如果已经调用了读串口函数就看看有没有接收到东西。
3如果接受到看看数据是否完整。完整就准备下一个向设备写的命令,不完整就准备继续读串口函数。
4如果数据完整,写串口向下一个设备发命令。
5如果允许读串口,调用读串口函数。
6Sleep(1);睡一下,少占CPU。睡醒了回到0。
------
好吧,我承认我上面说了假话.. 看了美女忘了学习 O(∩_∩)O~
------
这类应用最好不使用TIMER,还是使用线程收数,并开足够的缓冲区!
------
Mark!
------
你的和我的一样,只不过我的下位机没有那么多,我是用线程接收的,开一个辅助线程用来接收数据,主线程用来显示数据
------
你最好是用pc做主机,485设备作从机,主机发命令,从机应答的形式,每个从机要有地址。
------
1.485接口的设备一般可以设定地址
2.pc 发地址
3.pc 接收相应地址的数据
4.第二项和第三项重复循环。
------
各位大侠就是厉害啊,顶,有钱的捧个钱场,没钱的捧个人场啊。
------
------
不错
------
哈哈
------
mark
------
MODBUS吧
------
MARK。。。
就快用到咯~~~
学习下。。。
------
不错哦
------
异步IO。
------
haohaohao....
------
学习来的
------
回帖是一种美德!
------
回帖是一种美德!
------
iiiiiiiiiiiiiiiiiiiiiiiiiiiii
------
ooooooooooooooooooooooooooooooooooooooooooo
------
多线程
------
用timer事件肯定是不合理的,应该用异步方式或开一个线程监视数据的到来。
------
.
------
呵呵呵,用我的组态软件吧,你只需要写两个函数就完成啦
一个是定义发送命令字节
一个是处理接收数据
其它的全部由组态软件完成了。
将生成128个单元,每个单元有多少数据你可以通过资源文件定义。
不过,价格有点高 :)
------
我是来学习的。
------
仔细看了一下,18、19楼说的比较好,不过你要考虑多线程。一个串口处理128台下位机完成一个循环的时间比较长,如果对轮询时间有要求就要考虑多串口了,可以参考MOXA的多串口卡
------
没有事件吗
------
纯顶贴,不发表任何以及爱你
------
jf
------
不要用Timer,除非你想整死客户或系统是拿来演示教学用的.
用多串口卡和多线程,1线程-->1串口,1串口-->n控制器
,128个控制器可以相当是实时连接
同时应考虑数据同步,不然会出现系统错误,这比较复杂
------
Windows 下可以考虑使用WaitCommEvent
------
PC->串口->PC发送的数据->485总线->设备1->设备返回的数据->485总线->PC串口->PC
PC->串口->PC发送的数据->485总线->设备2->设备返回的数据->485总线->PC串口->PC
PC->串口->PC发送的数据->485总线->设备3->设备返回的数据->485总线->PC串口->PC
。。。。。。。
pc向串口设备发送读取数据指令
串口设备响应之后返回数据
进入下一个设备
如此循环就可以
------
上面大家说了半天,能告诉我一下出了 timer 能实现循环,还有什么
方法能够实现循环那??
, 如果不用 timer 做循环的话,那么用什么方式循环那?
是用 for 语句吗?谢谢。
------
其实这种方案有很大的问题,128路串联的话,这个和IP通讯不同,它没有侦测线路是否繁忙的命令,所以每个机器都必须不停的接收数据,判断协议,如果有数据通信,不是自己的就不通讯,这样线路就异常繁忙(串口的传输速率太低了)。
至于楼主问的timer中做循环轮询是行不通的,应该采用串口异步通信,线程中事件通知的方式。
不过我建议楼主还是用多串口卡并发通讯比较稳当.
------
#include <Process.h>
到这个文件里看看,解决办法就在里面
写一个静态函数,做为处理流程
用上面包将该静态函数启动为线程。
不用Timer处理
------
------
最近看了资料,485可能用阻塞更简单。
------
我这里有128台仪器串联,然后其中一台连485接到到电脑上,电脑上的界面就负责采集这些仪器发送过来的数据,仪器发送数
据时是一台一台发的,有时间的先后顺序,不能同时发,我该怎么来循环接收这些数据呢?我现在用的是Timer事件,隔400ms
接收一次,不知道是否可以?有人推荐我用线程,但是我对线程一点都不了解,不知道怎么用。而且不知道是不是用线程会更
好,或者还有没有别的更好的方法。请大家指教!谢谢!
-----------------------------------
建议在unix 或 Linux ,使用select方式,比较好处理些。
后台负责数据采集,
前台负责数据展现。
------
windows下操作系统不稳定,容易出问题,连你自己都不知道。
------
在windows ,使用线程机制,每个线程采用阻塞的方式,也是可以的。但控制起来不是非常好,只要其中一个线程数据或处理有点小问题,呵呵,问题就麻烦了。
------
485就是一对一的串口通信,多一个地址字节而已。
------
放在TIMER里绝不可取!TIMER停掉了,你都不知道怎么回事,一个繁忙的进程里,TIMER可能不触发或延迟触发。
------
学习了!
桂ICP备07017180号