读取Tek示波器波形超时的问题

aofengshen 2015-02-07 02:15:02
小弟最近在弄一个示波器,要求是用c++读出示波器所捕获波形的数据。根据提供的例程FORMATIO.cpp,我修改了资源地址后运行,在进入ReadWaveform(ViSession vi, long* elements)函数,读取
// Get width of element field.
status = viScanf(vi, "%c", &c);
if (status < VI_SUCCESS) goto error;
assert(c >= '0' && c <= '9');
时报错为TIMED  OUT  或者是触发断言。
以下贴上代码,请求各位大侠指导!

小弟能读出示波器的ID,设置各种属性,但就是无法读出波形数据。
弄了三个星期了,不好意思了~~无奈求助于众位大神!

/*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <visa.h>
#include <string.h>

// This function reads the currently selected waveform and returns
// it as an array of doubles.
double* ReadWaveform(ViSession vi, long* elements) {
ViStatus status;
float yoffset, ymult;
ViChar buffer[256];
ViChar c;
long count, i;
double* ptr = NULL;
unsigned char szBuff[256] = { 0,};

assert(elements != NULL);

status = viSetAttribute(vi,VI_ATTR_WR_BUF_OPER_MODE, VI_FLUSH_ON_ACCESS);
status = viSetAttribute(vi,VI_ATTR_RD_BUF_OPER_MODE, VI_FLUSH_ON_ACCESS);

// Turn headers off, this makes parsing easier
status = viPrintf(vi, "header off\n");
if (status < VI_SUCCESS) goto error;

// Get record length value
status = viQueryf(vi, "hor:reco?\n", "%ld", elements);
if (status < VI_SUCCESS) goto error;

// Make sure start, stop values for curve query match the full record length
status = viPrintf(vi, "data:start 1;data:stop %d\n", *elements);
if (status < VI_SUCCESS) goto error;

// Get the yoffset to help calculate the vertical values.

status = viQueryf(vi, "WFMOutpre:YOFF?\n", "%f", &yoffset);
if (status < VI_SUCCESS) goto error;

// Get the ymult to help calculate the vertical values.
status = viQueryf(vi, "WFMOutpre:YMULT?\n", "%f", &ymult);
if (status < VI_SUCCESS) goto error;

// Request 8bit binary data on the curve query
status = viPrintf(vi, "DATA:ENCDG RIBINARY;WIDTH 1\n");
if (status < VI_SUCCESS) goto error;

// Request the curve
status = viPrintf(vi, "CURVE?\n");
if (status < VI_SUCCESS) goto error;

// Always flush if a viScanf follows a viPrintf or viBufWrite.
status = viFlush(vi, VI_WRITE_BUF | VI_READ_BUF_DISCARD);
if (status < VI_SUCCESS) goto error;

// Get first char and validate
status = viSetAttribute(vi,VI_ATTR_RD_BUF_OPER_MODE, VI_FLUSH_DISABLE);
status = viScanf(vi, "%c", &c);
if (status < VI_SUCCESS) goto error;
assert(c == '#');
//此处运行错误
// Get width of element field.
status = viScanf(vi, "%c", &c);
if (status < VI_SUCCESS) goto error;
assert(c >= '0' && c <= '9');

// Read element characters
count = c - '0';
for (i = 0; i < count; i++) {
status = viScanf(vi, "%c", &c);
if (status < VI_SUCCESS) goto error;
assert(c >= '0' && c <= '9');
}

// Read waveform into allocated storage
ptr = (double*) malloc(*elements*sizeof(double));

for (i = 0; i < *elements; i++) {
status = viScanf(vi, "%c", &c);
if (status < VI_SUCCESS) goto error;
ptr[i] = (((double) c) - yoffset) * ymult;
}

status = viFlush(vi, VI_WRITE_BUF | VI_READ_BUF_DISCARD);
if (status < VI_SUCCESS) goto error;

return ptr;

error:
// Report error and clean up
viStatusDesc(vi, status, buffer);
fprintf(stderr, "failure: %s\n", buffer);
if (ptr != NULL) free(ptr);
return NULL;
}


// This program reads a waveform from a Tektronix
// TDS scope and writes the floating point values to
// stdout.
int main(int argc, char* argv[])
{
ViSession rm = VI_NULL, vi = VI_NULL;
ViStatus status;
ViChar buffer[256];
double* wfm = NULL;
long elements, i;

// Open a default Session
status = viOpenDefaultRM(&rm);
if (status < VI_SUCCESS) goto error;

// Open the gpib device at primary address 1, gpib board 8

//因为我用的是usb故此处修改为USB::0x0699::0x03A3::C011293::INSTR
status = viOpen(rm, "GPIB8::1::INSTR", VI_NULL, VI_NULL, &vi);  

if (status < VI_SUCCESS) goto error;

// Read waveform and write it to stdout
wfm = ReadWaveform(vi, &elements);
if (wfm != NULL) {
for (i = 0; i < elements; i++) {
printf("%f\n", wfm[i]);
}
}

// Clean up
if (wfm != NULL) free(wfm);
viClose(vi); // Not needed, but makes things a bit more understandable
viClose(rm);

return 0;

error:
// Report error and clean up
viStatusDesc(vi, status, buffer);
fprintf(stderr, "failure: %s\n", buffer);
if (rm != VI_NULL) viClose(rm);
if (wfm != NULL) free(wfm);
return 1;
}
...全文
2202 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
ilikeorange 2017-06-28
  • 打赏
  • 举报
回复
直接注释掉,用viQueryf(vi, ":CURV?", "%#b", &totalPoints, rdBuffer); 来代替。
hchmirage 2015-12-08
  • 打赏
  • 举报
回复
我也遇到了同样的问题,请问楼主你解决了吗?是如何解决的呢?
aofengshen 2015-02-07
  • 打赏
  • 举报
回复
引用 1 楼 xjq2003 的回复:
是不是你发送命令错误啊, 或者数据解析不对!
我看过手册 似乎也没有什么不对的。贴上解说~~~ The following C++ example, FORMATIO.CPP, includes a main program that opens the Default Resource Manager, opens a session to the GPIB device with primary address 1 on board 8, calls the ReadWaveform() function to get header and waveform data from a Tektronix TDS scope, then writes the response to the standard output, and closes the session. At the end of the example, the program closes the session to the Default Resource Manager. To review the use of Tektronix TDS scope commands and formatted I/O operations in more detail: 1. The header off command sent using the viPrintf() operation causes the oscilloscope to omit headers on query responses, so that only the argument is returned. The \n format string sends the ASCII LF character and END identifier. 2. The hor:reco? query sent using the viQueryf() operation asks the oscilloscope for the current horizontal record length and receives the response.The \n format string sends the ASCII LF character and END identifier. The %ld modifier and format code specify that the argument is a long integer. 3. The data:start %d;data:stop %d\n commands sent using the viPrintf() operation set the starting data point to 0 and the ending data point to the record length - 1 for the waveform transfer that will be initiated later using a CURVE? query. The %d format codes specify that the arguments are integers. The \n format string sends the ASCII LF character and END identifier. 4. The WFMOUTPRE:YOFF?\n query sent using the viQueryf() operation asks the oscilloscope for the vertical offset (YOFF) and receives the response. This information is needed to convert digitizing units to vertical units (typically volts) in order to scale the data. The %f format code specifies that the argument is a floating point number. The \n format string sends the ASCII LF character and END identifier. 5. The WFMOutpre:YMULT?\n query sent using the viQueryf() operation asks the oscilloscope for the vertical scale factor (YMULT) per digitizing level (also called the Y multiple) vertical multiplier and receives the response. This information is needed to convert digitizing units to vertical units (typically volts) in order to scale the data. The %f format code specifies that the argument is a floating point number. The \n format string sends the ASCII LF character and END identifier. 6. The DATA:ENCDG RIBINARY;WIDTH 1\n command sent using the viPrintf() operation sets the data format for the waveform transfer to binary using signed integer data-point representation, with the most significant byte transferred first. The DATA:WIDTH command sets the number of bytes to transfer to one byte per data point. The \n format string sends the ASCII LF character and END identifier. In binary format, the waveform is formatted as: #<a><bbb><data><newline> where: a = the number of b bytes bbb = the number of bytes to transfer data = the curve data newline = a single-byte new-line character at the end 7. The CURVE?\n query sent using the viPrintf() operation asks the oscilloscope to transfer the waveform. The \n format string sends the ASCII LF character and END identifier. Since the waveform could easily exceed the size of the formatted I/O read buffer, a viQueryf() is not being used here. Instead, wewant to split up the write (viPrintf()) and read (viScanf()) operations, rather than combining them in a single query. 8. The viFlush(vi, VI_WRITE_BUF | VI_READ_BUF_DISCARD) operation performs two combined tasks before getting the oscilloscope’s response to the CURVE? query. It transfers the contents of the formatted I/O write buffer (in this case, the CURVE? query) to the oscilloscope, and discards the contents of the formatted I/O read buffer.This flushing operation should always be performed before a viScanf() operation that follows a viPrintf() or viBufWrite() operation, to guarantee that flushing occurs. 9. The first viScanf(vi, “%c”, &c)operation reads the first character of the waveform response from the oscilloscope. The %c format code specifies that the argument is a character. This character is expected to be #. 10. The second viScanf(vi, “%c”, &c)operation reads the next character of the waveform response from the oscilloscope. This character specifies the width of the next field, which contains the number of bytes of waveform data to transfer, and is expected to be between 0 and 9. 11. The third viScanf(vi, “%c”, &c)operation reads the characters that represent the number of bytes to transfer. The result of the previous scan is used as the counter in the FOR loop. Each character read is expected to be between 0 and 9. 12. The program uses the results of the previous scan to allocate the right size for an array of double-word floating-point numbers that will contain the waveform. Then the fourth viScanf(vi, “%c”, &c) operation reads the waveform itself, using the result of the previous scan as the counter in the FOR loop. The viScanf() operation accepts input until an END indicator is read or all the format specifiers in the format string are satisfied. 13. The ptr[i] = (((double) c) yoffset) * ymult;calculation converts the waveform data results from string data into a numerical array of double-word floating point numbers, and also converts the data from digitizing units into vertical units (typically volts in the case of waveform data).
xjq2003 2015-02-07
  • 打赏
  • 举报
回复
是不是你发送命令错误啊, 或者数据解析不对!

1,221

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧