AxsunOCTControl_LW 2.0.0
A light-weight & cross-platform alternative to the .NET-based AxsunOCTControl.dll.
Loading...
Searching...
No Matches
AxsunOCTControl_LW_ExampleConsoleApp.cpp

This is example source code showing how to use the AxsunOCTControl_LW API in a C++ client application, including context construction/destruction (axOpen.. & axClose..), callback function registration, opening of communication interfaces, and sending a variety of commands to Laser and DAQ devices with user interaction. Several additional helper functions are also provided for conversion from char* or enums into std::string for console output.

// AxsunOCTControl_LW_ExampleConsoleApp.cpp
// Copyright 2023 Excelitas Technologies
#include <iostream> // for std::cin & std::cout
#include <string>
#include <vector>
// Get error message as a C++ std::string (convert from char* that C interface uses)
std::string GetErrorStringCpp(AxErr e) {
char errormsg[256];
axGetErrorExplained(e, errormsg);
return errormsg; // calls std::string(char*) constructor automatically based on the function return type
}
// Function which counts the connected devices and then prints some details about them to std::cout.
// It is safe to call these library functions from the callback function (executed in a background thread).
void PrintConnectedDevices() {
auto count = axCountConnectedDevices(); // how many devices are connected now?
if (count > 0) { // if any devices are connected,
AxErr retval;
for (uint32_t i = 0; i < count; ++i) { // print out their connection type, device type, serial number, and firmware version
AxDeviceInfo device_info{};
retval = axGetDeviceInfo(&device_info, i);
std::cout << "\nCONNECTED DEVICE index: " << i << ", handle: " << device_info.handle << '\n';
std::cout << AxDevTypeString(device_info.device_type) << " (" << AxConnectTypeString(device_info.connection_type) << ")\tFW: v" << device_info.firmware_version << "\tSN: " << device_info.serial_number << "\t";
if (device_info.device_type == AxDevType::EDAQ || device_info.device_type == AxDevType::AZMYTH_LASER || device_info.device_type == AxDevType::CLDAQ) {
std::cout << "\tFPGA: v" << device_info.FPGA_version;
}
std::cout << '\n';
}
std::cout << '\n';
}
else
std::cout << "No devices connected.\n";
}
void PrintDevice(const AxDeviceInfo& info) {
std::cout << AxDevTypeString(info.device_type) << " (" << AxConnectTypeString(info.connection_type) << ")\tFW: v" << info.firmware_version << "\tSN: " << info.serial_number << "\t";
if (info.device_type == AxDevType::EDAQ || info.device_type == AxDevType::AZMYTH_LASER || info.device_type == AxDevType::CLDAQ) {
std::cout << "\tFPGA: v" << info.FPGA_version;
}
}
// Callback functions are useful for maintaining a list of the connected devices at the client application level.
// Function which is executed via callback when a device connects or disconnects:
void ConnectedCallbackFunc(void* userData) {
try {
PrintConnectedDevices();
// NOTE: calling this print function from the callback is not a thread-safe use of std::cout.
// It is convienient for example code, but production code should avoid this approach.
}
catch (AxErr e) { std::cout << "***** ERROR: " << GetErrorStringCpp(e) << " in callback function.\n"; }
}
// Function which is executed via callback only when a new device connects:
void ConnectOnlyCallbackFunc(AxDeviceInfo info, int32_t index, void* userData) {
std::cout << "\nCONNECTED DEVICE index: " << index << ", handle: " << info.handle << '\n';
PrintDevice(info);
std::cout << '\n';
}
// Function which is executed via callback only when a previously-connected device disconnects:
void DisconnectOnlyCallbackFunc(AxDeviceInfo info, int32_t index, void* userData) {
std::cout << "\nDISCONNECTED handle: " << info.handle << '\n';
PrintDevice(info);
std::cout << '\n';
}
// RAII class to call axCloseAxsunOCTControl function automatically in its destructor
class AOCTLW {
public:
~AOCTLW() {
}
};
int main()
{
try {
AOCTLW close_scope;
AxErr retval{AxErr::NO_AxERROR};
// report the current library version and details
std::cout << "Using AxsunOCTControl_LW library version: " << axLWLibVersion() << " (" << axLWBuildDateTime() << ", " << ((axGetLWBuildCfg() & 1) ? "release)" : "debug)") << "\n";
// Callback registration functions tell library to execute a handler when a device connect or disconnect event happens; userData pointer also available in the callback if needed.
/*
// uncomment this block to use a single callback which responds to both connect and disconnect events
retval = axRegisterConnectCallback(ConnectedCallbackFunc, nullptr);
if (retval != AxErr::NO_AxERROR) throw retval;
*/
retval = axRegCallbackConnectOnly(ConnectOnlyCallbackFunc, nullptr);
if (retval != AxErr::NO_AxERROR) throw retval;
retval = axRegCallbackDisconnectOnly(DisconnectOnlyCallbackFunc, nullptr);
if (retval != AxErr::NO_AxERROR) throw retval;
// opens the Ethernet network interface (for Ethernet DAQ connectivity only)
if (retval != AxErr::NO_AxERROR) throw retval;
// opens the USB interface (for Laser or DAQ connectivity) and get libusb version
retval = axUSBInterfaceOpen(1);
if (retval != AxErr::NO_AxERROR) throw retval;
uint32_t major, minor, patch, build;
retval = axGetLibusbVersion(&major, &minor, &patch, &build);
if (retval != AxErr::NO_AxERROR) throw retval;
std::cout << "Using libusb library version: " << major << "." << minor << "." << patch << "." << build << "\n";
/*
// un-comment this block to open a RS-232 serial interface
retval = axSerialInterfaceOpen(true, "/dev/tty.usbserial-A9015L62"); // example for Linux or macOS
retval = axSerialInterfaceOpen(true, "COM8"); // example for Windows
if (retval != AxErr::NO_AxERROR) throw retval;
*/
// 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) {
std::cout << "Type a character and press enter to execute a command ('?' for command list).\n>> ";
std::cin >> which_command;
try {
switch (which_command) {
case 'd':
case 'D':
std::cout << "axSetLaserEmission(...) for LASER OFF\n";
retval = axSetLaserEmission(0, 0);
if (retval != AxErr::NO_AxERROR) throw retval;
break;
case 'e':
case 'E':
std::cout << "axSetLaserEmission(...) for LASER ON\n";
retval = axSetLaserEmission(1, 0);
if (retval != AxErr::NO_AxERROR) throw retval;
break;
case 'f':
case 'F':
{
std::cout << "axGetFPGARegisterRange(0..63)\n";
auto regvals = std::vector<uint16_t>(64);
retval = axGetFPGARegisterRange(0, 63, regvals.data(), regvals.size() * sizeof(uint16_t), 0);
if (retval != AxErr::NO_AxERROR) throw retval;
for (auto i = 0; i < 64; ++i) {
std::cout << "Reg " << i << " =\t" << std::hex << regvals[i] << std::dec << "\n";
}
}
break;
case 'h':
case 'H':
std::cout << "axHomeVDL(...)\n";
retval = axHomeVDL(0);
if (retval != AxErr::NO_AxERROR) throw retval;
break;
case 'i':
case 'I':
PrintConnectedDevices();
break;
case 'l':
case 'L':
std::cout << "axImagingCntrlEthernet(...) for LIVE IMAGING\n";
retval = axImagingCntrlEthernet(-1, 0);
if (retval != AxErr::NO_AxERROR) throw retval;
break;
case 'o':
case 'O':
std::cout << "axImagingCntrlEthernet(...) for IDLE\n";
retval = axImagingCntrlEthernet(0, 0);
if (retval != AxErr::NO_AxERROR) throw retval;
break;
case 'b':
case 'B':
std::cout << "axImagingCntrlEthernet(...) for BURST RECORD\n";
retval = axImagingCntrlEthernet(100, 0);
if (retval != AxErr::NO_AxERROR) throw retval;
break;
case 't':
case 'T':
std::cout << "axTECState(...) ";
AxTECState state;
retval = axGetTECState(&state, 1, 0);
if (retval != AxErr::NO_AxERROR) throw retval;
std::cout << "State of Primary TEC: " << static_cast<int32_t>(state) << "\n";
break;
case 'a':
case 'A':
std::cout << "axSetFPGADataArray(...) \n";
{
std::vector<uint16_t> pattern(1024, 500);
retval = axSetFPGADataArray(37, pattern.data(), pattern.size(), 0);
if (retval != AxErr::NO_AxERROR) throw retval;
}
break;
case 'c':
case 'C':
std::cout << "axSetFPGADataArray(...) \n";
{
std::vector<uint16_t> pattern(1024, 0);
retval = axSetFPGADataArray(37, pattern.data(), pattern.size(), 0);
if (retval != AxErr::NO_AxERROR) throw retval;
}
break;
case 'm':
case 'M':
std::cout << "axSetPipelineMode(...) \n";
retval = axSetPipelineMode(AxPipelineMode::LOG, AxChannelMode::INTERLEAVE_CHANNELS, 0);
if (retval != AxErr::NO_AxERROR) throw retval;
break;
case 'U':
std::cout << "axUSBInterfaceOpen(true) \n";
retval = axUSBInterfaceOpen(1);
if (retval != AxErr::NO_AxERROR) throw retval;
break;
case 'u':
std::cout << "axUSBInterfaceOpen(false) \n";
retval = axUSBInterfaceOpen(0);
if (retval != AxErr::NO_AxERROR) throw retval;
break;
case 'N':
std::cout << "axNetworkInterfaceOpen(true) \n";
if (retval != AxErr::NO_AxERROR) throw retval;
break;
case 'n':
std::cout << "axNetworkInterfaceOpen(false) \n";
if (retval != AxErr::NO_AxERROR) throw retval;
break;
case '?':
std::cout << "\n***** COMMAND LIST *****\n";
std::cout << "U\tI'FACE: axUSBInterfaceOpen(true); // Open USB Interface\n";
std::cout << "u\tI'FACE: axUSBInterfaceOpen(false); // Close USB Interface\n";
std::cout << "N\tI'FACE: axNetworkInterfaceOpen(true); // Open TCP Interface\n";
std::cout << "n\tI'FACE: axNetworkInterfaceOpen(false); // Close TCP Interface\n";
std::cout << "D\tLASER: axSetLaserEmission(false); // Laser emission ENABLED\n";
std::cout << "E\tLASER: axSetLaserEmission(true); // Laser emission DISABLED\n";
std::cout << "H\tLASER: axHomeVDL();\n";
std::cout << "T\tLASER: axGetTECState();\n";
std::cout << "F\tDAQ: axGetFPGARegisterRange(...);\n";
std::cout << "L\tDAQ: axImagingCntrlEthernet(-1); // Imaging ON - Live\n";
std::cout << "O\tDAQ: axImagingCntrlEthernet(0); // Imaging OFF - Idle\n";
std::cout << "B\tDAQ: axImagingCntrlEthernet(100); // Burst Record 100 Images\n";
std::cout << "A\tDAQ: axSetFPGADataArray(...); // Load Test Pattern\n";
std::cout << "C\tDAQ: axSetFPGADataArray(...); // Clear Test Pattern\n";
std::cout << "M\tDAQ: axSetPipelineMode(...); // LOG, INTERLEAVED\n";
std::cout << "\nI\tGet info on connected devices.\n";
std::cout << "?\tList command options.\n";
std::cout << "Q\tQuit this program.\n\n";
break;
case 'q':
case 'Q':
std::cout << "Quitting.\n";
running = false;
break;
default:
std::cout << "Command not recognized. Enter '?' to list options.\n";
} // switch
} // try
catch (const AxErr& e) {
std::cout << "***** ERROR: " << GetErrorStringCpp(e) << "\n\n";
} // catch
} // while loop
} // try
catch (const AxErr& e) {
std::cout << "***** ERROR: " << static_cast<int32_t>(e) << " " << GetErrorStringCpp(e) << " Program terminating.\n";
}
catch (...) {
std::cout << "***** UNKNOWN ERROR. Program terminating.\n";
}
}
AxErr
Error codes returned from AxsunOCTCapture or AxsunOCTControl_LW functions. Use axGetErrorString() in ...
Definition AxsunCommonEnums.h:40
This header file defines the usage of the AxsunOCTControl_LW "lightweight" library in a C or C++ appl...
AxTECState
Laser TEC states.
Definition AxsunOCTControl_LW_C.h:119
const char * axLWBuildDateTime()
Get a string describing the time and date that the AxsunOCTControl_LW library was built.
AxErr __cdecl axRegCallbackDisconnectOnly(AxCallbackConnectOrDisconnect_t callback_function, void *userData)
Registers a callback function to be executed following a device disconnection event.
AxErr __cdecl axRegCallbackConnectOnly(AxCallbackConnectOrDisconnect_t callback_function, void *userData)
Registers a callback function to be executed following a device connection event.
AxErr __cdecl axSetFPGADataArray(uint32_t regnum, const uint16_t *data_array, uint32_t number_of_words, uint32_t which_DAQ)
Sets (i.e. writes) a FPGA register with an array of multiple values.
const char * axLWLibVersion()
Get a string describing the AxsunOCTControl_LW library version.
AxErr __cdecl axGetFPGARegisterRange(const uint32_t start_regnum, const uint32_t end_regnum, uint16_t *regvals, const uint32_t bytes_allocated, uint32_t which_DAQ)
Gets (i.e. reads) current values in a range of FPGA registers.
uint32_t __cdecl axCountConnectedDevices()
Counts the number of devices successfully connected and enumerated by AxsunOCTControl_LW.
void __cdecl axGetErrorExplained(AxErr errornum, char *error_string)
Gets a string which explains an error code in a more verbose fashion.
AxErr __cdecl axNetworkInterfaceOpen(uint32_t interface_status)
Opens, resets, or closes the Ethernet network interface.
AxErr __cdecl axCloseAxsunOCTControl()
Closes an AxsunOCTControl_LW session previously opened with axOpenAxsunOCTControl().
AxErr __cdecl axHomeVDL(uint32_t which_laser)
Starts the VDL home operation.
AxErr __cdecl axSetLaserEmission(uint32_t emission_state, uint32_t which_laser)
Enables or disables swept laser emission.
int32_t __cdecl axGetLWBuildCfg()
Get the build configuration of the AxsunOCTControl_LW library.
AxErr __cdecl axUSBInterfaceOpen(uint32_t interface_status)
Opens, resets, or closes the USB interface.
AxErr __cdecl axGetTECState(AxTECState *TEC_state, uint32_t which_TEC, uint32_t which_laser)
Gets the current state of a Laser Thermo-Electric Cooler (TEC).
AxErr __cdecl axGetDeviceInfo(AxDeviceInfo *device_info, uint32_t which_device)
Gets info about a connected device.
AxErr __cdecl axImagingCntrlEthernet(int16_t number_of_images, uint32_t which_DAQ)
Control the DAQ operational mode (Live Imaging, Burst Recording, or Imaging Off) when using the Ether...
AxErr __cdecl axGetLibusbVersion(uint32_t *major, uint32_t *minor, uint32_t *patch, uint32_t *build)
Gets the version of the libusb library loaded with axUSBInterfaceOpen().
AxErr __cdecl axSetPipelineMode(AxPipelineMode pipeline_mode, AxChannelMode polarization_mode, uint32_t which_DAQ)
Select the DAQ's pipeline mode (i.e. bypass mode) and polarization channel configuration.
Structure for device information available in connect or disconnect callback functions.
Definition AxsunOCTControl_LW_C.h:159
char FPGA_version[16]
Definition AxsunOCTControl_LW_C.h:164
char firmware_version[16]
Definition AxsunOCTControl_LW_C.h:163
char serial_number[40]
Definition AxsunOCTControl_LW_C.h:162
AxDeviceHandle handle
Definition AxsunOCTControl_LW_C.h:165
AxDevType device_type
Definition AxsunOCTControl_LW_C.h:160
AxConnectionType connection_type
Definition AxsunOCTControl_LW_C.h:161