{"id":13802385,"url":"https://github.com/jphalip/ticlib","last_synced_at":"2025-07-05T07:06:52.728Z","repository":{"id":41116094,"uuid":"359018983","full_name":"jphalip/ticlib","owner":"jphalip","description":"Python library to drive Pololu Tic stepper motor controllers","archived":false,"fork":false,"pushed_at":"2021-06-15T15:35:39.000Z","size":44,"stargazers_count":17,"open_issues_count":4,"forks_count":1,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-04-30T06:32:12.295Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jphalip.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-04-18T01:31:36.000Z","updated_at":"2024-02-22T18:37:01.000Z","dependencies_parsed_at":"2022-09-07T13:51:07.546Z","dependency_job_id":null,"html_url":"https://github.com/jphalip/ticlib","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jphalip%2Fticlib","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jphalip%2Fticlib/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jphalip%2Fticlib/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jphalip%2Fticlib/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jphalip","download_url":"https://codeload.github.com/jphalip/ticlib/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221815175,"owners_count":16885134,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-04T00:01:43.219Z","updated_at":"2025-07-05T07:06:52.720Z","avatar_url":"https://github.com/jphalip.png","language":"Python","readme":"`ticlib` is a pure-Python library to drive [Pololu Tic stepper motor controllers](https://www.pololu.com/category/212/tic-stepper-motor-controllers).\n\nThis library supports serial, I²C, and USB connections for Python3; and serial and I²C for Micropython.\n\n# Example code\n\n```python\nfrom ticlib import TicUSB\nfrom time import sleep\n\ntic = TicUSB()\n\ntic.halt_and_set_position(0)\ntic.energize()\ntic.exit_safe_start()\n\npositions = [500, 300, 800, 0]\nfor position in positions:\n    tic.set_target_position(position)\n    while tic.get_current_position() != tic.get_target_position():\n        sleep(0.1)\n\ntic.deenergize()\ntic.enter_safe_start()\n```\n\n# Installation\n\nThe `ticlib` library is hosted on PyPI and can be installed by running this command:\n\n```shell\npip install ticlib\n```\n\n# Available controllers\n\n## Serial\n\nExample using Python 3 and the [pyserial](https://pypi.org/project/pyserial/) library:\n\n```python\nimport serial\nfrom ticlib import TicSerial\n\nport = serial.Serial(\"/dev/ttyS0\", baud_rate=9600, timeout=0.1, write_timeout=0.1)\ntic = TicSerial(port)\n```\n\nExample using Micropython:\n\n```python\nfrom machine import UART\nfrom ticlib import TicSerial\n\nport = UART(0, baudrate=9600, timeout=100)\ntic = TicSerial(port)\n```\n\nInstantiation parameters for `TicSerial`:\n\n- `port` (required): Serial port used to communicate with the Tic.\n- `device_number` (optional): Number of the device that you want to control. Use this if you have multiple devices\n  connected to your serial line. Defaults to `None`.\n- `crc_for_commands` (optional): If `True`, the library will append a CRC byte to every command sent to the Tic. Set\n  this to `True` if your Tic's \"Enable CRC for commands\" setting is turned on. Defaults to `False`.\n- `crc_for_responses` (optional): If `True`, the library will expect a CRC byte at the end of every response returned\n  by the Tic. Set this to `True` if your Tic's \"Enable CRC for responses\" setting is turned on. Defaults to `False`.\n\nFor more details, see Pololu's official documentation on [serial command encoding](https://www.pololu.com/docs/0J71/9).\n\n\n## I²C\n\nExample using Python 3 and the [smbus2](https://pypi.org/project/smbus2/) library.\n\n```python\nfrom smbus2 import SMBus\nfrom ticlib import TicI2C, SMBus2Backend\n\nbus = SMBus(3)  # Represents /dev/i2c-3\naddress = 14    # Address of the Tic, that is its device number\nbackend = SMBus2Backend(bus)\n\ntic = TicI2C(backend)\n```\n\nExample using Micropython:\n\n```python\nfrom machine import I2C\nfrom ticlib import TicI2C, MachineI2CBackend\n\ni2c = I2C(1)  # ID of your I2C peripheral\naddress = 14  # Address of the Tic, that is its device number\nbackend = MachineI2CBackend(i2c, address)\n\ntic = TicI2C(backend)\n```\n\nInstantiation parameter for `TicI2C`:\n\n- `backend` (required): The I²C backend. Available options are `SMBus2Backend` for Python 3 and `MachineI2C` for\n  Micropython.\n\nNote: If you use a Raspberry Pi, make sure to follow the workaround described in the [Pololu documentation](https://www.pololu.com/docs/0J71/12.8).\n\nFor more details, see Pololu's official documentation on [I²C command encoding](https://www.pololu.com/docs/0J71/10).\n\n## USB\n\nThe USB controller has a dependency on the [pyusb](https://pypi.org/project/pyusb/) library.\n\nExample:\n\n```python\nfrom ticlib import TicUSB\n\ntic = TicUSB()\n```\n\nInstantiation parameters for `TicUSB`:\n\n- `product` (optional): USB product ID for your Tic. If `None`, the device will be automatically detected. Use this if\n  multiple Tic devices are connected to your computer. The available options are: `TIC_T825` (`0x00b3`), `TIC_T834`\n  (`0x00b5`), `TIC_T500` (`0x00bd`), `TIC_N825` (`0x00c3`), `TIC_T249` (`0x00c9`), and `TIC_36v4` (`0x00cb`). Defaults\n  to `None`.\n- `serial_number` (optional): The serial number (in string format) of your Tic. If `None`, the device will be\n  automatically detected. Use this if multiple Tic devices are connected to your computer. Default to `None`.\n\nFor more details, see Pololu's official documentation on [USB command encoding](https://www.pololu.com/docs/0J71/11).\n\n# Commands:\n\nAvailable commands:\n\n```python\ntic.clear_driver_error()\ntic.deenergize()\ntic.energize()\ntic.enter_safe_start()\ntic.exit_safe_start()\ntic.go_home(value)\ntic.halt_and_hold()\ntic.halt_and_set_position(value)\ntic.reset()\ntic.reset_command_timeout()\ntic.set_agc_option(value)\ntic.set_current_limit(value)\ntic.set_decay_mode(value)\ntic.set_max_acceleration(value)\ntic.set_max_deceleration(value)\ntic.set_max_speed(value)\ntic.set_starting_speed(value)\ntic.set_step_mode(value)\ntic.set_target_position(value)\ntic.set_target_velocity(value)\n```\n\nFor more details, see the official [command reference](https://www.pololu.com/docs/0J71/8).\n\nPlease note:\n- `tic.set_current_limit(value)` is encoded as described [here](https://www.pololu.com/docs/0J71/6#setting-current-limit) rather than sent as a value in mA.\n- `tic.set_step_mode(value)` is encdoed as described [here](https://www.pololu.com/docs/0J71/8#cmd-set-step-mode) rather than sent as a fraction.\n\n# Variables\n\nAvailable variables:\n\n```python\n# General status  -------------------------------------\ntic.get_error_occured()\ntic.get_error_status()\ntic.get_misc_flags()\ntic.get_operation_state()\n\n# Step planning ---------------------------------------\ntic.get_acting_target_position()\ntic.get_current_position()\ntic.get_current_velocity()\ntic.get_max_acceleration()\ntic.get_max_deceleration()\ntic.get_max_speed()\ntic.get_planning_mode()\ntic.get_starting_speed()\ntic.get_target_position()\ntic.get_target_velocity()\ntic.get_time_since_last_step()\n\n# Other -----------------------------------------------\ntic.get_analog_reading_rx()\ntic.get_analog_reading_scl()\ntic.get_analog_reading_sda()\ntic.get_analog_reading_tx()\ntic.get_current_limit()\ntic.get_decay_mode()\ntic.get_device_reset()\ntic.get_digital_readings()\ntic.get_encoder_position()\ntic.get_input_after_averaging()\ntic.get_input_after_hysteresis()\ntic.get_input_after_scaling()\ntic.get_input_state()\ntic.get_pin_states()\ntic.get_rc_pulse()\ntic.get_step_mode()\ntic.get_vin_voltage()\ntic.get_uptime()\n\n# T249-only -------------------------------------------\ntic.get_agc_bottom_current_limit()\ntic.get_agc_current_boost_steps()\ntic.get_agc_frequency_limit()\ntic.get_agc_mode()\ntic.get_last_motor_driver_error()\n\n# 36v4-only -------------------------------------------\ntic.get_last_hp_driver_errors()\n```\n\nFor more details, see the official [variable reference](https://www.pololu.com/docs/0J71/7).\n\n# Settings\n\nAvailable settings:\n\n```python\ntic.settings.get_control_mode()\n\n# Miscellaneous -------------------------------------------------\ntic.settings.get_auto_clear_driver_error()\ntic.settings.get_disable_safe_start()\ntic.settings.get_ignore_err_line_high()\ntic.settings.get_never_sleep()\ntic.settings.get_vin_calibration()\n\n# Soft error response -------------------------------------------\ntic.settings.get_current_limit_during_error()\ntic.settings.get_soft_error_position()\ntic.settings.get_soft_error_response()\n\n# Serial --------------------------------------------------------\ntic.settings.get_serial_7bit_responses()\ntic.settings.get_serial_14bit_device_number()\ntic.settings.get_serial_alt_device_number()\ntic.settings.get_serial_baud_rate()\ntic.settings.get_serial_command_timeout()\ntic.settings.get_serial_crc_for_commands()\ntic.settings.get_serial_crc_for_responses()\ntic.settings.get_serial_device_number()\ntic.settings.get_serial_enable_alt_device_number()\ntic.settings.get_serial_response_delay()\n\n# Encoder -------------------------------------------------------\ntic.settings.get_encoder_postscaler()\ntic.settings.get_encoder_prescaler()\ntic.settings.get_encoder_unlimited()\n\n# Input conditioning --------------------------------------------\ntic.settings.get_input_averaging_enabled()\ntic.settings.get_input_hysteresis()\n\n# RC and analog scaling -----------------------------------------\ntic.settings.get_input_invert()\ntic.settings.get_input_max()\ntic.settings.get_input_min()\ntic.settings.get_input_neutral_max()\ntic.settings.get_input_neutral_min()\ntic.settings.get_input_scaling_degree()\ntic.settings.get_output_max()\ntic.settings.get_output_min()\n\n# Pin Configuration ---------------------------------------------\n# SCL\ntic.settings.get_scl_active_high()\ntic.settings.get_scl_config()\ntic.settings.get_scl_enable_analog()\ntic.settings.get_scl_enable_pull_up()\ntic.settings.get_scl_kill_switch()\ntic.settings.get_scl_limit_switch_forward()\ntic.settings.get_scl_limit_switch_reverse()\ntic.settings.get_scl_pin_function()\n# SDA\ntic.settings.get_sda_active_high()\ntic.settings.get_sda_config()\ntic.settings.get_sda_enable_analog()\ntic.settings.get_sda_enable_pull_up()\ntic.settings.get_sda_kill_switch()\ntic.settings.get_sda_limit_switch_forward()\ntic.settings.get_sda_limit_switch_reverse()\ntic.settings.get_sda_pin_function()\n# TX\ntic.settings.get_tx_active_high()\ntic.settings.get_tx_config()\ntic.settings.get_tx_enable_analog()\ntic.settings.get_tx_kill_switch()\ntic.settings.get_tx_limit_switch_forward()\ntic.settings.get_tx_limit_switch_reverse()\ntic.settings.get_tx_pin_function()\n# RX\ntic.settings.get_rx_active_high()\ntic.settings.get_rx_config()\ntic.settings.get_rx_enable_analog()\ntic.settings.get_rx_kill_switch()\ntic.settings.get_rx_limit_switch_forward()\ntic.settings.get_rx_limit_switch_reverse()\ntic.settings.get_rx_pin_function()\n# RC\ntic.settings.get_rc_active_high()\ntic.settings.get_rc_config()\ntic.settings.get_rc_kill_switch()\ntic.settings.get_rc_limit_switch_forward()\ntic.settings.get_rc_limit_switch_reverse()\n\n# Motor ---------------------------------------------------------\ntic.settings.get_current_limit()\ntic.settings.get_decay_mode()\ntic.settings.get_invert_motor_direction()\ntic.settings.get_max_acceleration()\ntic.settings.get_max_deceleration()\ntic.settings.get_max_speed()\ntic.settings.get_starting_speed()\ntic.settings.get_step_mode()\n\n# Homing --------------------------------------------------------\ntic.settings.get_auto_homing()\ntic.settings.get_auto_homing_forward()\ntic.settings.get_homing_speed_away()\ntic.settings.get_homing_speed_towards()\n\n# T249-only -----------------------------------------------------\ntic.settings.get_agc_bottom_current_limit()\ntic.settings.get_agc_current_boost_steps()\ntic.settings.get_agc_mode()\ntic.settings.get_agc_frequency_limit()\n\n# 36v4-only -----------------------------------------------------\ntic.settings.get_hp_current_trip_blanking_time()\ntic.settings.get_hp_decay_mode()\ntic.settings.get_hp_enable_adaptive_blanking_time()\ntic.settings.get_hp_enable_unrestricted_current_limits()\ntic.settings.get_hp_fixed_off_time()\ntic.settings.get_hp_mixed_decay_transition_time()\n```\n\nModifying settings is currently not supported.\n\nFor more details, see the official [settings reference](https://www.pololu.com/docs/0J71/6).\n\n# Version history\n\n## 0.3.0 (April 19, 2025)\n\n- Added a `.pyi` file for IDE/editor autocompletion and convenient documentation references.\n- Added support for Circuit Python\n- Fixed a bug with `set_current_limit()`\n- Handle gracefully a serial read returning `None`\n\n## 0.2.2 (May 14, 2021)\n\n- Fixed some bugs for Micropython\n\n## 0.2.1 (May 4, 2021)\n\n- Issue #1: Fixed bug that prevented multiple Tic controllers from working at the same time.\n\n## 0.2.0 (April 20, 2021)\n\n- Added support for Micropython with serial and I2C.\n\n## 0.1.0 (April 18, 2021)\n\nInitial release.\n\n# Running the tests\n\nFor Python:\n\n```shell\ndocker run -it -v ${PWD}:/base -w /base python python /base/tests/tests.py\n```\n\nFor Micropython:\n\n```shell\ndocker run -it -v ${PWD}:/base -w /base mitchins/micropython-linux micropython /base/tests/tests.py\n```\n\nFor CircuitPython:\n\n```\ndocker run -it -v ${PWD}:/base -w /base jphalip/circuitpython-linux micropython /base/tests/tests.py\n```\n\n# Notes for project maintainers\n\nTo release a new version of this library:\n\n- Create a virtualenv and install the dependencies in `requirements.txt`\n- Update version number in `src/ticlib/__init__.py`\n- Add release notes in the \"Version history\" section above.\n- Create and push tag of the form: `v\u003cVERSION_NUMBER\u003e` (e.g. `v.0.2.1`)\n- Delete existing `dist/` directory, if any.\n- Run: `python3 -m build`\n- Run: `python3 -m twine upload dist/*`\n","funding_links":[],"categories":["Libraries"],"sub_categories":["Motion"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjphalip%2Fticlib","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjphalip%2Fticlib","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjphalip%2Fticlib/lists"}