读取串口的最新行

时间:2019-02-28 23:44:13

标签: serial-port tcl serial-communication scilab

我从来没有用tcl编写过任何代码,也没有关于串行通信的新手,所以如果我的问题没有道理,请提前抱歉。

我正在尝试解决this problem的问题,我想在其中侦听串行端口,并像普通的串行终端(例如Arduino的串行监视器)一样在SciLab中逐行打印更新。 Serial Communication Toolbox for Scilab有一个readserial宏(source on GitHub):

function buf=readserial(h,n)
   if ~exists("n","local") then
     N=serialstatus(h); n=N(1)
   end
   TCL_EvalStr("binary scan [read "+h+" "+string(n)+"] cu* ttybuf")
   buf=ascii(evstr(TCL_GetVar("ttybuf")));
endfunction

其中TCL_EvalStr解释tcl中的字符串。所以我的问题是如何更改线路:

binary scan [read "+h+" "+string(n)+"] cu* ttybuf

是否只返回串行端口上的最新非空行?如果您能eli5这行是做什么的,我也将不胜感激。

P.S.1。。距离here很远,我尝试过:

 TCL_EvalStr("binary scan [lindex [split [read -nonewline "+h+" "+string(n)+"] "\n"] end] cu* ttybuf")

但我收到错误消息:

  

错误:语法错误,意外的字符串,期望为“,”或

在SciLab中。

P.S.2。定义新功能:

function buf=readlnserial(h)
   TCL_EvalStr("binary scan [lindex [split [read -nonewline "+h+"] \"\n\"] end] cu* ttybuf")
   buf=ascii(evstr(TCL_GetVar("ttybuf")));
endfunction

导致错误消息:

  

给定操作数的未定义操作。

     

检查或定义函数%c_l_s是否过载。

在SciLab终端中。

P.S.3。命令:

TCL_EvalStr('[split [read -nonewline '+h+'] "\n"]')

TCL_EvalStr("[split [read -nonewline "+h+"] '\n']")

均导致错误:

  

错误:检测到异构字符串,以'开头,以“。

结尾

在SciLab中。

P.S.4。。我认为,如果我使用SciLab命令TCL_EvalFile而不是TCL_EvalStr,我可以解决上述问题。我只需要弄清楚如何将h传递到tcl脚本并读回ttybuf

P.S.5。。我可以使用大括号代替双引号来解决SciLab字符串和"\n"之间的疯狂冲突:

 TCL_EvalStr("binary scan [lindex [split [read -nonewline "+h+"] {\n}] end] cu* ttybuf")

但是它仍然不能满足我的需求。

P.S.6。。对于那些由于带引号或双引号的异类字符串而最终出现在此处的用户,正确的语法为'this '"string'" is inside quotation'。在其他单引号或双引号之前,基本上单引号会将它们变成文字字符。

1 个答案:

答案 0 :(得分:1)

首先,让我们完成以下内容:

binary scan [read "+h+" "+string(n)+"] cu* ttybuf

就是这样:

binary scan [read CHANNEL NUM_BYTES] cu* ttybuf

其中CHANNEL实际上是您正在读取的Tcl通道的名称(它可能应该处于二进制模式,但这超出了所显示的代码范围),而{{1 }}是要读取的字节数。然后将其处理为一个数字列表(写入Tcl变量NUM_BYTES),这些数字是读取的无符号字节。


现在,您要使用面向行的阅读。好吧,Tcl的ttybuf命令不能做到这一点(这是面向固定缓冲区或面向整个文件的);您需要read才能进行面向行的阅读。 (从串行线路读取时,您永远不需要全文件导向的处理;它永远不会到达EOF。您可以使用非阻塞读取来进行欺骗……但这很复杂。)

gets命令将返回从通道读取的下一行,并且删除行尾标记。我们仍然可以将其与二进制通道一起使用(这有点奇怪,但并非不可能),这意味着我们可以这样做:

gets

将其转换回您拥有的所有包装器:

binary scan [gets CHANNEL] cu* ttybuf

我重命名了它,并删除了function buf=readserialline(h) TCL_EvalStr("binary scan [gets "+h+"] cu* ttybuf") buf=ascii(evstr(TCL_GetVar("ttybuf"))); endfunction 的所有操作;线是线,不是固定长度。 (我想知道我们是否可以直接检索字符串而无需通过字节列表进行转换;这样会效率更高。但这仅次于使它正常工作。)