// // Callback example for the Crandun Technologies CTI-AR200 // software library. // Copyright (c) 2001, Crandun Technologies Inc. // // This sample program demonstrates how to use a callback function // to retrieve sample data from the library, and write that data // to a disk file // // Note that this program must be compiled and linked with the // Visual C++ Multi-Threaded libraries, since the callback is called // in a different thread from the main program. // #include "CTI_AR200.h" // required header #include // needed for cout #include // needed for data file functions #include // needed for Sleep function using namespace std; // we use cout and cerr using namespace Crandun; // all library symbols are in this namespace // A helper macro for checking return codes #define CHK_RETURN_VALUE(retCode, fnName) \ if (retCode < 0) { \ cerr << "ERROR: " #fnName " returned error code: " << rc << endl; \ { char errMsg[300]; if (my_Sensor.getIsError()) { \ my_Sensor.getErrorMessage(errMsg, sizeof(errMsg)); \ cerr << "Library error msg is: " << errMsg << endl; \ } \ }\ my_Sensor.setCommClosed(); \ cerr << "Please enter any character to exit: "; \ cin >> c; \ return (-1); \ } // The data file and the Sensor instance must be global, // so that both the callback and main have access. ofstream my_DataFile; CTI_AR200 * my_Sensor; /* This is the callback function that will be called by the library */ long myCallback(const float * pD1, const long nPts1, const float * pD2, const long nPts2) { long i,j; printf("In callback, reading %d samples. Writing to file\n", nPts1+nPts2); for (i = 0, j = 0; i < nPts1; i++, j++, pD1++) { cout << "Range " << j << " is " << *pD1 << " mm" << endl; my_DataFile << *pD1 << "\n"; } /* read the samples from the second data pointer, if any */ for (i = 0; i < nPts2; i++, j++, pD2++) { cout << "Range " << j << " is " << *pD2 << " mm" << endl; my_DataFile << *pD2 << endl; } /* return non-zero to tell lib to remove samples from its buffer */ return 1; } int main() { const char * outFileName = "C:\\CallbackTest.out"; char c; long rc; float fullScaleSpan; CTI_AR200 my_Sensor; cout << "Crandun Technologies CTI-AR200 Library Callback example." << endl; cout << "Enter the Full Scale Span of the AR200 sensor you are using (e.g. 25): "; cin >> fullScaleSpan; cout << "Opening the serial port..." << endl; rc = my_Sensor.setCommOpen("COM1", 9600, fullScaleSpan); if (rc != CTI_SUCCESS) { cerr << "ERROR: setCommOpen returned error: " << rc << endl; return -1; } cout << "Successfully opened the serial port!" << endl; cout << "Opening output data file " << outFileName << endl; my_DataFile.open(outFileName); if (!my_DataFile.is_open()) { cerr << "Could not open the output data file " << outFileName << ". Aborting!" << endl; my_Sensor.setCommClosed(); return -1; } cout << "Testing callback function " << endl; // set the function "myCallback" as the callback function rc = my_Sensor.setCallbackFunction(myCallback); CHK_RETURN_VALUE(rc, setCallbackFunction); // Tell library to call the callback when 5 samples are available // Sensor is at factory default of 5 samples/sec // so this should result in the callback being called 3 times // during the 3 second period that the main thread is sleeping rc = my_Sensor.setCallbackThreshold(5); CHK_RETURN_VALUE(rc, setCallbackThreshold); // sleep for 3 seconds. cout << "Main program is sleeping for 3 seconds..." << endl; Sleep(3000); cout << "Main program finished sleeping - closing the serial port." << endl; // close the sensor serial port - this also ensures that the callback is done rc = my_Sensor.setCommClosed(); CHK_RETURN_VALUE(rc, setCommClosed); my_DataFile.close(); // close the data file cout << "Please enter any character to exit: "; cin >> c; return 0; }