Binary 转换泰克公司';TCL中的二进制数据

Binary 转换泰克公司';TCL中的二进制数据,binary,type-conversion,tcl,Binary,Type Conversion,Tcl,我使用TCL脚本从Tektronix示波器中提取Tektronix RIBinary格式的数据,然后在脚本中我需要将其转换为十进制值 首先,我对二进制转换做得很少,但在我看来,这种二进制格式的文档也非常模糊,这让我更加沮丧。无论如何,这是我当前的代码: proc ::Scope::CaptureWaveform {VisaAlias Channel} { # Apply scope settings ::VISA::Write $VisaAlias "*WAI" ::VI

我使用TCL脚本从Tektronix示波器中提取Tektronix RIBinary格式的数据,然后在脚本中我需要将其转换为十进制值

首先,我对二进制转换做得很少,但在我看来,这种二进制格式的文档也非常模糊,这让我更加沮丧。无论如何,这是我当前的代码:

proc ::Scope::CaptureWaveform {VisaAlias Channel} {
    # Apply scope settings
    ::VISA::Write $VisaAlias "*WAI"
    ::VISA::Write $VisaAlias "DATa:STARt 1"
    ::VISA::Write $VisaAlias "DATa:STOP 4000"
    ::VISA::Write $VisaAlias "DATa:ENCdg RIBinary"
    ::VISA::Write $VisaAlias "DATa:SOUrce $Channel"

    # Download waveform
    set RIBinaryWaveform [::VISA::Query $VisaAlias "CURVe?"]

    # Parse out leading label from scope output
    set RIBinaryWaveform [string range $RIBinaryWaveform 11 end]

    # Convert binary data to a binary string usable by TCL
    binary scan $RIBinaryWaveform "I*" TCLBinaryWaveform
    set TCLBinaryWaveform

    # Convert binary data to list
}
现在,此代码从机器中提取以下数据:

-1064723993-486674282 50109321-6337556 70678 8459972 143470359 1046714383 1082560884 1042711231 1074910212 1057300801 1061457453 1079313832 1066305613 1059935120 1068139252 1066053580 1065228329 1062213553

这就是当我只获取常规ASCII数据时,机器产生的结果(即转换后上述数据应该是什么样子):

-1064723968-48667427250109320-6337556 70678 8459972 143470352 1046714368 1082560896 1042711232 1074910208 1057300800 1061457472 1079313792 10663056005600 1059935104 1068139264 1066053568 1065228352 1062213568

最后,这里是对泰克公司RIBinary规范的参考,因为我认为它不是一种标准数据类型:

我已经在Tektronix网站上寻找了一段时间,以获取有关转换数据的更多信息,我只能找到上面的URL,但是如果我找到任何有用的信息,我会评论或编辑这篇文章

更新

  • 答案不一定非要出现在TCL中。如果有人能在高层次上帮助我从逻辑上解决这个问题,我可以详细分析TCL的细节(我认为这对其他人也会更有帮助)
  • 我需要以二进制格式传输数据,然后再进行转换的原因是为了优化。由于这个原因,我不能让设备在传输之前执行转换,因为它会减慢进程
  • 我更新了一些代码,现在我的结果与实际结果非常接近。我认为这可能与数据中的逗号有关
  • 下面是未经任何解析就从设备发送的原始数据的示例
  • 根据@kostix的建议,我用他给我的代码编写了第二个脚本,并对其进行了修改以适应我的数据集。可以在下面看到,但是结果与我上面的代码完全相同
ASCIi

:曲线-1064723968,-48667427250109320,-63375567067884599721434703521046714368108256089610427112321074910208105730080010614574107931379210663056010559910410681392641060535681065228352106213568

日报:

:曲线

注意:在RIBinary上-“:CURVE#280”是我需要解析的标题的全部部分,但它的#280部分可能因我收集的数据而异。以下是泰克关于#280的更多信息:

块是二进制格式的波形数据。波形已格式化 as:#其中是y字节数。对于 例如,如果=500,则=3。要删除的字节数 传输包括校验和

因此,对于我当前的数据集x=2和yyy=80。我只是不太熟悉转换二进制数据,所以我不知道如何通过编程来处理块格式

根据@kostix的建议,我用他给我的代码编写了第二个脚本,我对其进行了修改以适应我的数据集:

set RIBinaryWaveform [::VISA::Query ${VisaAlias} "CURVe?"]

binary scan $RIBinaryWaveform a8a curv nbytes

encoding convertfrom ascii ${curv}

scan $nbytes %u n

set n

set headerlen [expr {$n + 9}]

binary scan $RIBinaryWaveform @9a$n nbytes

scan $nbytes %u n

set n

set numints [expr {$n / 4}]

binary scan $RIBinaryWaveform @${headerlen}I${numints} data

set data

这段代码的输出与我上面提供的代码相同。

我没有这方面的经验,但喜欢谷歌搜索。以下是我的发现

,在标题为“格式化I/O操作”的部分中,告诉我们
viQueryf()
标准C API函数将
viPrintf()
(写入设备)与
viScanf()
(从设备读取)结合在一起,示例包括调用
viQueryf(io),“:CURV?\n”,“%#b”和&totalPoints,rdBuffer)(参见«IEEE-488.2二进制数据-“%b”»一节),其中函数的第三个参数指定了所需的格式

Tcl库中的
VISA::Query
过程与我眼中的
viQueryf()
非常相似,因此我希望它接受第三个(可选)参数,该参数指定数据的格式

如果没有类似的情况,让我们看看您的ASCII数据。您的FAQ条目和我找到的文档都指定不透明数据可能以一系列不同大小和长度的整数的形式出现。“RIBinary”格式声明它应该是大端有符号整数

binary scan
Tcl命令能够扫描字节流中的16位和32位大端整数-相应地使用
S*
I*
格式

您的ASCII数据显然看起来像32位整数,因此我会尝试使用
I*
进行扫描

另请参阅-它似乎与我上面链接的PDF指南有很多共同之处,但无论如何可能很方便

TL;博士

  • 尝试研究您的API,找到一种明确告诉设备您想要的数据格式的方法。如果设备可能以某种方式在外部重新配置以更改其默认数据格式,这可能会产生一个更健壮的解决方案,从而有效地将地毯拉到依赖于某些(猜测的)默认值的代码脚下
  • 试着按照上面概述的方式解释数据,看看解释是否合理
附言。 这可能毫无意义,但在调用
viQueryf()
时,我找不到任何在“CURV”和“?”之间有“e”的示例

更新(2013-01-17,根据数据格式的新发现):要对不同类型的数据进行
二进制扫描
,可以采用两种技术:

  • 二进制扫描
    一行接受任意多个说明符;当
    二进制扫描
    读取提供的数据时,从左到右处理它们
  • 你能做到吗
    % set b [encoding convertto ascii ":CURVE #224"]
    :CURVE #224
    % append b [binary format S* [list 0 1 2 -3 4 -5 6 7 -8 9 10 -11]]
    :CURVE #224............
    
    % binary scan $b a8a curv nbytes
    2
    % encoding convertfrom ascii $curv
    :CURVE #
    % scan $nbytes %u n
    1
    % set n
    2
    % set headerlen [expr {$n + 9}]
    11
    % binary scan $b @9a$n nbytes
    1
    % scan $nbytes %u n
    1
    % set n
    24
    % set numints [expr {$n / 2}]
    12
    % binary scan $b @${headerlen}S${numints} data
    1
    % set data
    0 1 2 -3 4 -5 6 7 -8 9 10 -11
    
    # Download waveform
    set RIBinaryWaveform [::VISA::Query ${VisaAlias} "CURVe?"]
    
    # Extract block format data
    set ResultCount [expr [string range ${RIBinaryWaveform} 2 [expr [string index${RIBinaryWaveform} 1] + 1]] / 4]
    
    # Parse out leading label from Tektronics block format
    set RIBinaryWaveform [string range ${RIBinaryWaveform} [expr [string index ${RIBinaryWaveform} 1] + 2] end]
    
    # Convert binary data to integer values
    binary scan ${RIBinaryWaveform} "I${ResultCount}" Waveform
    set Waveform