// 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; }