Tic T825 I2C help

Hi,

I’m trying to control the T825 using a Nucleo F411re board and I’m having some trouble getting it to work. One question I had was how to set a negative speed? In the Arduino example, it is simply set as -200000. If I’m sending the binary value, would it be in 2s complement?

Thanks

Hello.

Yes, when sending a negative value (for commands that accept them) you should use two’s complement. It sounds like you are talking about using the Set Target Velocity command (the “max speed” setting is always positive). As detailed in the “Command reference” section of the Tic user’s guide, the Set Target Velocity command uses a signed 32-bit value for the data, and has a valid range between -500,000,000 to 500,000,000.

For reference, using the “32-bit write” format and the compact protocol, the bytes for setting the target velocity to -200000 would be the following:

Cmd: 0xE3
MSBs: 0x0F
data 1: 0x40
data 2: 0x72
data 3: 0x7C
data 4: 0x7F

Brandon

Another thing I’m confused about:

The user guide for I2C shows that the sequence is: addr + Wr, wait for acknowledge, then send the command, wait for acknowledge, then send the data bytes.

When I’m programming the microcontroller, do I have to send an addr + Wr command? Or do I just write the command to 0x1C (addr+Wr)?

Sorry if I’m not explaining this correctly. Please let me know if I can clarify.

Thanks!

Sorry, I just found the section which explains how we get the MSB and data byte values. Just to confirm, if I want to send a 900000 speed setting, it would be:

msb = 0x3
data1 = 0x20
data2 = 0x3B
data3 = 0xD
data4 = 0x0

And -900000 would be:
msb= 0xC
data1 = 0x60
data2 = 0x44
data3 = 0x72
data4 = 0x7F

Right?

I’m still not able to get it to run though, and the LED blinking is indicating the motor is deenergized and there is an error aside from safe start violation. How would you recommend going about figuring out which error it could be?

Cheers

Hello.

Sorry for the confusion; my breakdown of the bytes in my previous post was for TTL serial. I missed that you were talking about I²C.

You can see how the I²C commands are encoded in the “I²C command encoding” section of the Tic user’s guide.

The default I²C address for the Tic is 0x0E (0001110 in binary). As specified by the I²C standard, a transfer’s address byte consists of the 7-bit slave address followed by another bit to indicate the transfer direction (0 for a write and 1 for a read). Since the set target velocity command is a write (and not a read) the 0 is added to the 7-bit address and becomes 00011100 (0x1C in hex).

Next is the command, which for set target velocity is 0xE3.

Finally, the four data bytes, which contain the 32-bit value in little-endian order (starting with the least-significant byte). The two’s compliment binary conversion for -200000 is: 11111111 11111100 11110010 11000000. You can get this by taking the binary representation of the absolute value (200000):

00000000 00000011 00001101 01000000

inverting the bits:

11111111 11111100 11110010 10111111

and adding one:

11111111 11111100 11110010 11000000

So the data bytes are:

data 1: 11000000 (0xC0)
data 2: 11110010 (0xF2)
data 3: 11111100 (0xFC)
data 4: 11111111 (0xFF)

Brandon

Thanks Brandon, that makes sense.

Still having some trouble getting it to run. Would you mind having a look over my code and see if you can spot any obvious errors?

Main loop:

setup();
while(1){
	settargetvelocityfor();
        delaywhileresetting(2000);
	 settargetvelocityback();
  	delaywhileresetting(2000);
	  }

Functions:

void resetcommandtimeout(void){
uint8_t command = 0x8C;
uint8_t command0 = (0x1C);
HAL_I2C_Master_Transmit(&hi2c2, command0, &command, 1, HAL_MAX_DELAY);
}

void exitsafestart(void){
uint8_t command = 0x83;
uint8_t command0 = (0x1C);
HAL_I2C_Master_Transmit(&hi2c2, command0, &command, 1, HAL_MAX_DELAY);

}

void energize(void){
uint8_t command = 0x85;
uint8_t command0 = (0x1C);
HAL_I2C_Master_Transmit(&hi2c2, command0, &command, 1, HAL_MAX_DELAY);
}

void setup(void){
	HAL_Delay(20);
	exitsafestart();
	energize();
}

void delaywhileresetting(uint32_t ms){

  uint32_t start = HAL_GetTick();
  resetcommandtimeout();
  uint32_t comp = HAL_GetTick();

  resetcommandtimeout();
  while ((comp - start) <= ms){
	  resetcommandtimeout();
	  comp = HAL_GetTick();
  }
}

void settargetvelocityfor(void){
  uint8_t command0 = (0x1C);
  uint8_t command1 = 0xE3;
  uint8_t command2 = 0x40;
  uint8_t command3 = 0xD;
  uint8_t command4 = 0x3;
  uint8_t command5 = 0x0;

  HAL_I2C_Master_Transmit(&hi2c2, command0, &command1, 1, HAL_MAX_DELAY);

  HAL_I2C_Master_Transmit(&hi2c2, command0, &command2, 1, HAL_MAX_DELAY);

  HAL_I2C_Master_Transmit(&hi2c2, command0, &command3, 1, HAL_MAX_DELAY);

  HAL_I2C_Master_Transmit(&hi2c2, command0, &command4, 1, HAL_MAX_DELAY);

  HAL_I2C_Master_Transmit(&hi2c2, command0, &command5, 1, HAL_MAX_DELAY);

}

void settargetvelocityback(void){

  uint8_t command0 = (0x1C);
  uint8_t command1 = 0xE3;
  uint8_t command2 = 0xC0;
  uint8_t command3 = 0xF2;
  uint8_t command4 = 0xFC;
  uint8_t command5 = 0xFF;

  HAL_I2C_Master_Transmit(&hi2c2, command0, &command1, 1, HAL_MAX_DELAY);

  HAL_I2C_Master_Transmit(&hi2c2, command0, &command2, 1, HAL_MAX_DELAY);

  HAL_I2C_Master_Transmit(&hi2c2, command0, &command3, 1, HAL_MAX_DELAY);

  HAL_I2C_Master_Transmit(&hi2c2, command0, &command4, 1, HAL_MAX_DELAY);

  HAL_I2C_Master_Transmit(&hi2c2, command0, &command5, 1, HAL_MAX_DELAY);

}

Thanks again for all the help. Hopefully we can get this running.

Just to add: When I plug the USB and open the Tic software, I get “Motor holding because of serial error”. From the error handling section of the guide (Pololu - 5.4. Error handling), I’m assuming this means I am sending an incorrect command? Not sure where it could be.

Also, is there any problem with keeping the USB plugged in while controlling the tic board with i2c? As in, will the two protocols interfere with each other?

Thanks!

Hello.

The errors are probably being caused by the way you are calling HAL_I2C_Master_Transmit for each byte you are sending. Instead, you should try putting the data in an array with the “size” argument specifying the length of the array. For example, something like this:

void settargetvelocityfor(void){
  uint8_t writeAddress = 0x1C;
  uint8_t data[5] = {0xE3, 0x40, 0x0D, 0x03, 0x00};

HAL_I2C_Master_Transmit(&hi2c2, writeAddress, data, 5, HAL_MAX_DELAY);
}

It is fine to have the Tic connected to USB while controlling it via I2C. Monitoring the Tic using the Tic Control Center while your system is running is a great way to see what is going on and troubleshoot issues.

Brandon

1 Like

It worked! Thank you so much, you’ve been extremely helpful!

1 Like