This tutorial introduces you to the basics of the ACI Remote in C. It will teach you, how to establish a connection and to get the first information from the device.
To compile our code, we write a small and simple Makefile:
We are using a gcc compiler and set the standard include path. In most of all Linux distributions (like in Ubuntu), it is /usr/include/. For linking, we are also using gcc with common linking flags and POSIX library. The executable is called aci_intro the sources are only ACI itself with asctecCommIntf.c and our new created file main.c. In each chapter of this tutorial we will use this Makefile and change only the name of the executable.
Let us begin with a short code example. For that, we need the ACI libraries and create a new c-file main.c, where we write all our code.
First of all, we have to include all necessary headers:
The first one is the AscTec Communication Interface. You don't have to include the asctecDefines.h. The rest are standard unix function definitions and posix threads.
Let us now define some functions and variables:
fd is the file descriptor for the serial device. The next four functions are defined for the necessary callbacks of ACI. The last one is declared to create an ACI thread.
After that, the main function is declared. We first have to declare the POSIX variable and open the device:
Maybe you have to adjust the path of your serial device correctly (/dev/ttyUSB0 is a port on the AscTec Atomboard). We open a non-blocking read-/writable device. Baudrate is standardly 57600 to communicate with the HL serial 0 port. Then, we setup ACI:
You have to initialize ACI with aciInit(), define all important callbacks and set the engine rate and the heart beat rate. The engine rate defines the communication frequency of your ACI remote. If your device e.g. sends variables with 100Hz, the engine rate needs to be set to at least 100Hz or faster. The heart beat can be sent with a separate frequency but only as fast as the engine rate. The device needs to receive the heart beat at least once in 3 seconds, otherwise it will stop sending data to the remote. The transmitting function
only writes all data very simple to the serial device. With aciInfoPacketReceivedCallback(&versions); we will check, if we are connected with the device by asking it for its versions. That will be an output on the screen:
ACI_INFO is a struct which includes all necessary information for version changes. That includes also length of strings or the count of packets. Be aware, that these parameters need to be compatible on the device and your program, otherwise the communication between the device and your program may have some problems.
The last thing, what is now missing is creating the thread for ACI:
To test, if everything works fine, we ask the device for getting information about the version with aciCheckVerConf(). In the ACI thread,
we read the incoming bytes and put them in the ACI receive handler byte by byte until there are no more bytes available. If your PC is too slow or the device is sending so much data, that the buffer will never be empty, the device will stop to send after a few seconds because it will not get the heartbeat signal.
Execute the program and you should get an output of the version of the device and the remote that looks similar to the following lines:
So, what happened? After establishing a connection, aciEngine(void) in aciThread(void) processed the incoming heartbeat signal. You see it on the Xbee connected to your PC, that it receives something (green LED), but don't send anything. Then we ask the device to give us version informations. After getting them, ACI executes the callback, we defined for version informations.