minute read
C API Guidelines
You are reading our Automation1 API documentation for the C programming language.
This page tells you about the guidelines that you must obey to correctly use the C API. It also includes information that is important to know when you start to write a large-scale custom application that uses the C API.
IMPORTANT: Before you read these guidelines, make sure that you read the About the C API page first. This page builds on that information.
The Three Controller Categories: Axis, Task, and System
The Automation1 controller is divided into three categories - axis, task, and system.
Each Automation1 controller has a fixed number of axes - 32 axes for a PC-based controller and 12 axes for a drive-based controller. The axis category consists of these axes and their configuration, parameters, and status.
Each Automation1 controller also has some number of controller tasks. The tasks can be different based on the type of controller and your license key. The task category consists of these controller tasks and their configuration, parameters, and status.
The system category consists of the Automation1 controller and its configuration, parameters, and status.
These three categories are important in the C API because different types of information are available for each one. For example, features such as controller parameters, status, and data collection are divided into these categories. The C functions that are related to each feature use variations for the axis, task, and system categories.
For Example
- Automation1_Status_GetAxisResult()
- Automation1_Status_GetTaskResult()
- Automation1_Status_GetSystemResult()
If you must specify an axis, you must use the axis index. The C API does not support axis names. You can use the Automation1_Controller_GetAxisIndexFromAxisName() function to get the axis index for an axis name.
If you must specify a task, you must use the task index. The C API does not support task names. You can use the Automation1_Controller_GetTaskIndexFromTaskName() function to get the task index for a task name.
Errors and Error Handling
All the C API functions return a bool result that lets you know if the function was successful. You must examine the bool result of each function call to make sure that no error occurred. If an error does occur, you can use the Automation1_GetLastError() and the Automation1_GetLastErrorMessage() functions to get more information about it.
Automation1Controller controller;
if (!Automation1_Connect(&controller))
{
int32_t lastError = Automation1_GetLastError();
char lastErrorMessage[2048];
Automation1_GetLastErrorMessage(lastErrorMessage, 2048);
// Print or log the error, clean up, change your process, etc.
}
The Automation1_GetLastError() function gives you the error number of the last error that occurred on the C thread that is currently executing.
The Automation1_GetLastErrorMessage() function gives you the string error message of the last error that occurred on the C thread that is currently executing.
C API errors are stored separately for each C thread. Each C thread tracks errors separately in the C API. You cannot get the C API error for one thread from a different thread.
A successful function call does not clear the last error. New errors will overwrite the previous errors.
Errors have error types that help keep similar errors together. In other APIs, these error types become exceptions. But in the C API, there are separate functions that you can use to determine the specific type of an error that occurs.
IMPORTANT: Automation1 error types are hierarchical. You must handle them in the correct order, which is most specific to least specific.
For Example
Make sure that you examine the error number to see if an error is a ControllerCommunication error type before you examine it to see if the error is a Controller error type.
The table that follows shows the error types for the C API, from the most important to the least important.
Table: C API Error Types
Error Type | Description |
---|---|
Automation1_IsControllerArgumentError(...) |
The error type that occurs when an argument to an Automation1 function or command is not valid. |
Automation1_IsControllerOperationError(...) |
The error type that occurs when a function or command cannot execute. |
Automation1_IsControllerAxisAbortError(...) |
The error type that occurs when an axis is aborted during the execution of a command. |
Automation1_IsControllerAxisFaultError(...) |
The error type that occurs when the controller generates an axis fault during the execution of a command |
Automation1_IsControllerStateError(...) |
The error type that occurs when a function or command cannot execute because the controller is not in the expected state, such as stopped, running, or resetting. |
Automation1_IsControllerCommunicationError(...) |
The error type that occurs when there is a problem communicating with the controller. |
Automation1_IsControllerDisconnectedError(...) |
The error type that occurs when you become disconnected from the controller. |
Axis Faults and Task Errors
C API errors are different from controller axis faults and controller task errors. The C API returns an error if a function call does not succeed. A C API error represents an error in one moment in time.
But axis faults and task errors are continuous error conditions that exist on an axis or a controller task.
For Example
If an axis moves into its end-of-travel limit, it will generate an end-of-travel limit axis fault. This axis fault stays until you acknowledge it.
If an AeroScript program divides by zero, it will cause a task error to occur on the task that it was running. This task error stays until you stop the program.
An axis fault or a controller task might cause the C API to return an error.
For Example
If you execute motion on an axis and that motion causes the controller to generate an axis fault, the C API will return an error.
If you execute an AeroScript command that causes a task error, the C API will return an error.
In these examples, the continuous axis fault or continuous task error caused the C API to return an error. The fault or error continues to stay after you handle the C API error.
To get active axis faults and controller task errors, use Status.
Match the C API Version with the Automation1 Controller Version
The version of the C API that you use in your custom application must match the version of the Automation1 controller that you are connecting to.
For Example
If you want to connect to an Automation1 controller that is running version 2.2.0, then your custom application must reference and use version 2.2.0 of the C API.
Upgrade the C API Version for Your Custom Application
To upgrade the version of the C API that you are using, do the steps that follow.
TO UPGRADE YOUR VERSION OF THE C API
- Download and install the version of Automation1 to which you want to upgrade. You can download the Automation1 software from the Software Downloads page of the Aerotech website.
- Install the Automation1-MDKSetup.exe file. This file is part of the Automation1 software that you downloaded.
- After you install the software, restart the PC.
- To upgrade the version of the C API that you are using, do the procedure that is specific to your machine:
- Replace all the current C API DLL files with the new DLL files that are from the Automation1 version to which you upgraded.
- Replace all the current H (header) files with the new H files that are from the Automation1 version to which you upgraded.
- Replace all the current SO (shared object) files with the new SO files that are from the Automation1 version to which you upgraded.
- Replace all the current H (header) files with the new H files that are from the Automation1 version to which you upgraded.
Tip: This file is located in the Installation folder. See the Install the Automation1-MDK section of the Install the Software page for more information.
It is not necessary for you to recompile your custom application. The C API maintains binary compatibility between versions. If the C API stops maintaining binary compatibility, its release notes will include this information.
For minor software versions, source compatibility and binary compatibility are preserved in the C API. But major software versions, such as 2.0.0, 3.0.0, or 4.0.0, might contain source compatibility or binary compatibility changes. The release notes for each software version will tell you if there are compatibility changes.
IMPORTANT: If one or more compatibility changes occur, you must update your custom application code with the new C API changes.
Distribute Your Custom Application
To get access to the C API, you must install Automation1-MDK on a Microsoft Windows PC. After you build your custom application, you can distribute and run it to any supported operating system. For information about which operating systems are supported, see Supported Languages, Versions, and Operating Systems.
To run your custom application, it is not necessary to have Automation1-MDK installed. But you must copy all the C API files to your target system. For a list of the files that are required based on your operating system, see Begin a New Project.
On Windows, the Microsoft Visual C++ Redistributable 2019 or newer is required. This redistributable is installed with Automation1-MDK. If you run your custom application on a PC that does not have Automation1-MDK installed, then you must install the redistributable manually.
Thread Safety
The C API consists of thread-safe and non-thread-safe functions. To learn about the thread safety of the controller features:
- Read the documentation for each controller feature.
- See the Full References for Automation1 C API page. This page helps you find documentation for the controller features.
Use the C API in a Graphical User Interface
When you use the C API in a graphical user interface application, you must contend with these behaviors of the API:
Latency and Communication Loss - Most functions in the C API communicate with the Automation1 controller. When they communicate, latency and communication loss can occur. You can install the Automation1 controller locally. Or you can install a remote Automation1 controller on a different device. If you install the controller remotely, the communication latency is higher and will be controlled by your local area network. This communication latency can add several milliseconds of delay to these functions in the C API.
Functions That Block Until a Controller Operation Completes - Some functions in the C API will block until a controller operation completes.
For Example
Let's say that you execute a MoveLinear()
AeroScript command through the Automation1_Command_MoveLinear() function. This function will block until the linear move is complete. One linear move can occur from 1 millisecond to multiple seconds.
WARNING: Because of these API behaviors, you must not call the C API functions from the UI thread. If you do this, your UI will become unresponsive while the Automation1 controller does its operation.
For more information about the problems that can occur if you call C API functions from the UI thread, refer to the use-case scenario that follows.
Use-Case Scenario - Call API Functions from the UI Thread (Not Recommended)
Let's say that you have a Windows application with a Move button that moves your X axis 10 millimeters over 5 seconds with a speed of 2 millimeters per second. You decide to call API functions from the UI thread by doing the steps that follow:
- You click the Move button. It executes a linear move through the Automation1_Command_MoveLinear() function in the button-clicked event handler.
- There is also an Abort button that aborts all motion if an emergency occurs. You click this button. It executes an abort through the Automation1_Command_Abort() function in the button-clicked event handler.
- You click the Move button again. Because the MoveLinear() function was executed on the UI thread, your application freezes or becomes unresponsive for 5 seconds while the
MoveLinear()
AeroScript command is executing. During these 5 seconds, an emergency occurs! - You click the Abort button to abort all motion. But the button cannot execute the Abort() function. This occurs because the UI thread is blocked until the MoveLinear() function is complete.
As referred to in the use-case scenario, it is important for you to not block the UI thread. If you do, unsafe conditions can occur.
To Prevent Functions from Blocking the UI Thread
You must use threads or asynchronous programming so that the UI thread does not call functions in the C API. Instead, you must use a background thread that interacts with the C API. This interaction keeps the UI thread responsive.
You have some options that you can use to implement threads or asynchronous programming. They are as follows:
- Use one background thread that interacts with the C API.
- Spawn a new thread for each operation on the controller.
IMPORTANT: For these two options, you must read and understand the thread safety of the C API and the operations that you are trying to do.
In the previous use-case scenario, the user blocked the UI thread by trying to call API functions from the thread. As a result, the user could not abort motion when an emergency occurred. But the user could have prevented this problem by executing the commands on new threads. By doing one of these options, a new use-case scenario can occur as follows.
Use-Case Scenario - Call API Functions by Spawning New Threads (Best Practice)
Let's say that you have a Windows application with a Move button that moves your X axis 10 millimeters over 5 seconds with a speed of 2 millimeters per second. You decide to call API functions by spawning a new thread for each operation on the controller by doing the steps that follow:
- You click the Move button. It executes a linear move through the Automation1_Command_MoveLinear() function in a new thread that is spawned in the button-clicked event handler.
- There is also an Abort button that aborts all motion if an emergency occurs. You click this button. It executes an abort through the Automation1_Command_Abort() function in a new thread that is spawned in the button-clicked event handler.
- You click the Move button again. Because the MoveLinear() function is executing on a background thread, your application stays responsive for the 5 seconds that are necessary for the command to fully execute. During these 5 seconds, an emergency occurs!
- You click the Abort button to abort all motion. Because each command is executing on a background thread and Commands is thread safe, the abort executes immediately. The abort stops all motion and the linear move stops.