我正在使用 TCL 脚本从 Tektronix 的 RIBinary 格式的 Tektronix 示波器中提取数据,然后在脚本中我需要将其转换为十进制值。
首先,我在二进制转换方面做得很少,但更让我感到沮丧的是,在我看来,关于这种二进制格式的文档也很模糊。无论如何,这是我当前的代码:
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 -486674272 50109320 -6337556 70678 8459972 143470352 1046714368 1082560896 1042711232 1074910208 1057300800 1061457472 1079313792 1066305600 1059935104 1068139264 1066053568 1065228352 1062213568
最后,这里引用了泰克的 RIBinary 规范,因为我认为它不是标准数据类型:
http://www.tek.com/support/faqs/how-binary-data-represented-tektronix-oscilloscopes
我一直在 Tektronix 网站上寻找有关转换数据的更多信息,上面的 URL 是我能找到的所有信息,但如果我发现任何更多信息,我会评论或编辑这篇文章可能有用。
更新
- 答案不一定必须在 TCL 中。如果有人可以帮助我在逻辑上从高层次上解决这个问题,我可以整理出 TCL 的详细信息(我认为这对其他人也更有帮助)
- 我需要以二进制形式传输数据然后进行转换的原因是为了优化。因此,我不能让设备在传输之前执行转换,因为它会减慢过程。
- 我更新了一些代码,现在我的结果非常接近实际结果。我认为这可能与最初数据中的逗号有关。
- 下面是从设备发送的原始数据的示例,无需我进行任何解析。
- 根据@kostix 的建议,我用他给我的代码制作了第二个脚本,我修改了它以适应我的数据集。它可以在下面看到,但是结果与我上面的代码完全相同。
ASCIi
:
:曲线-1064723968,-486674272,50109320,-6337556,70678,8459972,143470352,1046714368,1082560896,1042711232,1074910208,1057300800,1061457472,1079313792,1066305600,1059935104,1068139264,1066053568,1065228352,1062213568
肋骨:
:CURVE #280ÀçâýðüÿKì
关于 RIBinary 的注意事项 - ":CURVE #280" 是我需要解析的所有标头的一部分,但其中的 #280 部分可能会因我收集的数据而异。以下是泰克关于#280 含义的更多信息:
block 是二进制格式的波形数据。波形格式如下: # 其中是 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
此代码的输出与我上面提供的代码相同。