Support » Tic Stepper Motor Controller User’s Guide » 12. Writing PC software to control the Tic »
12.11. Example code using the C API
The code below uses the C API provided by the Tic software to send and receive data from a Tic over USB. This code is written in C and works on Windows, Linux, and macOS. For a very similar example using the C++ API, see Section 12.12.
If you have compiled the Tic software from source and installed it on a Unix-like system (including MSYS2 on Windows), and copied the code below to a file named code.c
, you should be able to compile the code below by running this command in a shell:
gcc code.c $(pkg-config libpololu-tic-1 --cflags --libs)
You might notice that the Tic only performs the desired movement for about a second before it stops moving and the red LED turns on, indicating an error. This is because of the Tic’s command timeout feature: by default, the Tic’s “Command timeout” error will happen if it does not receive certain commands periodically (see Section 5.4 for details), causing the motor to stop. You can send a “Reset command timeout” command every second to get around this, or you can disable the command timeout feature using the Tic Control Center: uncheck the “Enable command timeout” checkbox in the “Serial” box.
// Uses the Tic's C API to send and receive data from a Tic. // NOTE: The Tic's control mode must be "Serial / I2C / USB". #include <stdio.h> #include <stdint.h> #include <string.h> #include <tic.h> bool handle_error(tic_error * error) { if (error == NULL) { return false; } fprintf(stderr, "Error: %s\n", tic_error_get_message(error)); tic_error_free(error); return true; } // Opens a handle to a Tic that can be used for communication. // // To open a handle to any Tic: // tic_handle * handle = open_handle(NULL); // To open a handle to the Tic with serial number 01234567: // tic_handle * handle = open_handle("01234567"); tic_handle * open_handle(const char * desired_serial_number) { tic_handle * handle = NULL; // Get a list of Tic devices connected via USB. tic_device ** list = NULL; size_t count = 0; tic_error * error = tic_list_connected_devices(&list, &count); if (handle_error(error)) { goto cleanup; } // Iterate through the list and select one device. tic_device * device = NULL; for (size_t i = 0; i < count; i++) { tic_device * candidate = list[i]; if (desired_serial_number) { const char * serial_number = tic_device_get_serial_number(candidate); if (strcmp(serial_number, desired_serial_number)) { // Found a device with the wrong serial number, so continue on to // the next device in the list. continue; } } // Select this device as the one we want to connect to, and break // out of the loop. device = candidate; break; } if (device == NULL) { fprintf(stderr, "Error: No device found.\n"); goto cleanup; } error = tic_handle_open(device, &handle); if (handle_error(error)) { goto cleanup; } cleanup: for (size_t i = 0; i < count; i++) { tic_device_free(list[i]); } tic_list_free(list); return handle; } int main() { int exit_code = 1; tic_handle * handle = NULL; tic_variables * variables = NULL; handle = open_handle(NULL); if (handle == NULL) { goto cleanup; } tic_error * error = tic_get_variables(handle, &variables, false); if (handle_error(error)) { goto cleanup; } int32_t position = tic_variables_get_current_position(variables); printf("Current position is %d.\n", position); int32_t new_target = position > 0 ? -200 : 200; printf("Setting target position to %d.\n", new_target); error = tic_exit_safe_start(handle); if (handle_error(error)) { goto cleanup; } error = tic_set_target_position(handle, new_target); if (handle_error(error)) { goto cleanup; } exit_code = 0; // This program ran successfully. cleanup: // Free the resources used by the variables. tic_variables_free(variables); // Call tic_handle_close() to free its resources and because Windows only // allows one open handle per device. // (Though, in this program, we are about to return from main, so the program // will exit and the operating system will do this for us very soon.) tic_handle_close(handle); return exit_code; }