CyberAtom C Library

2.5.0

Tutorial: Getting System Information

This tutorial guides through construction of CyberAtom API objects and retrieving system information (model and firmware version) from AHRS device connected to PC via USB cable.

The API library uses concept of a logical device handle that represents a connected physical device in user's code. This is what IDeviceHandle type is for. Once instantiated, plays central role in device-to-application communication.

In order to construct a logical device handle, two other objects have to be provided:

Creating Connection Handle

To use connection via USB cable, IConnectionHandle can be created using UsbConnection_create() function.

It takes pointer to exception code as a parameter.

enum Exception e = E_OK;
if (e != E_OK)
{
printf("Problem with connecting to the USB device.\n");
return -1;
}

Preparing Response Handler

To create response handler, you need to prepare IResponseCallbacks structure.

E.g. to receive and print system information, you can define a standalone callback function like that. Note that the very first parameter is a pointer to a custom data. Here it is assumed that it points to a single byte flag indicating data retrieval. It will be show later how to ensure which data is passed as such custom pointer.

// Callback handler for sysInfo messages.
void sysInfoCallback(void* userData, const char* device, const char* firmwareDate)
{
uint8_t* received = (uint8_t*)userData;
*received = 1;
printf("Model: %s, Firmware: %s\n", device, firmwareDate);
}

and then in the main function you can declare the structure and fill it's fields accordingly. Here we set userData pointer and a sysInfo function pointer.

struct IResponseCallbacks response = { 0 };
// Assigning pointer to the retrieval flag as user data for callbacks.
uint8_t received = 0;
response.userData = &received;
// Setting up callback function fo system information data.
response.sysInfo = sysInfoCallback;

Retrieving Data from Device

Once this is done, you can create a logical device handle:

// Creating a device handle.
IDeviceHandle device = Device_create(connection, &response);

With this handle, you are now free to request for various information, e.g system details, like:

// Requesting system information from a device.

This method call sends request to the device. Now wee also need a way to obtain the information device is sending back. For that you need to use IDevice_checkForMessages() function, in a periodic loop until the message we expect arrives and is intercepted by the define callback:

while (!received)
{
// busy waiting for response.
#if _WIN32
Sleep(10); // milliseconds
#else
usleep(10000); // microseconds
#endif
e = E_OK;
if (e != E_OK)
{
printf("Problem with receiving message.\n");
return -1;
}
}

When the system information message arrives from the device, the sysInfoCallback() method will be called back by the device object, which eventually will help to terminate the loop and print the retrieved details.

Tear Down

The final piece is to release created resources:

IDevice_release(device);
IConnection_release(connection);

Complete Code

With adding some exception handling, the complete code can look like that:

#if _WIN32
#include <windows.h>
#endif
#include "cyberatom.h"
#include <stdio.h>
// Callback handler for sysInfo messages.
void sysInfoCallback(void* userData, const char* device, const char* firmwareDate)
{
uint8_t* received = (uint8_t*)userData;
*received = 1;
printf("Model: %s, Firmware: %s\n", device, firmwareDate);
}
int main()
{
enum Exception e = E_OK;
if (e != E_OK)
{
printf("Problem with connecting to the USB device.\n");
return -1;
}
struct IResponseCallbacks response = { 0 };
// Assigning pointer to the retrieval flag as user data for callbacks.
uint8_t received = 0;
response.userData = &received;
// Setting up callback function fo system information data.
response.sysInfo = sysInfoCallback;
// Creating a device handle.
IDeviceHandle device = Device_create(connection, &response);
// Requesting system information from a device.
while (!received)
{
// busy waiting for response.
#if _WIN32
Sleep(10); // milliseconds
#else
usleep(10000); // microseconds
#endif
e = E_OK;
if (e != E_OK)
{
printf("Problem with receiving message.\n");
return -1;
}
}
IDevice_release(device);
IConnection_release(connection);
return 0;
}

Summary

This tutorial demonstrates how-to retrieve system information from the CyberAtom AHRS device using a C library. The technique is based on creating and using logical device handle with combination with callback functions as handlers for incomming data. This is the pattern that works for almost any data retrieval scenario.