小弟最近在弄一個示波器,要求是用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;
}
uj5u.com熱心網友回復:
是不是你發送命令錯誤啊,或者資料決議不對!
uj5u.com熱心網友回復:
我看過手冊 似乎也沒有什么不對的。貼上解說~~~
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).
uj5u.com熱心網友回復:
我也遇到了同樣的問題,請問樓主你解決了嗎?是如何解決的呢?uj5u.com熱心網友回復:
直接注釋掉,用viQueryf(vi, ":CURV?", "%#b", &totalPoints, rdBuffer); 來代替。轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/58995.html
上一篇:學生成績管理系統的排序無法解決
