Pololu Robotics & Electronics
Menu
My account Comments or questions? About Pololu Contact Ordering information Distributors

Pololu Forum

Reading variables from Tic T825

#1

Hello, I am using a Tic T825 to control a stepper motor. The stepper accepts my write commands through the smbus and the I2C address for my device. The trouble I am having is getting any useful data returned when I want to read from a variable.
Here is a sample of my code with small GUI for user-control.

from tkinter import *
import tkinter
from smbus2 import SMBus, i2c_msg

# Reset
stepper_reset = 0xB0
# Set velocity
stepper_velocity = 0xE3
# Energize
energize = 0x85
# Denergize
de_energize = 0x86

# Class of variables
class Vars():
   position = 0
   control = 0

v = Vars()

# Establishes class for I2C commmunication
class TicI2C(object):
   def __init__(self, bus, address):
       self.bus = bus
       self.address = address

   # Sets the target position.
   def set_target_position(self, target):
       command = [0xE0,
         target >> 0 & 0xFF,
         target >> 8 & 0xFF,
         target >> 16 & 0xFF,
         target >> 24 & 0xFF]
       write = i2c_msg.write(self.address, command)
       self.bus.i2c_rdwr(write)

   # Gets one or more variables from the Tic.
   def get_variables(self, offset, length):
       write = i2c_msg.write(self.address, [0xA1, offset])
       read = i2c_msg.read(self.address, length)
       self.bus.i2c_rdwr(write, read)
       return list(read)

   # Gets the "Current position" variable from the Tic.
   def get_current_position(self):
       b = self.get_variables(0x22, 4)
       position = b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24)
       if position >= (1 << 31):
         position -= (1 << 32)
       return position

# Declaration and intialization of smbus variable
bus = SMBus(1)
# Declaration of TicI2C instance
tic = TicI2C(bus, 0x11)

# Function to print position
def print_position():
   print(tic.get_variables(0x22,4))

# Function to reset stepper
def reset_stepper():
   tic.bus.write_byte(tic.address,stepper_reset)
   v.position=0

def exit_stepper():
   tic.bus.write_byte(tic.address,de_energize)
   v.control = 1

def increase_position():
   tic.set_target_position(v.position+100)
   v.position+=100

def decrease_position():
   tic.set_target_position(v.position-100)
   v.position-=100

# Initially energizes the motor
tic.bus.write_byte(tic.address,energize)

# Creates frame for GUI
root = Tk()
root.title('Stepper Motor Variable Retrival')
root.geometry('300x300')

btt_reset = Button(root,text='reset',command=reset_stepper)
btt_reset.place(x=200,y=20)

btt_exit = Button(root,text='exit',command=exit_stepper)
btt_exit.place(x=200,y=50)

lbl_position = Label(root,text=v.position)
lbl_position.place(x=20,y=50)

btt_inc_position = Button(root, text='+100',command=increase_position)
btt_inc_position.place(x=60,y=30)

btt_dec_position = Button(root, text='-100',command=decrease_position)
btt_dec_position.place(x=60,y=70)

# Button to print position
btt_print_position = Button(root,text='print position', command=print_position)
btt_print_position.place(x=60,y=100)

# Button to print current position returned from TicI2C function
btt_current_position = Button(root,text='Current Position from TicI2C',
                             command=lambda:print(tic.get_current_position()))
btt_current_position.place(x=60,y=130)

# Update loop dependant on v.control
while v.control == 0:
   root.update_idletasks()
   root.update()
   lbl_position.config(text=v.position)

# Destroys the frame of the gui
root.destroy()
   
#2

Hello.

Can you elaborate on what return values you are seeing and what you expect? What are you using to control the Tic via I2C? Can you post pictures of your setup clearly showing how everything is connected in your setup?

- Amanda

#3

The get_variables function of the TicI2C class returns a list of 255 values; I specifically have used offsets 0x22 and 0x26, the offset for current position variable and the offset for current velocity variable, with lengths 4. The value returned for either offset is a list of 255 for the specified length. If the get_current_position function is used, a -1 is returned. I expect the current position value to change when the target position is changed and reached, and I expect to see the current velocity value to change when I write values to the set velocity command and be zero when I set it to zero. The code for velocity is not included in the provided code, but it function properly besides the write. I am using a Raspberry Pi to control multiple Tic T825s, each with their own stepper motor. I can provide photos of how everything is connected in my setup. I hope that is sufficient information for you to assist me.

#4

It looks like you are using the Raspberry Pi’s hardware I2C module, which has a known bug that prevents it from working reliably. Can you disconnect your Tic boards from your Raspberry Pi except for one and try running the example code in the “Example I2C code for Linux in Python” section in the Tic’s user’s guide? Please make sure to follow the instructions at the top of that section for setting up I2C on your Raspberry Pi and let us know the results.

- Amanda