Automation API
Active-Pro Automation API
The Active-Pro Software Application has a built in interface that allows you to control the application through your own program. This Application Programming Interface (API) defines how an external program can control the Active-Pro Application. It allows control of all features of the Active-Pro through simple string commands over a TCP Socket. We have also made a simple command line app that allows you to send commands and receive responses without writing any code.
If you are a coder, the Active-Pro Automation API uses TCP sockets to allow your custom developed application to send Commands and receive Responses with the Active-Pro Application that is attached to the Active-Pro hardware pod. Your application can be written in any language that you are familiar with. The examples that we show below are using C language and the QT library of routines, but many languages have similar functionality which you can port easily.
If you want to simply call a command line program to send a command to the Active-Pro Application, jump to the section below.
This API is available in software version 3.8 and above.
Commands and Responses
Below is the table of Commands and possible Responses. All Commands and Responses must have only one newline character at the end (‘\n’ which is hex byte 0x0A). Commands are not case sensitive. Each line below shows command -> responses.
Ping Active-Pro Application
This command checks that the TCP Socket connection to the Active-Pro Application is working correctly.
Hello -> HELLO
Connection to Active-Pro Device
This command determines if the Active-Pro hardware device is connected and the Active-Pro Application can communicate with it.
isConnected -> YES/NO
Capture Control
These commands start and stop a capture using the current settings. They also return the current logic levels and analog voltages at the inputs. To set the capture settings you would like, make a configuration file for those settings and execute the OpenConfiguration command below to load them.
StartCapture -> OK/NoActiveDevice/AlreadyStarted
StopCapture -> OK/NoActiveDevice/NotStarted
isCapturing -> Yes/No
GetCaptureSize -> number of bytes captured
GetCaptureTime -> How long the capture is in seconds
GetLogic -> 8-bits of current logic levels
GetCH1 -> voltage at CH1
GetCH2 -> voltage at CH2
GetCH3 -> voltage at CH3
Output Settings
These commands set the states of the output analog and digital outputs.
SetD0Mode Param -> OK Param: 0=Trisate, 1=0V, 2=3.3V, 3=PWM
SetD0PWM Percent -> OK
SetD1Mode Param -> OK Param: 0=Trisate, 1=0V, 2=3.3V, 3=PWM
SetD1PWM Percent -> OK
SetA0Mode Param -> OK Param: 0=Trisate, 1=0V, 2=1V, 3=2V, 4=3V, 5=3.3V, 6=DC
SetA0DCLEVEL -> OK
SetA1Mode Param -> OK Param: 0=Trisate, 1=0V, 2=1V, 3=2V, 4=3V, 5=3.3V, 6=DC, 7=RAMP, 8=SINE, 9=SQUARE, 10-TRIANGLE
SetA1DCLEVEL Volts -> OK
SetA1MINIMUM Volts -> OK
SetA1MAXIMUM Volts -> OK
SetA1Steps Steps -> OK
Notes
These commands let you add text to the Notes tab that is saved with the trace data.
ClearNote -> OK
AppendNote string -> OK
View and Cursor Positions
These commands place the cursors on the captured trace, zoom to specific parts of the trace, and opens and closes the tab windows on the right.
SetCursorCurrent time -> OK
SetCursorX1 time -> OK
SetCursorX2 time -> OK
ZoomAll -> OK
ZoomFrom start end -> OK
Search string -> timefound/NOTFOUND
ShowInputs -> OK
ShowOutputs -> OK
ShowList -> OK
ShowSettings -> OK
ShowNotes -> OK
CloseTabs -> OK
File Operations
These commands clear out the settings for a new capture, open and save capture and configuration files, exports the data between the cursors and saves the current screenshot.
NewCapture -> OK
OpenCapture filename -> OK/Error
SaveCapture filename -> OK/Error
SaveBetweenCursors filename -> OK/Error
OpenConfiguration filename -> OK/Error
SaveConfiguration filename -> OK/Error
ExportBetweenCursors filename -> OK/Error
SaveScreenshot filename -> OK/Error
Exit -> OK
Example Usage
Below is a sample application written in C using QT that shows how to connect to the TCP Socket (localhost::37800) and sends all of the commands and receives the responses for each.
Source Code Output
The output of this program looks like this:
Command: "Hello\n" Response: "HELLO\n" Command: "isConnected\n" Response: "YES\n" Command: "ShowInputs\n" Response: "OK\n" Command: "ShowList\n" Response: "OK\n" Command: "ShowSettings\n" Response: "OK\n" Command: "ShowNotes\n" Response: "OK\n" Command: "ShowOutputs\n" Response: "OK\n" Command: "CloseTabs\n" Response: "OK\n" Command: "SetD0Mode 0\n" Response: "OK\n" Command: "SetD0Mode 1\n" Response: "OK\n" Command: "SetD0Mode 2\n" Response: "OK\n" Command: "SetD0Mode 3\n" Response: "OK\n" Command: "SetD0PWM 25\n" Response: "OK\n" Command: "SetD0PWM 75\n" Response: "OK\n" Command: "SetD1Mode 0\n" Response: "OK\n" Command: "SetD1Mode 1\n" Response: "OK\n" Command: "SetD1Mode 2\n" Response: "OK\n" Command: "SetD1Mode 3\n" Response: "OK\n" Command: "SetD1PWM 25\n" Response: "OK\n" Command: "SetD1PWM 75\n" Response: "OK\n" Command: "SetA0Mode 0\n" Response: "OK\n" Command: "SetA0Mode 1\n" Response: "OK\n" Command: "SetA0Mode 2\n" Response: "OK\n" Command: "SetA0Mode 3\n" Response: "OK\n" Command: "SetA0Mode 4\n" Response: "OK\n" Command: "SetA0Mode 5\n" Response: "OK\n" Command: "SetA0Mode 6\n" Response: "OK\n" Command: "SetA0DCLEVEL 0.5\n" Response: "OK\n" Command: "SetA0DCLEVEL 1.5\n" Response: "OK\n" Command: "SetA0DCLEVEL 2.5\n" Response: "OK\n" Command: "SetA1Mode 1\n" Response: "OK\n" Command: "SetA1Mode 2\n" Response: "OK\n" Command: "SetA1Mode 3\n" Response: "OK\n" Command: "SetA1Mode 4\n" Response: "OK\n" Command: "SetA1Mode 6\n" Response: "OK\n" Command: "SetA1DCLEVEL 0.5\n" Response: "OK\n" Command: "SetA1DCLEVEL 1.5\n" Response: "OK\n" Command: "SetA1Mode 7\n" Response: "OK\n" Command: "SetA1MINIMUM 0.5\n" Response: "OK\n" Command: "SetA1MAXIMUM 2.5\n" Response: "OK\n" Command: "SetA1Mode 8\n" Response: "OK\n" Command: "SetA1Mode 9\n" Response: "OK\n" Command: "SetA1Mode 10\n" Response: "OK\n" Command: "SetA1Steps 4000\n" Response: "OK\n" Command: "SetA1Steps 500\n" Response: "OK\n" Command: "isCapturing\n" Response: "NO\n" Command: "STARTCAPTURE\n" Response: "OK\n" Command: "GetLogic\n" Response: "0\n" Command: "GetCH1\n" Response: "0.862284\n" Command: "GetCH2\n" Response: "0.863042\n" Command: "GetCH3\n" Response: "-0.0238061\n" Command: "STOPCAPTURE\n" Response: "OK\n" Command: "GetCaptureSize\n" Response: "1085440\n" Command: "GetCaptureTime\n" Response: "0.201007\n" Command: "ShowNotes\n" Response: "OK\n" Command: "ClearNote\n" Response: "OK\n" Command: "AppendNote Sent to the Active-Pro Application.\n" Response: "OK\n" Command: "AppendNote \n" Response: "OK\n" Command: "AppendNote And here is more data.\n" Response: "OK\n" Command: "ZOOMALL\n" Response: "OK\n" Command: "ZoomFrom 1.0 2.0\n" Response: "OK\n" Command: "SetCursorCurrent 1\n" Response: "OK\n" Command: "Search mon\n" Response: "NOTFOUND\n" Command: "Search booga\n" Response: "NOTFOUND\n" Command: "SetCursorCurrent 3\n" Response: "OK\n" Command: "SetCursorX1 0\n" Response: "OK\n" Command: "SetCursorX2 5.0\n" Response: "OK\n" Command: "ExportBetweenCursors C:\\APITesting\\test.csv\n" Response: "OK\n" Command: "SaveCapture C:\\APITesting\\testsave.active\n" Response: "OK\n" Command: "SaveBetweenCursors C:\\APITesting\\testsavebetweencursors.active\n" Response: "OK\n" Command: "SaveConfiguration C:\\APITesting\\testsaveconfig.active\n" Response: "OK\n" Command: "OpenConfiguration C:\\APITesting\\testsaveconfig.active\n" Response: "OK\n" Command: "SaveScreenshot C:\\APITesting\\testclosed.png\n" Response: "OK\n" Command: "NewCapture\n" Response: "OK\n" Command: "OpenCapture C:\\APITesting\\testsave.active\n" Response: "OK\n" Command: "Exit\n" Response: "OK\n"
Example Source Code Listing
#include <QTcpSocket> #include <qthread.h> #include <unistd.h> #define ACTIVE_TCP_PORT 37800 void SendCommand( QTcpSocket *socket, const char *str) { QString command(str); qDebug() << "Command: " << command; // Print the command we are sending to the console window socket->write(str); // Send a Command (must be \n terminated) socket->waitForBytesWritten(); // Wait for the command to be sent } QString ReadResponse( QTcpSocket *socket ) { QString response; if (!socket->canReadLine()) // If we have not received the entire response yet, socket->waitForReadyRead(1000); // Wait to receive the response response = socket->readLine(); // Read the entire response including the '\n' qDebug() << "Response: " << response; // Print the response we received to the console window return (response); // Return the response } int main(int argc, char const* argv[]) { QTcpSocket socket; socket.connectToHost("localhost", ACTIVE_TCP_PORT); // Connect to the Active-Pro Application if (socket.waitForConnected()) { // Wait for the connection to be initialized // Determining if we are connected to the Active-Pro Application and the Active-Pro Hardware Pod SendCommand( &socket, "Hello\n"); // See if we are talking OK to the Active-Pro Application ReadResponse( &socket ); SendCommand( &socket, "isConnected\n"); // See if the Active-Pro Application is connected to the Active-Pro Pod ReadResponse( &socket ); // Opening and Closing the Tabbed Windows on the right side of the application SendCommand( &socket, "ShowInputs\n"); // Show the Inputs Window in the Active-Pro App ReadResponse( &socket ); SendCommand( &socket, "ShowList\n"); // Show the List Window in the Active-Pro App ReadResponse( &socket ); SendCommand( &socket, "ShowSettings\n"); // Show the Settings Window in the Active-Pro App ReadResponse( &socket ); SendCommand( &socket, "ShowNotes\n"); // Show the Notes Window in the Active-Pro App ReadResponse( &socket ); SendCommand( &socket, "ShowOutputs\n"); // Show the Outputs Window in the Active-Pro App ReadResponse( &socket ); SendCommand( &socket, "CloseTabs\n"); // Close any open tabs in the Active-Pro App ReadResponse( &socket ); // Setting Outputs A0, A1, D0 and D1 SendCommand( &socket, "SetD0Mode 0\n"); // Set the D0 Output level to Tristate ReadResponse( &socket ); SendCommand( &socket, "SetD0Mode 1\n"); // Set the D0 Output level to 0V ReadResponse( &socket ); SendCommand( &socket, "SetD0Mode 2\n"); // Set the D0 Output level to 3.3V ReadResponse( &socket ); SendCommand( &socket, "SetD0Mode 3\n"); // Set the D0 Output level to PWM Mode ReadResponse( &socket ); SendCommand( &socket, "SetD0PWM 25\n"); // Set the D0 Output PWM Percentage to 25% high ReadResponse( &socket ); SendCommand( &socket, "SetD0PWM 75\n"); // Set the D0 Output PWM Percentage to 75% high ReadResponse( &socket ); SendCommand( &socket, "SetD1Mode 0\n"); // Set the D1 Output level to Tristate ReadResponse( &socket ); SendCommand( &socket, "SetD1Mode 1\n"); // Set the D1 Output level to 0V ReadResponse( &socket ); SendCommand( &socket, "SetD1Mode 2\n"); // Set the D1 Output level to 3.3V ReadResponse( &socket ); SendCommand( &socket, "SetD1Mode 3\n"); // Set the D1 Output level to PWM Mode ReadResponse( &socket ); SendCommand( &socket, "SetD1PWM 25\n"); // Set the D1 Output level PWM Percentage to 25% high ReadResponse( &socket ); SendCommand( &socket, "SetD1PWM 75\n"); // Set the D1 Output level PWM Percentage to 75% high ReadResponse( &socket ); SendCommand( &socket, "SetA0Mode 0\n"); // Set the A0 Output level to Tristate ReadResponse( &socket ); SendCommand( &socket, "SetA0Mode 1\n"); // Set the A0 Output level to 0V ReadResponse( &socket ); SendCommand( &socket, "SetA0Mode 2\n"); // Set the A0 Output level to 1V ReadResponse( &socket ); SendCommand( &socket, "SetA0Mode 3\n"); // Set the A0 Output level to 2V ReadResponse( &socket ); SendCommand( &socket, "SetA0Mode 4\n"); // Set the A0 Output level to 3V ReadResponse( &socket ); SendCommand( &socket, "SetA0Mode 5\n"); // Set the A0 Output level to 3.3V ReadResponse( &socket ); SendCommand( &socket, "SetA0Mode 6\n"); // Set the A0 Output level to DC ReadResponse( &socket ); SendCommand( &socket, "SetA0DCLEVEL 0.5\n"); // Set the A0 Output DC level to 0.5V ReadResponse( &socket ); SendCommand( &socket, "SetA0DCLEVEL 1.5\n"); // Set the A0 Output DC level to 1.5V ReadResponse( &socket ); SendCommand( &socket, "SetA0DCLEVEL 2.5\n"); // Set the A0 Output DC level to 2.5V ReadResponse( &socket ); SendCommand( &socket, "SetA1Mode 1\n"); // Set the A1 Output level to 0V ReadResponse( &socket ); SendCommand( &socket, "SetA1Mode 2\n"); // Set the A1 Output level to 1V ReadResponse( &socket ); SendCommand( &socket, "SetA1Mode 3\n"); // Set the A1 Output level to 2V ReadResponse( &socket ); SendCommand( &socket, "SetA1Mode 4\n"); // Set the A1 Output level to 3V ReadResponse( &socket ); SendCommand( &socket, "SetA1Mode 6\n"); // Set the A1 Output level to DC ReadResponse( &socket ); SendCommand( &socket, "SetA1DCLEVEL 0.5\n"); // Set the A1 Output DC level to 0.5V ReadResponse( &socket ); SendCommand( &socket, "SetA1DCLEVEL 1.5\n"); // Set the A1 Output DC level to 1.5V ReadResponse( &socket ); SendCommand( &socket, "SetA1Mode 7\n"); // Set the A1 Output to a Ramp waveform ReadResponse( &socket ); SendCommand( &socket, "SetA1MINIMUM 0.5\n"); // Set the A1 waveform minimum to 0.5V ReadResponse( &socket ); SendCommand( &socket, "SetA1MAXIMUM 2.5\n"); // Set the A1 waveform maximum to 2.5V ReadResponse( &socket ); SendCommand( &socket, "SetA1Mode 8\n"); // Set the A1 Output to a Sine waveform ReadResponse( &socket ); SendCommand( &socket, "SetA1Mode 9\n"); // Set the A1 Output to a Square waveform ReadResponse( &socket ); SendCommand( &socket, "SetA1Mode 10\n"); // Set the A1 Output to a Triangle waveform ReadResponse( &socket ); SendCommand( &socket, "SetA1Steps 4000\n"); // Set the A1 Output waveform to be 4000 steps per cycle (16.17msecs). Each step is 4usecs. ReadResponse( &socket ); SendCommand( &socket, "SetA1Steps 500\n"); // Set the A1 Output waveform to be 500 steps per cycle (2msecs). Each step is 4usecs. ReadResponse( &socket ); // Capture Control SendCommand( &socket, "isCapturing\n"); // Check if the Active-Pro is capturing data ReadResponse( &socket ); SendCommand( &socket, "STARTCAPTURE\n"); // Start a capture ReadResponse( &socket ); SendCommand( &socket, "GetLogic\n"); // Get the current Logic Inputs (0-255 each bit is a channel ie. bit 0 = channel 0 digital level) ReadResponse( &socket ); SendCommand( &socket, "GetCH1\n"); // Get the current voltage on analog CH1 in volts ReadResponse( &socket ); SendCommand( &socket, "GetCH2\n"); // Get the current voltage on analog CH2 in volts ReadResponse( &socket ); SendCommand( &socket, "GetCH3\n"); // Get the current voltage on analog CH3 in volts ReadResponse( &socket ); SendCommand( &socket, "STOPCAPTURE\n"); // Stop the capture ReadResponse( &socket ); SendCommand( &socket, "GetCaptureSize\n"); // How big is the capture in bytes ReadResponse( &socket ); SendCommand( &socket, "GetCaptureTime\n"); // How long is the capture in seconds ReadResponse( &socket ); // Clearing and Entering Notes into the Notes Window SendCommand( &socket, "ShowNotes\n"); // Show the Notes Window in the Active-Pro App ReadResponse( &socket ); SendCommand( &socket, "ClearNote\n"); // Clear out the notes in the Notes Window ReadResponse( &socket ); SendCommand( &socket, "AppendNote Sent to the Active-Pro Application.\n"); // Add text to the Notes Window ReadResponse( &socket ); SendCommand( &socket, "AppendNote \n"); // Add a blank line to the notes window ReadResponse( &socket ); SendCommand( &socket, "AppendNote And here is more data.\n"); // Add more text to the notes window ReadResponse( &socket ); // Zooming the trace window SendCommand( &socket, "ZOOMALL\n"); // Zoom the waveforms to see all of the capture ReadResponse( &socket ); SendCommand( &socket, "ZoomFrom 1.0 2.0\n"); // Zoom the waveforms from 1s to 2s ReadResponse( &socket ); // Searching for data SendCommand( &socket, "SetCursorCurrent 1\n"); // Place the Current Cursor at time 1 seconds. This cursor is where the searching starts from. ReadResponse( &socket ); SendCommand( &socket, "Search mon\n"); // Find "mon" in the trace starting from the Current Cursor. Returns the time that it was found. ReadResponse( &socket ); SendCommand( &socket, "Search booga\n"); // Find "booga" in the trace. If not found it returns NOTFOUND ReadResponse( &socket ); // Setting Cursor Positions SendCommand( &socket, "SetCursorCurrent 3\n"); // Place the Current cursor at time 3.0 seconds ReadResponse( &socket ); SendCommand( &socket, "SetCursorX1 0\n"); // Place the X1 cursor at time 0.0 seconds ReadResponse( &socket ); SendCommand( &socket, "SetCursorX2 5.0\n"); // Place the X2 cursor at time 5.0 seconds ReadResponse( &socket ); // File Operations SendCommand( &socket, "ExportBetweenCursors C:\\APITesting\\test.csv\n"); // Export all decoded traffic between the X1 and X2 cursors to a file (csv format) ReadResponse( &socket ); SendCommand( &socket, "SaveCapture C:\\APITesting\\testsave.active\n"); // Export all decoded traffic between the X1 and X2 cursors to a file (csv format) ReadResponse( &socket ); SendCommand( &socket, "SaveBetweenCursors C:\\APITesting\\testsavebetweencursors.active\n"); // Export all decoded traffic between the X1 and X2 cursors to a file (csv format) ReadResponse( &socket ); SendCommand( &socket, "SaveConfiguration C:\\APITesting\\testsaveconfig.active\n"); // Export all decoded traffic between the X1 and X2 cursors to a file (csv format) ReadResponse( &socket ); SendCommand( &socket, "OpenConfiguration C:\\APITesting\\testsaveconfig.active\n"); // Export all decoded traffic between the X1 and X2 cursors to a file (csv format) ReadResponse( &socket ); SendCommand( &socket, "SaveScreenshot C:\\APITesting\\testclosed.png\n"); // Take a screenshot of the Active-Pro App window and save it to a file ReadResponse( &socket ); SendCommand( &socket, "NewCapture\n"); // Reset all settings and clear any existing capture data ReadResponse( &socket ); SendCommand( &socket, "OpenCapture C:\\APITesting\\testsave.active\n"); // Open a capture file that was previously saved ReadResponse( &socket ); SendCommand( &socket, "Exit\n"); // Closes the Active-Pro Application ReadResponse( &socket ); socket.close(); // Close the connection } }
Command Line Application
We have written a simple command line application that can be called by batch files, scripts, or other programs to send a command to the Active-Pro application. This application only works on Windows currently, but we have included the source code below if you’d like to port it over to other operating systems. It is a single executable file and needs no support files, so simply unzip the file and place it somewhere accessible by your path settings.
Command Line Application Source Code
// This program accesses the TCP Socket to the Active-Pro API so people dom't need to write code. // // This works with Active-Pro App version 4.0 and above // // Each call simply: // - Open the connection to the app // - Sends the Command // - Receives the response // - Writes the response to the commandline output (stdio) // - Closes the connection // - Exits // #include <QTcpSocket> #include <QtCore> #define ACTIVE_TCP_PORT_DEVICE_1 37800 #define ACTIVE_TCP_PORT_DEVICE_2 37801 QTcpSocket socket; void SendCommand( QTcpSocket *socket, QString QStr) { const char *str = QStr.toLocal8Bit().constData(); socket->write(str); // Send a Command (must be \n terminated) socket->waitForBytesWritten(); // Wait for the command to be sent } QString ReadResponse( QTcpSocket *socket) { QString response; socket->waitForReadyRead(10); response = socket->readAll(); while (!response.contains("\n")) // If we have not received the entire response yet, { socket->waitForReadyRead(10); response +=socket->readAll(); } return (response); // Return the response } int main(int argc, char * argv[]) { QCoreApplication a(argc, argv); QTextStream out(stdout); // Send the output to stdout QString Command; int device = 1; // Default to device 1 int port = ACTIVE_TCP_PORT_DEVICE_1; bool throwhelpscreen = 0; // Validate the command line arguments if ((argc < 2) || (argc > 3) || ((argc == 2) && (strcmpi(argv[1], "-?")) == 0)) { throwhelpscreen = 1; } else if (argc == 2) { // No port number so just get the command device = 1; // Default to device 1 port = ACTIVE_TCP_PORT_DEVICE_1; Command = QString::fromLatin1(argv[1]); } else if (argc == 3) { // The port is specified if (strcmpi(argv[1], "1") == 0) { port = ACTIVE_TCP_PORT_DEVICE_1; device = 1; Command = QString::fromLatin1(argv[2]); } else if (strcmpi(argv[1], "2") == 0) { port = ACTIVE_TCP_PORT_DEVICE_2; device = 2; Command = QString::fromLatin1(argv[2]); } else { throwhelpscreen = 1; } } if (throwhelpscreen) { out << "ActiveAPICommandLine version 1.1\n"; out << "Usage: activeapicommandline [optional device number] \"command with parameters\"\n"; out << " [optional device number] is 1 or 2. Device number 1 is default if not provided.\n"; out << " command is the command to send and must be encloded in quotes.\n"; out << " Responses will be written to the console output (stdio).\n"; out << " Commands and Responses are available at http://www.activefirmwaretools.com\n"; return (0); } socket.connectToHost("localhost", port); if (socket.waitForConnected(5000)) { // Wait for the connection to be initialized SendCommand( &socket, Command + "\n"); // Append a new line QString response = ReadResponse( &socket ); out << response; // The responses already have a new line socket.disconnectFromHost(); if (socket.state() != QAbstractSocket::UnconnectedState) socket.waitForDisconnected(1000); socket.close(); // Close the connection } else { out << "Can not connect to device " << device << " on port " << port << "\n"; } return (0); }
Command Line Application Usage
The batch files below show how to launch 2 separate Active-Pro Applications connected to 2 separate Active Pro pods, and how to send commands to either of the applications.
This first batch file simply launches 2 instances of the Active-Pro Application and assigns them each an ID, 1 and 2. These IDs are used by the following batch file to specify which Active-Pro you want to communicate with.
Filename: Launch2ActiveApps.bat start ActiveProDebugger -a 1 start ActiveProDebugger -a 2 pause
This batch file below talks to the 2 separate Active-Pro Applications, each attached to a separate Active-Pro pod.
Filename: SendCommandsToActives.bat activeapicommandline 1 "startcapture" activeapicommandline 2 "startcapture" activeapicommandline 1 "stopcapture" activeapicommandline 2 "stopcapture" activeapicommandline 1 "closetabs" activeapicommandline 2 "closetabs" pause