我是tcl中的总菜鸟,但我收到了使用tcl的相当复杂的系统(硬件和软件),我必须做一件事。这个硬件有接口,我可以在tcl脚本中读取。例如。我可以发送命令来读取一些电压电平,硬件应该使用轮询值进行响应(AFAIK它是带有工程值,原始值等的tcl列表)。
我需要做的是使用该池值创建实时(每秒新值)图形,并且必须使用某些数据分析软件(DAS)的图形功能。假设该软件可以使用许多数据IO访问方式,那么从tcl传递数据值的最佳方法是什么?例如。我可以将它写入文件,然后在DAS中读取文件,但在这种情况下,我认为访问打开的文件甚至是同步的问题。
我认为如果我可以从该DAS运行tcl脚本可能会更容易,但现在它看起来不可能,它看起来必须从该系统特定软件启动脚本。
非常感谢任何帮助,提示等。
祝你好运 bLAZ
答案 0 :(得分:3)
after
命令,但您可以在延迟到期时为其提供过程或脚本。当您考虑将多个此类读取器链接在一起时,两个模型之间的差异变得非常重要。所以你应该使用类似的东西:
proc schedule_xx_update {interval} {
variable id_xx
set values [get_value_from_source]
display_value $values
set xx_id [after $interval schedule_xx_update]
}
proc stop_xx_updates {} {
variable id_xx
after cancel $id_xx
}
connect_to_device
schedule_xx_update 1000
vwait ::forever
最后的vwait
开始运行Tcl事件循环。在我们输入之前,我们安排一个读取和显示功能,它将在指定的延迟后运行,并在完成后重新安排自己再次运行。添加额外的阅读器是相当明显的。
对于原始问题:如果您使用API调用或命令来读取设备输出,则上述内容应该可用。可能您的设备使用频道(文件或串行频道)进行响应,在这种情况下,您应该使用fileevent
进行调查,这将引发一个事件,以便在频道上的数据可用时调用过程。
答案 1 :(得分:2)
据我所知,假设“命令”是一个导致你电压值的命令: 因此可以使用tk canvas生成Plot,并且可以使用exec
获取值代码:
set width 500
set height 500
canvas .c -width $width -height $height -background white
pack .c
set oldx 0
set oldy 0
while {1} {
after 1000; # After 1 sec
set newy 0
catch {set newy [exec command]}; # setting the newy value, means voltage value from "cmd" which is a shell command
.c create line $oldx $oldy [expr $oldx+1] $newy; # will draw a line from previous plot point to latest plot point
incr oldx; # increasing x values means time be 1 sec
set oldy $newy
puts "Updating for $oldx sec"
update
}
答案 2 :(得分:2)
这是一种基于套接字的方法:
# Use port 12345
socket -server accept_client 12345
proc accept_client {sock from port} {
fconfigure $sock -blocking 0 -buffering line
fileevent $sock readable [list readsock $sock]
lappend ::clients $sock
}
proc readsock {sock} {
catch {read $sock}
if {[eof $sock]} {
global clients
set pos [lsearch -exact -- $clients $sock]
if {$pos != -1} {
set clients [lreplace $clients $pos $pos]
}
close $sock
}
}
proc broadcastValues {} {
global clients
after 1000 broadcastValues
if {![llength $clients]} {
# No client connected
return
}
# You have to modify the next line
set data [lindex [GetTheDataHere] 1]
foreach client $clients {
# The data is seperated by a newline (\r\n)
puts $client $data
}
}
after idle broadcastValues
vwait forever; # Enter the event loop.
如果你只想让它在本地机器上监听,你可以做一些额外的检查,例如将-myaddr 127.0.0.1
传递给套接字,或者检查这个IP是否可以在accept_client中连接(如果它不应该只是close $sock
)
你必须自己找出所需数据的索引,我使用了1
,这是列表的第二个元素。您必须使用返回值的命令替换GetDataHere
。
协议很简单:每行一个值,每秒一个新值。