title: Convert Tektronix's RIBinary data in TCL
body: <p>I am pulling data from a Tektronix oscilloscope in Tektronix' RIBinary format using a TCL script, and then within the script I need to convert that to a decimal value.</p>
  
  <p>I have done very little with binary conversions in the first place, but to add to my frustration the documentation on this binary format is also very vague in my opinion. Anyway, here's my current code:</p>
  
  <pre><code>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
  }
  </code></pre>
  
  <p>Now, this code pulls the following data from the machine:</p>
  
  <p>-1064723993 -486674282 50109321 -6337556 70678 8459972 143470359 1046714383 1082560884 1042711231 1074910212 1057300801 1061457453 1079313832 1066305613 1059935120 1068139252 1066053580 1065228329 1062213553</p>
  
  <p>And this is what the machine pulls when I just take regular ASCII data (i.e. what the above data should look like after the conversion):</p>
  
  <p>-1064723968 -486674272 50109320 -6337556 70678 8459972 143470352 1046714368 1082560896 1042711232 1074910208 1057300800 1061457472 1079313792 1066305600 1059935104 1068139264 1066053568 1065228352 1062213568</p>
  
  <p>Finally, here is a reference to the RIBinary specification from Tektronix since I don't think it is a standard data type:</p>
  
  <p><a href="http://www.tek.com/support/faqs/how-binary-data-represented-tektronix-oscilloscopes" rel="nofollow noreferrer">http://www.tek.com/support/faqs/how-binary-data-represented-tektronix-oscilloscopes</a></p>
  
  <p>I've been looking for a while now on the Tektronix website for more information on converting the data and the above URL is all I've been able to find, but I'll comment or edit this post if I find any more information that might be useful.</p>
  
  <p><em>Updates</em></p>
  
  <ul>
  <li>Answers don't necessarily have to be in TCL. If anyone can help me logically work through this on a high level I can hash out the TCL details (this I think would be more helpful to others as well)</li>
  <li>The reason I need to transfer the data in binary and then convert it afterwards is for the purpose of optimization. Due to this I can't have the device perform the conversion before the transfer as it will slow down the process.</li>
  <li>I updated my code some and now my results are maddeningly close to the actual results. I assume it may have something to do with the commas that are in the data originally.</li>
  <li>Below are now examples of the raw data sent from the device without any of my parsing.</li>
  <li>On suggestion from @kostix, I made a second script with code he gave me that I modified to fit my data set. It can be seen below, however the result are exactly the same as my above code.</li>
  </ul>
  
  <p><code>ASCIi</code>:</p>
  
  <blockquote>
    <p>:CURVE -1064723968,-486674272,50109320,-6337556,70678,8459972,143470352,1046714368,1082560896,1042711232,1074910208,1057300800,1061457472,1079313792,1066305600,1059935104,1068139264,1066053568,1065228352,1062213568</p>
  </blockquote>
  
  <p>RIBinary:</p>
  
  <p>:CURVE #280ÀçâýðüÿKì</p>
  
  <p>Note on RIBinary - ":CURVE #280" is all part of the header that I need to parse out, but the #280 part of it can vary depending on the data I'm collecting. Here's some more info from Tektronix on what the #280 means:</p>
  
  <blockquote>
    <p>block is the waveform data in binary format. The waveform is formatted
    as: # where  is the number of y bytes. For
    example, if  = 500, then  = 3.  is the number of bytes to
    transfer including checksum.</p>
  </blockquote>
  
  <p>So, for my current data set x = 2 and yyy = 80. I am just really unfamiliar with converting binary data, so I'm not sure what to do programmatically to deal with the block format.</p>
  
  <p>On suggestion from @kostix I made a second script with code he gave me that I modified to fit my data set:</p>
  
  <pre><code>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
  </code></pre>
  
  <p>The output of this code is the same as the code I provided above.</p>