Ticlib: New Python library for driving Tic controllers

Hi,

TL;DR: I released a new Python library for Tic controllers: GitHub - jphalip/ticlib: Python library to drive Pololu Tic stepper motor controllers — Feedback welcome!

I recently got my first Tic controller and started looking into ways to write Python programs for it. I found the existing PyTic library but that only works on Windows and I use a Mac and a Raspberry PI. I also wanted to drive the controller using serial and I²C, not just USB. So I fell into a rabbit hole and wrote a new little library :slight_smile:

The library is called ticlib. It’s available on Github (GitHub - jphalip/ticlib: Python library to drive Pololu Tic stepper motor controllers) and can be installed by running “pip install ticlib”.

I’ve currently tested it on the following platforms:

  • Raspberry PI with USB, serial, and I²C.
  • Mac with USB and with serial via a USB-to-serial adapter.

Let me know if you are able to run it on other platforms or if you run into any issues.

Wanted to share it in case it’s useful to other people. Feel free to try it out. Feedback and contributions welcome!

Cheers,

Julien

5 Likes

Hello, Julien.

Thank you for making this library and releasing it. I’m sure it will be useful to other Tic users. We added a link to it in the “Writing PC software to control the Tic” section of the Tic user’s guide.

–David

1 Like

Thank you David, that’s great!

As an aside, I’ve just added support for Micropython, so it now works for boards like the Raspberry Pi Pico as well.

2 Likes

Hi Julien,

Thank you for this.

Maybe you can help me through an issue I’ve been trying to work through for the last couple of days. I’m trying to connect two T825 controllers through i2c:

address_1 = 14
backend_1 = SMBus2Backend(bus, address_1)
tic1 = TicI2C(backend_1)

address_2 = 15
backend_2 = SMBus2Backend(bus, address_2)
tic2 = TicI2C(backend_2)

I can confirm my TicI2C objects have the assigned address (matching that assigned through ticgui) using:

print(tic1.backend.address)
print(tic2.backend.address)

However, when i try to move them (or get_variables), for example:

tic1.set_target_position(2000)
tic2.set_target_position(-2000)

the stepper with address 15 executes both commands (or prints its variables). If I assign address 15 to tic1 and 14 to tic2 then the other motor performs both commands, in other words, the last assigned address executes both commands. I have also tried connecting the controllers on different buses.

Being a relative newb, I’m not sure if I’m doing something wrong or if there is an issue with the library.

Hi there,

Yes indeed, that’s a bug that was just reported by a user on GitHub a few days ago and I’ve since pushed a fix for it. Could you update to the latest version and try again?

Thanks!

Julien

indeed, thanks alot

Thank you for your generous contribution, Julien. I have been posting in another thread (Raspberry Pi connect to tic with I2C) and getting nowhere, but after implementing your example with my hardware I am finally over the hurdle. I am using I2C over the GPIO pins 23 and 24, and it works like a charm. I had to combine the short I2C example you provided with the example code, which is obvious enough. I did find one additional thing that needed to be adjusted in the example to make it work – backend=SMBus2Backend(bus) needs to include the address as a second argument. Here is the adjusted code:

from smbus2 import SMBus
from ticlib import TicI2C, SMBus2Backend
from time import sleep

bus = SMBus(3)  # Represents /dev/i2c-3
address = 14    # Address of the Tic, that is its device number
backend = SMBus2Backend(bus, address)

tic = TicI2C(backend)

tic.halt_and_set_position(0)
tic.energize()
tic.exit_safe_start()

positions = [500, 300, 800, 0]
for position in positions:
    tic.set_target_position(position)
    while tic.get_current_position() != tic.get_target_position():
        sleep(0.1)

tic.deenergize()
tic.enter_safe_start()