12.10. 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.11.

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;
}

Related Products

Tic T825 USB Multi-Interface Stepper Motor Controller (Connectors Soldered)
Tic T825 USB Multi-Interface Stepper Motor Controller
Tic T834 USB Multi-Interface Stepper Motor Controller (Connectors Soldered)
Tic T834 USB Multi-Interface Stepper Motor Controller
Tic T500 USB Multi-Interface Stepper Motor Controller (Connectors Soldered)
Tic T500 USB Multi-Interface Stepper Motor Controller
Tic T249 USB Multi-Interface Stepper Motor Controller (Connectors Soldered)
Tic T249 USB Multi-Interface Stepper Motor Controller
Log In
Pololu Robotics & Electronics
Shopping cart
(702) 262-6648
Same-day shipping, worldwide
Menu
Shop Blog Forum Support
My account Comments or questions? About Pololu Contact Ordering information Distributors