AxsunOCTCapture  3.0.0.0
Captures and buffers streamed imaged data from the Axsun Ethernet/PCIe DAQ and displays or retrieves images to a client application on request.
axScanCmd_Test.cpp

This is example source code showing how to use the AxsunOCTCapture scanner command API in a C++ client application.

// axScanCmd_Test.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <iostream>
#include <string>
#include <chrono>
using namespace std::chrono_literals;
using std::cout;
using std::cin;
using std::string;
// Get error message as a C++ std::string (convert from char* that ANSI C interface uses)
string GetErrorStringCpp(AxErr e) {
char errormsg[512];
axGetErrorString(e, errormsg);
return errormsg; // calls std::string(char*) constructor automatically based on the function return type
}
// Wrap the DESTROY_SCAN command in a C++ class so that it will be called automatically
// in the destructor when the object goes out of scope (we won't have to remember to do it explicitly)
class ScannerSession {
public:
ScannerSession() {}
~ScannerSession() {
axScanCmd(DESTROY_SCAN, 0, NULL, NULL, NULL);
}
};
// function to call when scanner is connected or disconnected
void DeviceConnectedCallback(void * user_data) {
int32_t devices = static_cast<int32_t>(axScanCmd(COUNT_DEVICES, 0, NULL, NULL, NULL));
if (devices < 0) throw static_cast<AxErr>(devices);
cout << "Total devices connected: " << devices << "\n";
for (int index = 0; index < devices; index++) {
int32_t serialno = static_cast<int32_t>(axScanCmd(GET_DEVICE_SERIALNO, index, NULL, NULL, NULL));
if (serialno > 0)
cout << std::hex << serialno << " is device index " << std::dec << index << "\n";
else throw static_cast<AxErr>(devices);
}
cout << "\n";
}
int main()
{
try {
cout << "Welcome to the AxsunOCTCapture DAQmx Scanner Control example application.\n";
AxErr retval{ AxErr::NO_AxERROR };
ScannerSession mySession; // construct ScannerSession class instance
axRegisterScannerConnectCallback(DeviceConnectedCallback, NULL);
// declare some variables for our user interaction loop
bool running = true;
char which_command;
// prompt the user for a character, interpret this as a command, and then execute it if recognized
// examples are given for several common device functions; additional functions in the library can be added following the same pattern
while (running) {
cout << "Type a character and press enter to execute a command.\n>> ";
cin >> which_command;
try {
switch (which_command) {
case '?':
cout << "\n***** COMMAND LIST *****\n";
cout << "L\tList connected device serial numbers using axScanCmd(GET_DEVICE_SERIALNO, ..);\n";
cout << "D\tMake device at index 1 active using axScanCmd(SELECT_DEVICE, 1, ..);\n";
cout << "P\tSet scan parameters using axScanCmd(set_rect_pattern, ..);\n";
cout << "1\tStart continuous 1D linear scanning using axScanCmd(CONTINUOUS_LINE_SCAN, ..);\n";
cout << "2\tStart continuous 2D raster scanning using axScanCmd(CONTINUOUS_RASTER_SCAN, ..);\n";
cout << "S\tStop scanning using axScanCmd(STOP_AT_POSITION, ..);\n";
cout << "I\tSet internal sample clock using axScanCmd(SET_SAMPLE_CLOCK, 1, ..);\n";
cout << "E\tSet external sample clock using axScanCmd(SET_SAMPLE_CLOCK, 0, ..);\n";
cout << "B\tPrepare for burst raster scan using axScanCmd(SETUP_BURST_RASTER, ..);\n";
cout << "R\tStart burst raster scan using axScanCmd(START_BURST_RASTER, ..);\n";
cout << "M\tSet maximum analog output voltage to 1.0V using axScanCmd(SET_MAX_VOLTAGE, 1.0, ..);\n";
cout << "?\tList command options.\n";
cout << "Q\tQuit this program.\n\n";
break;
case '1':
retval = axScanCmd(CONTINUOUS_LINE_SCAN, 0, NULL, NULL, NULL); if (retval) throw retval;
cout << "Linear scan started.\n";
break;
case '2':
retval = axScanCmd(CONTINUOUS_RASTER_SCAN, 0, NULL, NULL, NULL); if (retval) throw retval;
cout << "Raster scan started.\n";
break;
case 's':
case 'S':
{
scan_params_t scan_pattern{ 0 };
scan_pattern.X_shift = 1.0; // uses X_shift and Y_shift to define the stop position
scan_pattern.Y_shift = -1.0;
retval = axScanCmd(STOP_AT_POSITION, 0, &scan_pattern, NULL, NULL); if (retval) throw retval;
cout << "Scan stopped at (" << scan_pattern.X_shift << "," << scan_pattern.Y_shift << ").\n";
break;
}
case 'p':
case 'P':
{
scan_params_t scan_pattern{ 0 };
scan_pattern.X_increments = 2000;
scan_pattern.Y_increments = 2000;
scan_pattern.X_range = 3.0;
scan_pattern.Y_range = 3.0;
retval = axScanCmd(SET_RECT_PATTERN, 0, &scan_pattern, NULL, NULL); if (retval) throw retval;
cout << "Scan parameters set.\n";
break;
} // scope limit for scan_pattern
case 'l':
case 'L':
{
DeviceConnectedCallback(NULL); // just do the same thing that the callback function does: list the connected devices
break;
} // scope limit for devices
case 'd':
case 'D':
retval = axScanCmd(SELECT_DEVICE, 1, NULL, NULL, NULL); if (retval) throw retval;
cout << "Selected active device: " << std::hex << static_cast<int32_t>(axScanCmd(GET_DEVICE_SERIALNO, 0, NULL, NULL, NULL)) << "\n";
break;
case 'e':
case 'E':
retval = axScanCmd(SET_SAMPLE_CLOCK, 0, NULL, NULL, NULL); if (retval) throw retval;
cout << "Selected external sample clock. \n";
break;
case 'i':
case 'I':
retval = axScanCmd(SET_SAMPLE_CLOCK, 1, NULL, NULL, NULL); if (retval) throw retval;
cout << "Selected internal 100 kHz sample clock. \n";
break;
case 'm':
case 'M':
retval = axScanCmd(SET_MAX_VOLTAGE, 1.0, NULL, NULL, NULL); if (retval) throw retval;
cout << "Maxiumum analog output voltage has been set. \n";
break;
case 'b':
case 'B':
retval = axScanCmd(SETUP_BURST_RASTER, 0, NULL, NULL, NULL); if (retval) throw retval;
cout << "Burst raster setup and waiting for START_BURST_RASTER command. \n";
break;
case 'r':
case 'R':
{
retval = axScanCmd(START_BURST_RASTER, 0, NULL, NULL, NULL); if (retval) throw retval;
cout << "Burst raster started... \n";
retval = axScanCmd(WAIT_BURST, 10, NULL, NULL, NULL); if (retval) throw retval; // wait for 10 seconds and then timeout
cout << "Burst raster completed.\n";
break;
}
case 'q':
case 'Q':
cout << "Quitting.\n";
running = false;
break;
default:
cout << "Command not recognized. Enter '?' to list options.\n";
} // switch
} // try
catch (AxErr& e) {
cout << "***** ERROR: " << GetErrorStringCpp(e) << "\n\n";
} // catch
}
} // try (NOTE: myInstance goes out of scope here and its destructor calls DESTROY_SCAN to release resources)
catch (AxErr& e) {
cout << "***** ERROR: " << GetErrorStringCpp(e) << " Program terminating.\n";
}
catch (...) {
cout << "***** UNKNOWN ERROR. Program terminating.\n";
}
}