A HITI Motor Group is a variable which lets you synchronize the motions of several HITI Servos moving at the same time (they start and stop their motions at the same time). To synchronize the motions of several Servos, simply put them in the same Motor Group (available for Finite Motions only, not for Continuous Motions).
To illustrate this, let’s synchronize 3 Servos by adding them to the same Motor Group. We will make a back-and-forth motion sequence of all the servos.
Sketch
Upload this 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 to control and monitor the Motor Group from HITIPanel :
- Current position of all Servos
- Max speed of Servo 1
- Target motion time of the Group
- “START” and “STOP” buttons
- 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 buttons 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 display its initial value in HITIPanel. As we will see after, the max speed of one of the Servo can impact the whole Group.
void setup() { // 1) initialize library HC_begin(); // 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 group.init(3); group.add(&servo_1); group.add(&servo_2); group.add(&servo_3); // 4) set max speed of Servos, if required (affect motion time) servo_1.maxSpeed(100); // °/s // 5) display initial values of the control parameters in 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 else step = 0; // go to step 0 }
Inside the loop(), we start by reading the value of the max speed of Servo 1 set from HITIPanel and we apply it.
void loop() { // communicate with HITIPanel HC_communicate(); // set new control parameters -------------------------------------------- // read from HITIPanel maxSpeed_S1 = HC_analogDataRead(ad_maxSpeed_S1); // set max speed (servo 1) servo_1.maxSpeed(maxSpeed_S1);
Next, the motion sequence is started if the “START” button is clicked and if the sequence is ready to start (step 0).
Immediately after, we check if the “STOP” button is clicked to know if the sequence must be stopped. The sequence can be stopped at any steps and at any moment. The STOP has priority over the processing of steps 1 to 4, therefore 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).
// start/stop motion sequence -------------------------------------------- // step 0: ready to start sequence with the START button if((step == 0) && HC_digitalDataRead(dd_Start)) { step = 1; // start sequence } // at any step: stop sequence with the STOP button if(HC_digitalDataRead(dd_Stop)) { 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 group.moveNow(); // when motion ends if(group.isEnding()) onMotionDone(); } // 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 group.moveNow(); // when motion ends if(group.isEnding()) onMotionDone(); } // deactivate the Virtual Buttons HC_digitalDataWrite(dd_Start, false); HC_digitalDataWrite(dd_Stop, false);
Finally, we display the following data in HITIPanel:
- Sequence step
- Position (Target, Current) of all Servos
- Motion time (Target) of the Group
- Group state (Ready or Moving)
// display data in 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()); }
Control Panels
1) Display the 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.
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 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?
That’s Great!
Thank you for your feedback
Sorry! We couldn't be helpful
Thank you for your feedback
Feedback sent
We appreciate your effort and will try to fix the article