Tic 834 , drive more than 127 stepper motor

Hello,
I would like use more than 127 stepper motor with a lot of Tic 834,
Would you have an examplefor arduino to use the pololu protocol to use the command
thank you
alain

Hello.

You can enable the 14-bit device number option on the Tic to use more than 127 of them on the same serial bus. Unfortunately, our Arduino library for the Tic controllers does not have support for 14-bit device numbers yet, so you would need to write your own function for sending those commands.

As described in the “Serial command encoding” section of the Tic user’s guide, when using a 14-bit device number, you will need to send 2 bytes to specify the device number instead of 1. Both of these bytes are between 0 and 127: the first byte holds the lower 7 bits of the device number and the second byte holds the upper 7 bits. The full byte sequence for a 7-bit write command using the Pololu protocol becomes:

0xAA, Device number low bits, Device number high bits, Command (with MSB cleared), Data

Arduino code for splitting the device number into two the lower 7 bits and upper 7 bits would look something like this:

int deviceNumber = 1023; //Can be anywhere from 0 to 16383

uint8_t deviceNumberLower = deviceNumber & 0x7F;
uint8_t deviceNumberUpper = (deviceNumber >> 7) & 0x7F;

Brandon

Thank you Brandon,
Could you show me a little bit of code to sent for exemple
for the tic no 1000, set targetposition at 200
thank you
alain

The format of the “Set target position” command is 32-bit write, so it will start with 0xAA then the device number bytes (like all Pololu Protocol commands), then the command byte with the MSB clear, and then the 5 data bytes, as described in the “Serial command encoding” section of the Tic user’s guide.

int deviceNumber = 1000; //Can be anywhere from 0 to 16383

uint8_t deviceNumberLower = deviceNumber & 0x7F;
uint8_t deviceNumberUpper = (deviceNumber >> 7) & 0x7F;

int32_t target = 200;

uint8_t msb = ((target >> 7) & 1) | ((target >> 14) & 2) | ((target >> 21) & 4) | ((target >> 28) & 8);
uint8_t data1 = (target >> 0) & 0x7F;
uint8_t data2 = (target >> 8) & 0x7F;
uint8_t data3 = (target >> 16) & 0x7F;
uint8_t data4 = (target >> 24) & 0x7F;

//start byte
Serial.write(0xAA);

//14-bit device number
Serial.write(deviceNumberLower); 
Serial.write(deviceNumberUpper);

//0xE0 command byte with MSB cleared
Serial.write(0x60); 

//data bytes for target position
Serial.write(msb); 
Serial.write(data1); 
Serial.write(data2);
Serial.write(data3);
Serial.write(data4);

Brandon

Thanks a lot Brandon

Your code help me , it’s great.

But i ‘am not sure for the code of 4 commands in 32 bit

how would be the code for:

  • TicSerial tic1000(ticSerial, 1000);

  • tic1000.haltAndsetPosition(0);

  • tic1000.exitSafeStart;

  • tic1000.setMaxSpeed(100000000);

Thank you

Alain

The only thing that needs to change for the code I posted above to work for other commands that use the “32-bit write” format is the command byte. So for “halt and set position” and “set max speed”, the code would look the same as what I posted before, except the command byte would be 0x6C (which is 0xEC with the MSB cleared) and 0x66 (which is 0xE6 with the MSB cleared), respectively. You can find the “Type” and “Command byte” for each available command in the “Command reference” section of the Tic user’s guide.

However, please note that the “exit safe start” command does not use a 32-bit write format. It uses a “Quick” format. So, there are no data bytes and the command ends after the command byte (i.e. 0xAA, low 7 bits of device number, upper 7 bits of device number, 0x03).

The first “command” you listed, TicSerial tic1000(ticSerial, 1000); is calling a class in our Arduino library that creates a new TicSerial object. That object essentially takes care of setting up the serial communication and associating the provided device number to that object (so you do not have to specify it each time you call a command from the library)

Brandon

Thank you Brandon ,
I will try what you say me
thank’s a lot
Best regards
alain

Hello Brandon,

Thank you for helping me.
It ’s important for me that this code will go well, because i would like to command at pololu 400 x tic 500

I send my code wich doesnt work
what do you think and what is wrong
Thank you
Alain

#include <Tic.h>

#ifdef SERIAL_PORT_HARDWARE_OPEN
#define ticSerial SERIAL_PORT_HARDWARE_OPEN
#else
#include <SoftwareSerial.h>
SoftwareSerial ticSerial(18, 19); //pour arduino 2560 18 tx sur arduino (transmet) pour rx (reçois)sur le tic
#endif

TicSerial tic1000(ticSerial, 1000);

int deviceNumber;

void setup()
{
Serial.begin(9600);
// Set the baud rate.
ticSerial.begin(9600);

// Give the Tic some time to start up.
delay(20);

moteurplus(1000,0xEC,0);//haltandsetposition avec plus de 127 moteurs
exitsafedebut(1000);//exitsafestart avec plus de 127 moteurs

}

void loop()
{

moteurplus(1000,0xE6,1000000);//setMaxSpeed(1000000) avec plusde 127 moteur

moteurplus(1000,0xE0,-10000);// set target position

delay(30000);

moteurplus (1000,0xEC,0);// set and hold position

delay(2000);

}

//*************************** commande avec plus que 127 moteurs*******************************
void moteurplus(int deviceNumber,uint8_t command,int32_t target)
{
//deviceNumber = 1000; //Can be anywhere from 0 to 16383

uint8_t deviceNumberLower = deviceNumber & 0x7F;
uint8_t deviceNumberUpper = (deviceNumber >> 7) & 0x7F;

//int32_t target = 200;

uint8_t msb = ((target >> 7) & 1) | ((target >> 14) & 2) | ((target >> 21) & 4) | ((target >> 28) & 8);
uint8_t data1 = (target >> 0) & 0x7F;
uint8_t data2 = (target >> 8) & 0x7F;
uint8_t data3 = (target >> 16) & 0x7F;
uint8_t data4 = (target >> 24) & 0x7F;

//start byte
Serial.write(0xAA);

//14-bit device number
Serial.write(deviceNumberLower);
Serial.write(deviceNumberUpper);

//0xE0 command byte with MSB cleared // set target position = 0xE0
uint8_t commandmsbclear = command & 0x7F;
Serial.write(commandmsbclear);

//data bytes for target position
Serial.write(msb);
Serial.write(data1);
Serial.write(data2);
Serial.write(data3);
Serial.write(data4);

}
// **********exit safe start**********
void exitsafedebut(int deviceNumber){
uint8_t deviceNumberLower = deviceNumber & 0x7F;
uint8_t deviceNumberUpper = (deviceNumber >> 7) & 0x7F;

//start byte
Serial.write(0xAA);
//14-bit device number
Serial.write(deviceNumberLower);
Serial.write(deviceNumberUpper);

// command
Serial.write(0x03);

}

Ok Brandon

All is good now. i have change this

#include <SoftwareSerial.h>
SoftwareSerial Serial1(18, 19); //pour arduino 2560 18 tx sur arduino (transmet) pour rx (reçois)sur le tic
#endif

and this
Serial1.write

it’s perfect , and i don’t need now the tic.h

so i will make a lot of test and i will command you 2 or 300 tic500
i hope you will make me a good price for all these items
thank you
alain

1 Like

I am glad you got your code working; thank you for letting us know.

I suggest expanding your system slowly, as troubleshooting hundreds of connections will be very difficult if you have problems.

If you are purchasing the Tic T500 controllers directly from us, you can contact us at sales@pololu.com to discuss special volume pricing.

Brandon

Hi,
I saw this post which relates to my problem of controlling 100’s of stepper motors.
I don’t know much about your controllers and to be honest did not understand your response to op.
Do Tic controllers are one controller for each stepper or they can handle multiple steppers ?
Are they like Maestro where you can record a “scenario” (movements) for each stepper ?
I’d appreciate your help on the hardware needed for my project.

Hello.

Each Tic controller can independently control a single stepper motor. If you do not need independent control, you could connect more than one stepper motor in series or parallel to a Tic, but if you are not familiar with how these setups work, I recommend researching it first to make sure you configure it properly.

The Tic controllers cannot store sequences of movements like the Maestro, although scripting features are something we would still like to add at some point in the future. For now, if you want to control many Tic controllers, you can use a separate microcontroller (such as an Arduino or one of our Arduino-compatible A-Star controllers) to programming your own sequences and control the Tics through their I²C or TTL serial interface.

Brandon

Thank you. Unfortunately, I need independent control of each servo.

Hello Brandon

I’am using 120x tic 500 that i ordered one month ago
I’am using them to make something like the kinetic rain
https://www.youtube.com/watch?v=NXuQnDeIyY8

the project go well,
but I would like to calculate the speed and the acceleration to give to the tick so that each motor arrives at the same time at the place I want.
for example if a motor has to go from 0 to 2000 in 2 sec and another motor has to go from 0 to 1000 also in 2 sec, it is easy to calculate the speed to give to these two motors.
Where it is more complicated is that I would like that during for example the first and the last quarter of the 2 seconds that there is an acceleration and a deceleration respectively, then during the second and the third quarter of the 2 seconds constant speed
so what I would like to be able to calculate is the speed and the accelaration to give for total distance = x in a time t

thank you for your support

Alain Haerri

Hello, Alain.

I am excited to hear that your project is going well and would love to see some videos when you are ready to share.

Please note that:

  • The Tic is not designed to support perfectly synchronized motion of multiple motors.
  • The formulas in this post are approximations; there will be some inaccuracy caused by the discrete nature of the calculations the Tic has to do.
  • I will assume that you are leaving the Tic’s starting speed set to 0 since that makes the math easier.

If you are commanding the Tic to move x steps with a maximum acceleration of a, maximum deceleration of d, and with a maximum speed of v, and the Tic actually does reach its maximum speed, then the time T it takes to do the movement (in seconds) will be:

T = 10000 \cdot \frac{x}{v} + \frac{v}{200 \cdot a} + \frac{v}{200 \cdot d}

In this case, the time spent accelerating is 100 \cdot v/a and the time spent decelerating is 100 \cdot v/d.

If the maximum speed is high enough so that the Tic does not actually reach it, then the formula for the total time becomes:

T = \sqrt{200 \cdot x \cdot \left ( \frac{1}{a} + \frac{1}{d} \right ) }

These formulas might help you come up with some good speed profiles.

Once you have a speed profile that you like, there are some simple rules you can use to adjust it.

  1. If you want to increase the number of steps by a factor of P while keeping the acceleration time, deceleration time, and total time the same, just multiply the maximum speed, acceleration limit, and deceleration limit by a factor of P.
  2. If you want to increase the acceleration time, deceleration time, and total time by a factor of Q while keeping the number of steps the same, then divide the maximum speed by Q, divide the acceleration limit by Q², and also divide the deceleration limit by Q².

–David

Hello David

Thanks a lot for your reply, i study what you propose
and i have this calculation, say me what youz think about

Thank you
Alain

I see that your “Path” variable has units of steps over 10000, so be sure to multiply any step counts by 10000 before plugging it into that formula.

The first error I see is that you have an extra factor of 100 in the first term of the upper left equation. To get the distance traveled during the acceleration phase (in the same units as Path), you would multiply the acceleration time t \cdot x by the average speed ( a \cdot t \cdot x \cdot 100 ) / 2. So there is only one factor of 100, and you do not square it.

By the way, I find it easier to use the normal math units (steps, steps per second, and steps per second squared) for most of my calculations. This allows me to simply multiply an acceleration by a time to get a change in velocity, and multiply a velocity by a time to get a number of steps. Then, in a later stage, I multiply any velocities by 10000 and multiply any accelerations by 100 to convert those numbers into the Tic’s units.

–David

Hello David

Thank you for your support.
I tried a lot of things this week-end , but without the succes i would like,

May be i havent explained you the exact problem.

  1. i would like for example : i give a path of 2000 on a motor and i give a path of 4000 to another motor , and i would that they reach the target at the same time

i have a good background with matematic and physic :
the formula for a path of x with a accelerationof a is x=1/2 a t*t + vt

for sure i multiply the velocity by 10000 and the acceleration by 100,

the result i have is that the 2 motor reachs the target a little in advance .

I can adjust the velocity or the time but i need to make this a lot of time and with different path,
so i need a formula to calculat the velocyty and the accélération i have to give to the tic for each path so the motors reach at the same time

If you have any suggestions

Thank you

Alain

Hello, Alain.

It sounds like you want one motor to move 2000 steps and another motor to move 4000 steps, and you want them both to start and stop their motions at the same time, but one of them is finishing faster.

The Tic is not designed to support perfectly synchronized motion of multiple motors, so if the time difference is pretty small then it might be hard to fix.

If you want us to look into this more, please provide all the relevant details about your system’s configuration, how you are controlling it, and how you are measuring its behavior. (Can you post a video?) I also recommend simplifying your system as much as possible and making sure you are sending the two “Set target position” commands as quickly as possible with no other commands in between.

–David

835
/ 5000
<> <>
Résultats de traduction
Thank you David for your response.

In the meantime I understood what was wrong.
The formulas I use for you to calculate the speed and acceleration are correct (1 / 2at * t + vt = path)
what was wrong is the delay I give after sending the commands to both motors, I gave a delay equal to T, but in fact it must be a little shorter because the calculation instructions also take time.
Now it works fine.

Now my question is:
Is it possible to send an instruction to the tic while the motor is already effecting a trip.
Does the tick already finish the path to be performed before taking charge of the following instructions? or does the tick stop the current trip to immediately stop the next instruction.

Thank you for your support