// agilentscope.c - GNU g++ egcs-2.91.66, V. Bancroft 1999
//Fixed to run on ubuntu linux 2018
//src from documentation. --fixed errors
#include
#include
#include // ISO C Standard: 4.9 INPUT/OUTPUT
#include // ISO C Standard: 4.12 DATE and TIME
#include // POSIX Standard: 7.1-2 General Terminal Intf.
#include // POSIX Standard: 2.10 Symbolic Constants
#include // POSIX Standard: 6.5 File Control Operations
#include // POSIX Standard: 2.6 Primitive System Data Types
#include // POSIX Standard: 5.6 File Characteristics
#define DWORD size_t
// a file handle is an integer descriptor,
#define HANDLE int
// open failure results in negative one,
#define INVALID_HANDLE_VALUE -1
// default device string
#define DEVICE "/dev/ttyUSB0"
// define values for iSerOK
#define TRUE 1
#define FALSE 0
HANDLE hSerPort; // Global variables
int iSerOK;
void SerMessage(char* msg1, char* msg2)
// Displays a message to the user.
// msg1 = main message
// msg2 = message caption
// Change this to your preferred way of displaying msgs.
{
printf( "%s ( %s )\n", msg1, msg2);
}
void SerCrash(char* msg1, char* msg2)
// Like SerMessage, but ends the program.
{
SerMessage(msg1,msg2);
iSerOK = 0;
}
int SerOK()
// Returns nonzero if most recent operation succeeded,
// or 0 if there was an error
{
return iSerOK;
}
void SerOpen(char* portname, char* handshake)
// Opens the serial port.
// portname = "COM1", "COM2", etc.
// handshake = "RTS" or "DTR"
{
//
// Open the port using a handle
//
hSerPort = open( portname, O_RDWR );
if (hSerPort == INVALID_HANDLE_VALUE) {
SerCrash("Can't open comm port",portname);
iSerOK = FALSE;
}
struct termios term;
if ( tcgetattr( hSerPort, &term ) ) {
SerMessage( "Can't get device settings.", "tcgetattr");
iSerOK = FALSE;
}
// Now choose the handshaking mode...
if ((handshake[0] == 'r') || (handshake[0] == 'R'))
{
term.c_cflag = CRTSCTS; // RTS/CTS flow control of output
}
else
{
term.c_cflag &= ~( CRTSCTS ); // disable CTS flow control of output
}
//
// Set baud rate and other attributes
//
term.c_cflag |= CS8; // eight bit character set
term.c_cflag |= CREAD; // enable receiver
term.c_cflag |= HUPCL; // lower modem lines on last close
term.c_cflag |= CLOCAL; // ignore modem status lines
term.c_iflag = 0; // turn off input processing
// term.c_iflag = IGNPAR; // ignore parity errors
term.c_lflag = 0; // turn off local processing
term.c_oflag = 0; // turn off output processing
cfsetispeed( &term, B9600 );
cfsetospeed( &term, B9600 );
if (tcsetattr( hSerPort, TCSANOW, &term )) {
SerCrash("Bad parameters for port",portname);
iSerOK = FALSE;
}
if (!iSerOK) SerCrash("Bad parameters for port",portname);
//
// Disable Windows' timeouts; we keep track of our own
//
// COMMTIMEOUTS t = {MAXDWORD,0,0,0,0};
// SetCommTimeouts(hSerPort,&t);
}
void SerClose()
// Closes the serial port.
{
iSerOK != close(hSerPort);
if (!iSerOK) SerCrash("Problem closing serial port","");
}
void SerPut(char* data)
// Transmits a line followed by CR and LF.
// Caution! Will wait forever, without registering an error,
// if handshaking signals tell it not to transmit.
{
DWORD nBytes;
iSerOK = nBytes=write(hSerPort,(const void *)data,strlen(data));
iSerOK &= nBytes=write(hSerPort,"\r\n",2);
if (!iSerOK) SerCrash("Problem writing to serial port","");
}
void SerGetChar(char* c, int* success)
// Receives a character from the serial port,
// or times out after 10 seconds.
// success = 0 if timeout, 1 if successful
{
time_t finish;
finish = time(NULL) + 10;
*success = 0;
DWORD nBytes = 0;
while ((*success == 0) && (time(NULL) < finish)) {
nBytes=read(hSerPort,c,(size_t)1);
*success = nBytes;
}
if (*success == 0)
SerCrash("Timed out waiting for serial input","");
}
void SerGet(char* buf, int bufsize)
// Inputs a line from the serial port, stopping at
// end of line, carriage return, timeout, or buffer full.
{
int bufpos = 0;
buf[bufpos] = 0; // initialize empty string
int bufposmax = bufsize-1; // maximum subscript
char c = 0;
int success = 0;
//
// Eat any Return or Line Feed characters
// left over from end of previous line
//
do { SerGetChar(&c,&success); }
while ((success == 1) && (c <= 31));
//
// We have now read the first character or timed out.
// Read characters until any termination condition is met.
//
while (1) {
if (success == 0) return; // timeout
if (c == 13) return; // carriage return
if (c == 10) return; // line feed
if (bufpos >= bufposmax) return; // buffer full
buf[bufpos] = c;
bufpos++;
buf[bufpos] = 0; // guarantee validly terminated string
SerGetChar(&c,&success);
}
}
void SerGetNum(double* x)
// Reads a floating-point number from the serial port.
{
char buf[20];
SerGet(buf,sizeof(buf));
iSerOK = sscanf(buf,"%lf",x); // "%lf" = "long float" = double
if (iSerOK < 1) {
SerCrash("Problem converting string to number",buf);
*x = 0.0;
}
}
// Sample main program to conduct dialogue
// with Agilent 54645D oscilloscope,
// 9600 baud, DTR handshaking
int main()
{
char b[20];
double x;
// Sample dialogue for Agilent 64645D oscilloscope
SerOpen("/dev/ttyUSB0","RTS"); // note RTS handshaking
SerPut("*RST");
SerPut("*CLS");
SerPut(":SYSTEM:DSP 'Communicating with computer'");
SerPut(":AUTOSCALE");
SerPut(":MEASURE:VRMS? ANALOG1");
SerGetNum(&x);
printf( "Channel 1 RMS voltage (as number) = %f\n", x );
// cout << "Channel 1 RMS voltage (as number) = " << x << "\n";
SerPut(":MEASURE:VPP? ANALOG2");
SerGet(b,sizeof(b));
printf( "Channel 2 P-P voltage (as string) = %s\n", b );
// cout << "Channel 2 P-P voltage (as string) = " << b << "\n";
/*
// Sample dialogue for Agilent 34401A multimeter
SerOpen("COM1","DTR"); // note DTR handshaking
SerPut(":SYST:REM");
SerPut("*RST");
SerPut("*CLS");
SerPut(":DISP:TEXT 'OK'");
SerPut(":MEASURE:VOLT:DC?");
SerGetNum(&x);
printf( "Voltage (as number) = %d\n", x );
// cout << "Voltage (as number) = " << x << "\n";
SerPut(":MEASURE:VOLT:DC?");
SerGet(b,sizeof(b));
printf( "Voltage (as string) = %s\n", b );
// cout << "Voltage (as string) = " << b << "\n";
*/
// Say goodbye
printf( "Press Enter...");
scanf("\r");
SerClose();
return 0;
}