From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

tek210 programming

Im not sure if this is the best group to post a tek210 gpib
programming question, but i got no response on
sci.electronics.equipment and this is the group with more mention of
the "gpib" keyword

Im dealing with grabbing curve data from a old tek210 scope with the
gpib interface. Since its crucial to get both channels at the same
time, my adquisition cycle is:

im pausing the scope
grabbing each channel separately
and then resume adquisition

I do this with a compiled .dll that uses the NI-488-Gpib api and then
call it from a program. The strange problem is that in a PIV with
Windows2000 professional this works nicely for my purpose. But in a
PIII machine with Windows98 i get an "unable to serial poll scope"
error

ibwrt(Dev, "CURVE?\n", 7 );
ibwait(Dev, TIMO | RQS);
ibrsp(Dev, &ResByte);

//either i grab a positive error 3 in this test in windows98
if (ibsta & ERR)
{
GPIBCleanup(Dev, "Unable to serial poll oscilloscope");
return 3;
}

//or either i grab later a "cannot get waveform preamble" error


Any ideas what may cause the different behaviour of the same dll both
in windows 98/P3 and W2000Pro/P4? even the scope is the same in both
cases




The code of the cycle is the following (the called functions code are
displayed at the end of the post)


*-----------------------------------------*------------------------------------*
device = Init_Osciloscopio( "DAT:SOU CH1;:DAT:ENC RIBinary;:DAT:WID
1;:DAT:STAR 1;:DAT:STOP 2500;:HOR:MAIN:SCALE 5e-4;:CH1:SCALE
5e-1;:CH2:SCALE 5e-3\n"
, "SEL:CH1 ON;:SEL:CH2 ON;:ACQ:MOD SAMPLE\n" );

error_code = SendString(device, "ACQUIRE:STATE ON\n");

// Done initialization, now we start adquisition

error_code = Pause(device);

error_code = 1;
while (error_code != 0)
{
device = Init_Osciloscopio( "DAT:SOU CH1;:DAT:ENC RIBinary;:DAT:WID
1;:DAT:STAR 1;:DAT:STOP 2500;:HOR:MAIN:SCALE 5e-4;:CH1:SCALE
5e-1;:CH2:SCALE 5e-3\n"
, "SEL:CH1 ON;:SEL:CH2 ON;:ACQ:MOD SAMPLE\n" );
error_code = SendString(device, "CURVE?\n");
error_code := WriteWaveform(device, CH1_fileout);
}

error_code = 1;
while (error_code != 0)
{
device = Init_Osciloscopio( "DAT:SOU CH1;:DAT:ENC RIBinary;:DAT:WID
1;:DAT:STAR 1;:DAT:STOP 2500;:HOR:MAIN:SCALE 5e-4;:CH1:SCALE
5e-1;:CH2:SCALE 5e-3\n"
, "SEL:CH1 ON;:SEL:CH2 ON;:ACQ:MOD SAMPLE\n" );
error_code = SendString(device, "CURVE?\n");
error_code := WriteWaveform(device, CH2_fileout);
}

error_code = Resume(device);
*-----------------------------*------------------------------------------*






-------------------*---------------------*---------------------------
DLL functions

////////////////////////////////////////////
// INIT_OSCILOSCOPIO( SCOPECONFIG ; ACQWFM )

extern "C" int Init_Osciloscopio(char* ScopeConfigString

, char* AcqWaveformString )
{
int Dev,
LoopCount = 0,
Done = 0;
char ResByte;

/*
char ScopeConfigString[] = "DAT:SOU CH1;:DAT:ENC RIBinary;:DAT:WID
1;"
":DAT:STAR 1;:DAT:STOP 2500;"
":HOR:MAIN:SCALE 5e-4;"
":CH1:SCALE
5e0\n";
char AcqWaveformString[] = "SEL:CH1 ON;:ACQ:MOD SAMPLE\n";
*/

Dev = ibdev(BDINDEX, PRIMARY_ADDR_OF_SCOPE, NO_SECONDARY_ADDR,
TIMEOUT, EOTMODE, EOSMODE);
if (ibsta & ERR)
{
printf("Unable to open device\nibsta = 0x%x iberr = %d\n",
ibsta, iberr);
return 1;
}

ibwrt(Dev, ScopeConfigString, strlen(ScopeConfigString));
if (ibsta & ERR)
{
GPIBCleanup(Dev, "Unable to set waveform characteristics");
return 1;
}

ibwrt(Dev, AcqWaveformString, strlen(AcqWaveformString));
if (ibsta & ERR)
{
GPIBCleanup(Dev, "Unable to set up acquisition");
return 1;
}

ibwrt(Dev, "*SRE 16\n", 8L);
if (ibsta & ERR)
{
GPIBCleanup(Dev, "Unable to set SRE");
return 1;
} return Dev;
}

//////////////////////////////////////////////////
// SENDSTRING( DEV ; MSG )

extern "C" int SendString(int Dev, char* message)
{
ibwrt(Dev, message, strlen(message));
if (ibsta & ERR)
{
GPIBCleanup(Dev, "Unable to set message");
return 1;
} return 0;
}

/////////////////////////////////////
// PAUSE ( DEV )

extern "C" int Pause(int Dev)
{
ibwrt(Dev , "ACQuire:STATE STOP\n", 18L);
if (ibsta & ERR)
{
GPIBCleanup(Dev, "Unable to resume");
return 5;
}
//ibwrt(Dev , "ACQuire:STATE RUN\n", 18L);
}


//////////////////////////////////////
// RESUME ( DEV )

extern "C" int Resume(int Dev)
{
ibwrt(Dev , "ACQuire:STATE RUN\n", 18L);
if (ibsta & ERR)
{
GPIBCleanup(Dev, "Unable to resume");
return 1;
}
//ibwrt(Dev , "ACQuire:STATE RUN\n", 18L);
}

/////////////////////////////////////////////////////////
// WRITEWAVEFORM ( DEV ; FILENAME )

extern "C" int WriteWaveform(int Dev, char* filename)
{
const Addr4882_t address = 7; //the address of the scope
(change to fit your configuration)
const int BUF_SIZE = 2048; //the total buffer size
const int NUM_DEVICES = 31; //maximum number of devices on the bus

char buffer[BUF_SIZE];
char data_buf[BUF_SIZE];
int LoopCount = 0,
Done = 0;

char ResByte;
/*
* The application waits for either the oscilloscope to request
* service or the call to timeout. The wait mask supplied to
* ibwait contains two bits: TIMO and RQS. The TIMO bit limits
* the wait period to the timeout value that was specified in
* the ibdev call; the RQS bit instructs the application to wait
* until the device has requested service. The ibwait call is
* completed when one or more of the specified wait conditions
* becomes true.
*/
ibwait(Dev, TIMO | RQS);
if (ibsta & ERR)
{
GPIBCleanup(Dev, "Error occurred while waiting for Service
Request");
return 1;
}

/*
* If after the ibwait call, the RQS bit in ibsta is not set,
* the Oscilloscope did not request sevice.
*/
if (!(ibsta & RQS))
{
GPIBCleanup(Dev, "Error : Oscilloscope did not request
service");
return 2;
}

ibrsp(Dev, &ResByte);
if (ibsta & ERR)
{
GPIBCleanup(Dev, "Unable to serial poll oscilloscope");
return 3;
}

/*
* If the value is not 0x50, the device did not request service
* as a result of completing the acquisition. In this case, an
* error message is printed and the program exited.
*/
if (ResByte != SERPOLLRESPONSE)
{
printf("Error : Unexpected serial poll response. Expected :
0x%x "
"Received : 0x%x\n", SERPOLLRESPONSE, ResByte);
printf("Cleanup: Taking device off-line\n");
ibonl (Dev, 0);
return 4;
}

/*
* The Curve string from the oscilloscope is read into the
* character variable ValueStr
*/
ibrd(Dev, ValueStr, ARRAYSIZE);
if (ibsta & ERR)
{
GPIBCleanup(Dev, "Unable to read curve data");
return 5;
}

LoopCount++;

ValueStr[ibcntl - 1] = '\0';

printf("\nWaveform No: %d\n\n", LoopCount);
cout << ValueStr<< " :"<< ibcntl << endl;

ibwrt(Dev , "WFMPre?\n" , 8L);
if (ibsta & ERR)
{
GPIBCleanup(Dev, "Unable to request curve preamble");
return 6;
}
ibrd(Dev, data_buf, ARRAYSIZE);
if (ibsta & ERR)
{
GPIBCleanup(Dev, "Unable to read curve preamble");
return 7;
}
data_buf[ibcntl - 1] = '\0';
cout << " preamble: "<< data_buf << endl;



/*
* The application writes the command 'CURVE?' to the
oscilloscope.
* This command requests the oscilloscope to supply the waveform
* data before serial polling it again.
*/

ibwrt(Dev, "CURVE?\n", 7L);
if (ibsta & ERR)
{
GPIBCleanup(Dev, "Unable to request curve data");
return 8;
}

cout << "string conversion "<< endl;
//decode the byte-stream that represents the waveform
TekWaveform wfm = DecodeWaveform(data_buf , ValueStr);
cout << "Desc: " << wfm.description.c_str() << endl;
cout << "Num points: " << wfm.num_points << endl;
cout << "x units: " << wfm.x_units.c_str() << endl;
cout << "x increment: " << wfm.x_increment << endl;
cout << "x offset: " << wfm.x_offset << endl;
cout << "y units: " << wfm.y_units.c_str() << endl;
cout << "y multiplier: " << wfm.y_multiplier << endl;
cout << "y offset: " << wfm.y_offset << endl;
cout << "y zero: " << wfm.y_zero << endl;

ofstream outfile(filename, ios::out);
outfile << wfm.x_units.c_str() << "\t" << wfm.y_units.c_str()
<< endl;
//the x-values are calculated using the x_increment and
x_offset
for(int i = 0; i < wfm.num_points; i++)
outfile << wfm.x_zero + wfm.x_increment * (i -
wfm.x_offset)
<< "\t" << wfm.data_points[i] << endl;
outfile.close();

//clean up after ourselves
DeleteTekWaveform(wfm);

return 0;
}


////////////////////////// Local Library functions
DecodeWaveform( databuffer , valuestr )

struct TekWaveform {
string description; //a string with the description of the
waveform
int num_points; //the number of points in the waveform
string x_units; //a string with the x axis units
double x_increment; //x-axis inter-point spacing
double x_offset; //trigger point offset index
double x_zero;
string y_units; //a string with the y axis units
double y_multiplier; //y-value multiplier
float y_offset; //y-value offset
double y_zero; //y zero intercept
double *data_points; //the points in the waveform


};



TekWaveform DecodeWaveform(char *preamble, char *curve) {
TekWaveform wfm; //declare a waveform
wfm.data_points = NULL; //set to zeros
wfm.num_points = 0;
wfm.x_increment = 0;
wfm.x_offset = 0;
wfm.y_multiplier = 0;
wfm.y_offset = 0;
wfm.y_zero = 0;

string pre(preamble); //make a string out of char*

int byte_number = atoi(pop_string(pre, ';').c_str()); //get
byte number
int bit_number = atoi(pop_string(pre, ';').c_str()); //get bit
number
string encoding = pop_string(pre, ';'); //get encoding
string binary_format = pop_string(pre, ';'); //get binary
format
string byte_order = pop_string(pre, ';'); //get byte order

wfm.num_points = atoi(pop_string(pre, ';').c_str()); //get the
number of points

cout << " numpoints "<< wfm.num_points << endl;

cout << "byteN: "<< byte_number << " bitN: "<< bit_number <<
endl;
cout << "encoding "<<< endl;
cout << "bf " << binary_format << endl;
cout << "bo "<< byte_order<< endl;

/*
if((byte_number != 2) || (bit_number != 16) //check for proper
conditions
|| (encoding.compare("BIN") != 0)
|| (binary_format.compare("RI") != 0)
|| (byte_order.compare("LSB") != 0)
)
return wfm; //return the null waveform if bad
conditions
*/

pop_string(pre, '\"'); //ignore a quote char
wfm.description = pop_string(pre, '\"'); //get the description
pop_string(pre, ';'); //ignore the semicolon

string point_format = pop_string(pre, ';'); //get the point
format
cout << " point format "<< point_format << endl;
if(point_format.compare("Y") != 0) {
wfm.num_points = 0;
return wfm;
}

//this format is describe in the tektronix developer manual
// pag 2-159

wfm.x_increment = atof(pop_string(pre, ';').c_str()); //get x
increment
cout << " x_inc " << wfm.x_increment<< endl;

wfm.x_offset = atoi(pop_string(pre, ';').c_str()); //get x
offset
cout << " x_off " << wfm.x_offset << endl;

wfm.x_zero = atof(pop_string(pre, ';').c_str()); //get x
offset
cout << " x_zero " << wfm.x_zero << endl;

pop_string(pre, '\"'); //ignore a quote char
wfm.x_units = pop_string(pre, '\"'); //get the x-axis units
cout << " x_units " << wfm.x_units << endl;
pop_string(pre, ';'); //ignore the semicolon


wfm.y_multiplier = atof(pop_string(pre, ';').c_str());
cout << " y_mult " << wfm.y_multiplier << endl;


wfm.y_zero = atof(pop_string(pre, ';').c_str());
cout << " y_zero " << wfm.y_zero << endl;

wfm.y_offset = atof(pop_string(pre, ';').c_str());
cout << " y_off " << wfm.y_offset << " cast " <<
*(int*)(&wfm.y_offset)<

pop_string(pre, '\"'); //ignore a quote char
wfm.y_units = pop_string(pre, '\"'); //get y-axis units
cout << " y_units " << wfm.y_units << endl;
pop_string(pre, ';'); //ignore the semicolon




/* Process the data itself. To get values in the right units,
we have to use the multipliers and offsets.
So we have X_i = x_increment * (i - x_offset)
and Y_i = y_zero + y_multiplier * (y_i - y_offset)
where y_i is the value from the byte-stream.
The y-value conversion is done here into the
array of doubles data_points. The x-axis conversion
is done outside, where applicable. */
int start = ((int) curve[1]) - ((int) '0'); //get some header
info
wfm.data_points = new double[wfm.num_points]; //allocate space
char *curve_data = (char *) (curve + 2 ); //pointer magic
for(int i = 0; i < wfm.num_points; i++) //calculate the y
values
//wfm.data_points[i] = ((curve_data[i]);
wfm.data_points[i] = wfm.y_zero + wfm.y_multiplier *
(curve_data[i] - (char)wfm.y_offset);

return wfm; //return the completed waveform
}
0 Kudos
Message 1 of 2
(2,332 Views)
Charles,

I didn't dig through your code much, but what is your iberr constant after you do the IBRSP() and you get the error? That could give us a clue as to why it is failing. What version of the driver are you using in both cases (Win98 and 2K)?

Scott B.
Applications Engineer
National Instruments
0 Kudos
Message 2 of 2
(2,332 Views)