SPCOMM控件的CommReceiveData()过程(50分)

  • 主题发起人 主题发起人 carrie4002
  • 开始时间 开始时间
C

carrie4002

Unregistered / Unconfirmed
GUEST, unregistred user!
在SPCOMM控件的CommReceiveData():
1、move(buffer^,rbuf,bufferlength)后,rbuf字符串是否可以直接用于显示?
2、这个接受过程是否会影响通讯速度(COMM控件只一条指令就可以读/写命令)?
3、为何调用数表的读过程时,在正确数据前总出现'00 00...'等频率不同的字符?
 
1.rbuf数组里存放的就是16进制数.
2.如果你在收过程中要处理的事情很多,建议你用线程,每次收到数据,就传给线程,然后把buf清空,等待收下一条数据.具体的数据处理由线程去做.这样,对通讯速度基本上没有影响.
3.没看明白.
 
TO guanweiw:
谢谢。
1、rbuf里的数连取2次,能否直接用这2个数求平均而不必经过转换呢?
2、接收过程没有别的事物,只取数而已,感觉比.net用COMM的通讯慢,我没查到原因
3、仪表通讯。向扫描开关发完指令后,与之连接的被测元件的温度会传到数字电压表,此时调用数字电压表的读过程将数据读出。除读出数表上显示的数据之外,在该数据之前总有'00....'字符显示——直接显示读数结果。不知道原因在哪里?
 
1.一般rbuf定义为byte数组,其实接收到的就是0..255间的整数数组一般是ASCII值,不能直接显示,需要转成ASCII字符
2.spcomm的接受是用单独线程实现的,CommReceiveData事件只是对接收到的数据进行处理
3.发送协议不同,接收到的数据不一样,有定义字符和数据

1.肯定不行
2.串口传输速度根据波特率不同而不同,一般不能连续操作,中间要加延时,串口处理速度肯定没cpu快
3.还是协议的问题,多余的数据可能是协议里的其他字段
 
1.如果rBuf定义的是Array of Byte 型的,我认为可以不用转换了.
2.我没用过.net的COMM通讯,所以可能没有你的感觉那么明显.
3.我觉得你应该查一下被测元件和数字电压表传上来的数据,按理说,SPCOMM不会加字符的.你可以利用串口调试助手测试一下,把读指令用串口调试助手发出去,然后看看收到的数据,是否多出你说的那些字符,如果有,就是硬件有问题.
 
多谢楼上二位。
1、.net和VC++与之通讯不存在我上述的“多余字符”的问题,所以,硬件错误的概率很小了;
2、取出的数是否直接求平均值的问题我一会去测试一下;
3、在向扫描仪发指令后,延时后在向数字表发读取指令的,中间有延迟了;
4、扫描仪的协议很简单,而且“只发不收”,接收数据是通过数字表来完成的。
请帮我分析一下上述问题的可能原因?
另:
现在,系统是等扫描仪全部扫描结束后再一次性将读取的数据显示出来。
如果,我想边扫描边读同时显示出来呢?(CommReceiveData事件是有数据就触发的啊,并且,显示的语句也是放在该过程的)为何到扫描全部结束时才一条条数据显示出来呢??
 
>>1、move(buffer^,rbuf,bufferlength)后,rbuf字符串是否可以直接用于显示?

能否直接显示和协议有关,如果发送方发送的是ascii码,那就可以直接显示了。求平均值同理,这些东西主要取决于协议。

>>2、这个接受过程是否会影响通讯速度(COMM控件只一条指令就可以读/写命令)?
会影响通讯效率,可以采取措施降低影响,上面仁兄已经提出一种方法了

>>3、为何调用数表的读过程时,在正确数据前总出现'00 00...'等频率不同的字符?
是不是某个属性没设对?串口通信不管什么系统、控件不外乎就是createfile,readfile,writefile,不应该同样设置不同结果的。建议看看spcomm的源码
 
TO maze:
1、move(buffer^,rbuf,bufferlength)里,rbuf是array[0..64] of byte;然后直接用于显示,则提示:Incompatible types:'String' and 'Array'.
其实,数表口发送和接收的都是ASCII码。
 
把rbuf定义成array[0..64] of char
:)
 
可能是你的控件设置的串口速率和硬件的速率不匹配。
这个控件我用了非常好用。非常方便。
 
TO maze:(问题1)
谢谢。
目前在CommReceiveData()中,我取消了转换过程。照你的类型定义,在求平均值之前还需要转化吗?
另,(1)该过程中,无论是否有Memo1.Lines.Add(sbuf),在Memo1上都会有00...等个数不等的0字符显示,这是否与CommReceiveData()过程是自动有关呢?
(2)我想在接收前,对sbuf中的数据进行判断,如是'00..'等字符,就把它滤掉,照你的类型定义,该怎么做呢?
 
我一直没用弄明白你说说的“求平均值”是什么意思。
至于你说说的“个数不等的0字符显示”我觉得和你的串口初始化参数设置有关。
要过滤掉很简单只要判断sbuf[X]='0' 就行
 
TO maze:
(1) 数表相当于万用表,接在扫描仪的两端。在扫描仪的开关通道连续切换时,每切换一次,调用一次数表的读过程,读过程会自动触发数表串口的接收过程,该过程接收的数据为正确的数据,并显示。扫描仪的指令未必都是开关切换,还有开关的打开、断开等别的辅助指令,当发送这类指令时,也会激发数表产生电流从而有一个电压(即使为0),而,这也使数表通讯缓存有一个数值,从而自动触发CommReceiveData()过程。这就是上述问题的原因。
我现在不希望读出的数值为0,如果为0,则滤掉它。而且,低于-100和大于+1000的值都一样要过滤掉。
(2)求平均值,是我每切换一次通道时,读两次数,需对这两次数求平均值。
怎么做?
 
富翁们,诚请!
 
有点晕哈。
你说的读两次数,需对这两次数求平均值,根据你的协议,读到的是什么数?整数?浮点数?从前面你的描述中好像又是ASCII码,ASCII码求平均值有什么意义?
另外你关注一下CommReceiveData()接收到的数据的长度
 
TO maze:
谢谢你的关注。
CommReceiveData()接收到的正确数据是-8.16052837E-05这样结构的数,加符号位和小数点应该是15位。
从数表读出的数是浮点型的字符串,格式如上。连续取2次,然后求平均值。
拷给你,帮我看看。
procedure TForm2.CommReceive(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
Var
lnI:Integer;
RBuf:array[0..64] of char;
begin
RevChar:='';
FillChar(RBuf,SizeOf(RBuf),0);
Move(Buffer^,RBuf,BufferLength);
for lnI:=0 to BufferLength-1 do
RevChar:=RevChar+Char(RBuf[lnI]);
RevChar:=copy(RevChar,length(RevChar)-16,15); //取最右边的15位
Memo2.Lines.Add(RevChar);
end;
这个过程接收到的数据就是-8.16052837E-05这类数据。当然该过程还是解决不了'00 00...'等字符的出现问题。
其实,我很希望RBuf:string,而且。本来取出的数据就是字符串型的浮点数。这样的话,按照需要的-8.16052837E-05这种格式取出后,可以方便转为浮点数进行计算。也省了CommReceive()中的转换了。可不知道为什么,这样定义之后,程序执行到最后就死机。
 
出现00 00的时候也有可能是通信线路受到其他电线或者磁场的干扰,提一下而已
 
楼上说的对,但不是干扰。而是扫描仪接受指令时有一个输出,
该输出直接到了数字表的输出缓存。可我就是没办法把这些非
有用字符去掉。
 
调用过程之间加延时,这样调一次CommReceiveData()就会得出一次数据。不会一次性出来的。肯定行的。
 
后退
顶部