传递更改参数值的方法。档案还是......?

时间:2013-09-13 08:11:40

标签: tcl

我是tcl中的总菜鸟,但我收到了使用tcl的相当复杂的系统(硬件和软件),我必须做一件事。这个硬件有接口,我可以在tcl脚本中读取。例如。我可以发送命令来读取一些电压电平,硬件应该使用轮询值进行响应(AFAIK它是带有工程值,原始值等的tcl列表)。

我需要做的是使用该池值创建实时(每秒新值)图形,并且必须使用某些数据分析软件(DAS)的图形功能。假设该软件可以使用许多数据IO访问方式,那么从tcl传递数据值的最佳方法是什么?例如。我可以将它写入文件,然后在DAS中读取文件,但在这种情况下,我认为访问打开的文件甚至是同步的问题。

我认为如果我可以从该DAS运行tcl脚本可能会更容易,但现在它看起来不可能,它看起来必须从该系统特定软件启动脚本。

非常感谢任何帮助,提示等。

祝你好运 bLAZ

3 个答案:

答案 0 :(得分:3)

@vishwadeep:你正在考虑这个错误的方法。 Tk支持调度任务在一段延迟后运行,而不是等待1个周期然后再做某事。这使用完全相同的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

协议很简单:每行一个值,每秒一个新值。