Synchronized group

A HITI Motor Group is a variable which lets you synchronize the motions of several HITI Servos moving at the same time, which means they start and stop their motions at the same time. When you need to synchronize the motions of several Servos (for Finite Motions only), simply put them in the same Group.

In this example, 3 Servos are added to the same Group and are then automatically synchronized: when the Group moves, all its Servos moves synchronously. A back-and-forth motion sequence of all the Servos is performed here.


1) Sketch: 5_MotionControl \ 4_SynchronizedGroup

We start our code by including the HC_Servo.h and HC_MotorGroup.h libraries, and by creating 3 HITI Servo variables and 1 HITI Motor Group variable.

We also assign several HITI Data to different control parameters for controlling and monitoring the Groups from HITIPanel :

  • Current position of all Servos
  • Max speed of Servo 1
  • Target motion time of the Group
  • “START” and “STOP” virtual switches
  • State of the Group (can be Ready or Moving)

Finally, we create a variable called step whose value represents the number of the step being executed during the motion sequence. Step will take the values 0 to 2.

#include <HITIComm.h>
#include <HC_Servo.h>
#include <HC_MotorGroup.h>

// pins assignment 
const int pin_Servo_1 = 8;  // servos
const int pin_Servo_2 = 9;
const int pin_Servo_3 = 10;

// Analog Data assignment
const int ad_Step         = 0; // sequence step
const int ad_Position_S1  = 1; // current positions (Servos 1-3)
const int ad_Position_S2  = 2;
const int ad_Position_S3  = 3;
const int ad_maxSpeed_S1  = 4; // max speed (Servo 1)
const int ad_motionTime_G = 5; // motion time (Group)

// Digital Data assignment
const int dd_Start        = 0; // virtual switches
const int dd_Stop         = 1;
const int dd_isReady_G    = 2; // group state
const int dd_isMoving_G   = 3;

// motion sequence in 5 steps: 0 (Ready), 1-2 (Motions)
int step = 0;

// max speed (servo 1)
float maxSpeed_S1 = 100.0;

// HITI Motor Group
HC_MotorGroup group;

// HITI Servo
HC_Servo servo_1;
HC_Servo servo_2;
HC_Servo servo_3;

During the setup(), we start by initializing the 3 Servos individually and by giving them different servo IDs (1, 2 and 3). These IDs will be used by the Group to address them.

Next, we initialize the Group by specifying that it will contain exactly 3 Servos, and we add the Servos to it.

Finally, we set the max speed of Servo 1 and we send its initial value to HITIPanel to update its display in the control panels. The max speed of a Servo can impact the motion time of the whole Group it belongs to.

// run once at power on
void setup()
    // 1) initialize library

    // 2) initialize HITI Servos
    // param: servo ID, pin, invert direction, position offset, absolute init position
    servo_1.init(1, pin_Servo_1, true,  3,  20);
    servo_2.init(2, pin_Servo_2, false, -1, 40);
    servo_3.init(3, pin_Servo_3, false, 0,  60);
    // 3) initialize HITI Motor Group and add Servos to it

    // 4) set max speed of Servos, if required (affect motion time)
    servo_1.maxSpeed(100); // °/s

    // 5) send initial values of control parameters to HITIPanel
    HC_analogDataWrite(ad_maxSpeed_S1, maxSpeed_S1); // max speed (servo 1)

We then prepare the function onMotionDone() that will be called each time a motion ends.  Its role is to update the steps to create the motion sequence.

// called each time a motion ends
void onMotionDone()
    // at end of steps 0-1
    if (step < 2)
        step++;   // go to next step
    // at end of step 2
        step = 0; // go to step 0

Inside the loop(), we start by retrieving the value of the max speed of Servo 1 set through HITIPanel and we apply it.

// run repeatedly after setup()
void loop()
    // communicate with HITIPanel

    // set new control parameters --------------------------------------------

    // read from HITIPanel
    maxSpeed_S1 = HC_analogDataRead(ad_maxSpeed_S1);

    // set max speed (servo 1)

Next, the motion sequence is started when the “START” virtual switch is activated and if the sequence is ready to start (step 0).

Immediately after, we check if the “STOP” virtual switch is activated to know if the sequence must be stopped. The sequence can be stopped at any steps and at any moment. The STOP action has priority over the processing of steps 1 to 4, this is why it is checked before executing these steps.

The sequence steps are executed one after the other. At each step, the Servos perform a synchronized motion. Their positions are set individually using relativePosition(servo ID, setpoint), and the Group motion time is set using motionTime(time).

We systematically deactivate the virtual switches at the end of the program as we don’t want them to remain activated.

    // start/stop motion sequence --------------------------------------------
    // step 0: ready to start sequence with the START virtual switch
    if((step == 0) && HC_digitalDataRead(dd_Start))
        step = 1; // start sequence
    // at any step: stop sequence with the STOP virtual switch
        group.stopNow(); // stop group
        step = 0;          // reset sequence
    // step 1
    else if(step == 1)
        // move group
        group.relativePosition(1, 10);  // Servo 1: +10°
        group.relativePosition(2, 50);  // Servo 2: +50°
        group.relativePosition(3, 90);  // Servo 3: +90°
        group.motionTime(1.5);          // 1.5s
        // when motion ends
    // step 2
    else if(step == 2)
        // move group
        group.relativePosition(1, -10); // Servo 1: -10°
        group.relativePosition(2, -50); // Servo 2: -50°
        group.relativePosition(3, -90); // Servo 3: -90°
        group.motionTime(4);            // 4s
        // when motion ends
    // deactivate the Virtual Switches
    HC_digitalDataWrite(dd_Start, false);
    HC_digitalDataWrite(dd_Stop,  false);

Finally, we send all the data to HITIPanel:

  • Sequence step
  • Position (Target, Current) of all Servos
  • Motion time (Target) of the Group
  • Group state (Ready or Moving)
    // send data to HITIPanel ------------------------------------------------
    // sequence step
    HC_analogDataWrite(ad_Step, step);
    // current positions (servos)
    HC_analogDataWrite(ad_Position_S1, servo_1.getCurrentPosition());
    HC_analogDataWrite(ad_Position_S2, servo_2.getCurrentPosition());
    HC_analogDataWrite(ad_Position_S3, servo_3.getCurrentPosition());
    // motion time (group)
    HC_analogDataWrite(ad_motionTime_G, group.getMotionTime());
    // state (group)
    HC_digitalDataWrite(dd_isReady_G,  group.isReady());
    HC_digitalDataWrite(dd_isMoving_G, group.isMoving());


2) Control Panels

  1. Display the HITI DATA Control Panels.
  2. The Servos are at their initial positions and the Group is Ready to move.

  3. Click on “START” to start the motion sequence.

  4. Follow the motion sequence by looking at the step being executed. Also, check the motion time of each motion (should be 1.5s for motion 1 and 4s for motion 2).

  5. Change the max speed of Servo 1 to 2°/s and restart the motion sequence.

  6. As you can see, this parameter is affecting the motion times of the Group. Indeed, in order to respect the max speed of Servo 1, the Group had to increase its motion times accordingly. Both motion 1 and 2 have their time increased to 5s.

  7. Change the max speed of Servo 1 back to 100°/s.


3) Chart

  1. Open the Chart window.
  2. Start data acquisition. The servos positions are then plotted, and new data are added every 10ms and only the last 12s are displayed.
  3. In the HITI DATA Control Panels, click on “START” to start a new motion sequence.
  4. When the motion is finished, stop data acquisition. As you can see, the Servos start and stop moving at the same time: their motions are correctly synchronized.


Was this article helpful?
0 out of 0 found this helpful