有关在工业上plc的数据采集中,Timer不准的问题?(50分)

  • 主题发起人 主题发起人 wl_5545831
  • 开始时间 开始时间
W

wl_5545831

Unregistered / Unconfirmed
GUEST, unregistred user!
我编写了一个PLC的数据采集软件,每隔30ms从plc中读取512个字节,并以文件流的方式写入到文件中。这512个字节中头7个字节表示Year、Month、Day、Hour、Min、Sec、Msec,其中Msec仅表示0~99(去掉了个位,因为字节仅仅是0~255)。但是当我读取这个文件的时候发现文件中每条记录的时间间隔不是30ms,这是通过判断每条记录的Msec的间隔是否为30得出的。我想是不是Timer在30ms中出现了延迟导致的。然后我换上了JvThreadTimer,但是还是问题依旧,那位朋友能给出解决办法?下面是一个timer的小例子:
procedure TForm1.Button2Click(Sender: TObject);
var
Year,Month,Day,Hour,Min,Sec,Msec:word;
Tof:TFileStream;
buf:array[1..7] of byte;
begin
decodedate(now,Year,Month,Day);
DecodeTime(now,Hour,Min,Sec,Msec);
Year:=Year-2000;
buf[1]:=Year;
buf[2]:=Month;
buf[3]:=Day;
buf[4]:=Hour;
buf[5]:=Min;
buf[6]:=Sec;
buf[7]:=Msec;
if FileExists('test.dat') = true then
Tof:=TFileStream.Create('test.dat',fmOpenReadWrite)
else
Tof:=TFileStream.Create('test.dat',fmCreate);
Tof.Seek(0,soFromEnd);
Tof.WriteBuffer(Buf,7);
Tof.Free;
end;
这样测试以后结果就不准了。
 
你搞错了,
1。Timer的精度是到不了30ms的。
2。每隔30ms从plc中读取,每条记录的时间间隔为30ms,我想,到现在为止,只有神仙才有办法精确地做到这一点,而且还必须你和你的PLC都是神仙^_^
3。通常情况下,PLC中数据的传输是需要花费一定时间的,尤其当你指定读取的地址不是连续的。
4。我不知道你要这样做的目的是什么,但建议换一种思路,比如提高读取的速度,比如用线程不间断读取然后筛选需要的数据。
 
其实,这几天我做了实验,如果设定为30ms的话,实际的就会在31ms左右,而设定为125ms的话,就可以,而100ms则实际为109左右。
我呢只是想从S7-400的PLC中读取一个DB块,然后我做一个数据采集软件,这样就可以在出现事故以后进行分析事故原因了。难度有一些,比如数据采集的时间周期的精度、采集的数据有些大(压缩方面不太精通,我想将每次取回来的512个字节压缩小些,最好每次都压缩的大小一样,这样方便读取)、还有就是分析的时候想用CHart的方式显示,但是这个时间不好对应上。
 
我前一阵子调过一种三菱的PLC,厂家会提供一系列的编程接口,甚至无需编程可直接将指定地址与范围的数据生成到Excel或数据库中(利用Com接口)。如果是Excel,还可以使用VB宏进行定时等控制。

另外,Timer也是不可靠的,因为它需要依靠消息运作,当用户在你的界面上进行操作时,队列中的某个OnTimer动作有可能会被忽略。
 
我想问一下WickedladII。我现在想接收每秒70多帧的数据每帧35个字节。就这样的速度你说用spcomm控件,或者还有多线程的方法可以实现吗?我需要收到的每一帧数据的时间打印在这一帧后面。我是要把这些数据写入一个.bin文件中。我写的程序出现的情况就是接收到的帧不是完整的是一段一段的。但是好像不是丢帧。主要是程序无法判断就收到的数据中每两个字节间的时间间隔。因为spcomm控件的readintervaltime的时间单位是毫秒。所以现在我想不出好的解决方案。各位大虾请给我指条路吧。
 
Timer 定时不准的。

但我有个问题,PLC与PC 如何同步?

PLC 也是30ms 发一次数据?还是先是上位机发请求,下位机再发数据?

如果上位机不发请求,而它如何与PLC同步?
 
to QSmile,
PLC不是与PC同步的,我不知道你是否已经具有相当的硬件开发经验,就我的浅见,你不必担心PLC的速度,它上面内容的更新是非常迅速的,另外,PLC不像通讯口(如串口)传输,不需要握手,说白一点,它就是一个存储器,照着地址读就可以了,也就是说,他们之间并不存在发与送的问题(数据传送是依靠另外单独的模块实现的)。

哦,我忘记了,不知道你的PLC与PC之间是用什么接口,如果是以太网,使用UDP协议相对快些。
 
to mouthbig219,
串口每秒可以接收多少字节,跟用什么控件和多线程都没有很大关系,关键在于你的波特率。

我很久没用spcomm了,接收时最好每帧都要有起始和结束标志字节,或者字节量,这样你就
可以在每接收到一帧后进行相应处理。

如果有时间去看一下TurboPower,非常好。
 
那我想问一下大虾WickedladII。我设置的波特率是38400。我收的每一帧的前两个字节是帧头,而最后一个字节为校验和。有一个停止位。spcomm自己能判断吗?我老是感觉这个控件的效率可能不能在这种要求下使用。还有就是spcomm属性里有一个readintervaltime在这个属性里可以设置判断收到的两个字节是不是一次收到的(我感觉是不是用这个来区分每一帧)可是我接收到的数据每一帧间隔不到一毫秒。他的单位是毫秒。这样的话就不能区分了。我不知道是不是这样。
还有就是turbopower好像是个Delphi第三方组件开发商。他的控件里面有串口通信方面的的控件?
 
还有就是我用串口调试工具选择的波特率就是38400显示也没有问题.所以说波特率的设置应该问题不大.还是别的方面的原因.
 
turbopower->Async Professional
这个在98,2000,Xp下都可以,非常专业,本来要很多money的,后来开源了,悲哀啊。。。
忘记了spcomm中是否有这样的功能,不过当初也是因为达不到自己的需求,我才放弃了spcomm。

此贴中我针对你的回答到此为止,在别人的地盘里有点不好意思。。。
如果你还有问题,另开个贴吧。
 
我是用CPORT的,代码也比较简单,满足不了要求的话,可以自己改
最好用的还是自己根据API写,最快好控制(不存在丢帧问题)
如果要定时读的话,还是要用定时器的,不过不能用那个TIMER,用高精度线程定时器吧,它上面的说明可以达到10ms
另外,从站PLC不可能主动发数据的,只能是上位机查询。。。
 
我刚做了一个相当类似的东东。

用串口采集数据,速率 100Hz 每个包16bit (一个 Word)
采集到的数据实时用波形显示出来。

同时还要做一路声卡采集,11025Hz 16Bit ,实时画出波形
二者要求同步

如果用你的方法,定时去读,计算机能在1秒中之内完成这样多的事吗?
要读声卡 11025次,还要读串口 100次 还要画波形

不可能的

我只说我的方法
PLC 定时 30ms 发一次数据,不是叫你 30ms 读一次。它只是告诉你它的发送频率。

你一次读一堆数据,再把这些数据分到指定的时间段里。
比如:一个包 2个 byte
你读一次,可能读到 32 个 byte ,你再把这些数据分开到时间段。再显示

redsoft.ys168.com 这里有我程序的界面 在图片里。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
937
SUNSTONE的Delphi笔记
S
后退
顶部