Programation de 2 servomoteurs en rotation opposée

Bonjour à tous.

Je souhaiterais faire fonctionner deux servomoteurs en simultanée pour un système ouverture et fermeture d 'une boite en bois. Pour cela, les deux servomoteurs sont dos à dos, donc ils doivent tourner en rotation opposée. Je dois pouvoir aussi régler sur une vitesse pas trop élevé pour que ça s'ouvre doucement.

J'avais tout d'abord fait un code pour faire tourner les deux dans le même sens comme ci-dessous. Je n'avais pas pensé à la base qu'ils tourneraient en sens opposée. Après avoir essayé plusieurs modifications de code, je ne parviens toujours pas à faire fonctionner en simultanée quand je code avec les fonctions inversées sur le servogauche en partant d'un point initial à 90° pour aller à 0 et laissant le servodroite aller de 90° à 180°. ça me paraissait le plus simple, mais ça ne fonctionne pas.

Voici mon code d'origine:

/* Ouverture boite automatisée 2 servomoteurs */
// Inclure la librairie servomoteurs:
#include <Servo.h>
// Création des servomoteurs:
Servo servodroit;
Servo servogauche;
// Définir les entrées PIN:
#define servodroitPin 10
#define servogauchePin 9
// Création des variables de position initiale des servomoteurs:
int angle = 0;
void setup() {
 // Attribution des numéros de PIN:
 servodroit.attach(10);
 servogauche.attach(9);
}
void loop() {
 // Instructions d'angle des servomoteurs:
 servodroit.write(0);
 servogauche.write(0);
delay(1000);
 // Parcourir de 00 à 90 degrees:
for (angle = 0; angle <= 90; angle += 1) {
 servodroit.write(angle);
 servogauche.write(angle);
delay(80);
}
 // Instructions d'angle des servomoteurs:
 servodroit.write(90);
 servogauche.write(90);
delay(20000);
 // Retour en sens inverse de 90 à 0 degrees:
for (angle = 90; angle >= 0; angle -= 1) {
 servodroit.write(angle);
 servogauche.write(angle);
delay(80);
}
delay(10000);
}

Si quelqu'un peut m'aider à trouver une solution, ça m'aiderait vraiment. Une semaine que je cherche et impossible à faire fonctionner comme je veux.

Merci

Si un des servo va de 0) à 90°, pendant que l'autre va de 90° à 0°, il suffit de faire:

 servodroit.write(angle);
 servogauche.write(90-angle);

Merci pour cette solution. ça permet en effet de faire fonctionner en sens opposé, mais le servogauche part à toute vitesse à 90° avant de revenir à petite vitesse en sens inverse et repartir à grande vitesse à 90° , alors que le servodroit va directement à petite vitesse à la bonne position.
Il doit y avoir autre chose dans le code à changer:

/* Ouverture boite automatisée 2 servomoteurs */
// Inclure la librairie servomoteurs:
#include <Servo.h>
// Création des servomoteurs:
Servo servodroit;
Servo servogauche;
// Définir les entrées PIN:
#define servodroitPin 10
#define servogauchePin 9
// Création des variables de position initiale des servomoteurs:
int angle = 0;
void setup() {
 // Attribution des numéros de PIN:
 servodroit.attach(10);
 servogauche.attach(9);
}
void loop() {
 // Instructions d'angle des servomoteurs:
 servodroit.write(0);
 servogauche.write(0);
delay(1000);
 // Parcourir de 00 à 90 degrees:
for (angle = 0; angle <= 90; angle += 1) {
 servodroit.write(angle);
 servogauche.write(90-angle);
delay(80);
}
 // Instructions d'angle des servomoteurs:
 servodroit.write(90);
 servogauche.write(90);
delay(20000);
 // Retour en sens inverse de 90 à 0 degrees:
for (angle = 90; angle >= 0; angle -= 1) {
 servodroit.write(angle);
 servogauche.write(90-angle);
delay(80);
}
delay(10000);
}

Déjà, au départ, les 2 servos devraient, sans doute, être dans des positions différentes.
Il faudrait peut-être commencer par les positionner correctement dans setup(), .

Le programme, il fait ce que tu lui dis de faire
Regarde les commentaires que j'ai ajoutés

Bonjour euromagie

Une bibliothèque qui permet de régler la vitesse du servo, entre autres, est VarSpeedServo. Tu peux même faire des séquences et faire tourner le servo en mode bloquant ou pas. En non bloquant (wait) tu peux avoir tes 2 servo qui tournent en même temps.

Cordialement
jpbbricole

Merci pour ces commentaires, mais ça ne m'avance pas plus.

Pourtant, ça le devrait.
Tu te plaints d'un certain comportement . Je te montre où se trouvent les problèmes.
Les corrections ne devraient pas être difficiles à appliquer.

Entre nous, tu avais fait un code pour des servos tournant dans le même sens. Tu te retrouves avec des servos tournant différemment. Si tu galères pour retrouver tes petits, il vaudrait peut-être mieux repartir de 0 avec les nouvelles données.

Le plus simple serait de poser sur le papier le comportement attendu.

  1. setup(), il faut que le programme démarre toujours dans le même état
    • le servo gauche doit être à la position PG0
    • le servo droit doit être à la position PD0
  2. loop()
    • le servo gauche doit se déplacer de la position courante vers la positon PG1 lentement.
      Pendant que le servo droit se déplace de la position courante vers la position PD1
    • pause
    • le servo gauche doit se déplacer de la position courante vers la positon PG2 lentement.
      Pendant que le servo droit se déplace de la position courante vers la position PD2
    • pause

Et ainsi de suite.
Comme loop() s'exécute comme une boucle infinie, il faudrait qu'à la fin de loop les servos se trouvent dans l'état qui est attendu au début de loop sinon il va y avoir un à-coup.


A noter, pour faire ce genre de choses

on peut aussi faire ceci

  int angleG, angleD;

  for(angleG=0, angleD=90; angle1<90; angle1+=1, angle2-=1){
      servodroit.write(angleG);
     servogauche.write(angleD);
  }

Bonjour euromagie

Voilà un exemple, avec VarSpeedServo, de 2 servo en rotation opposée avec réglage de vitesse (servoSpeed) et en mode simultané (servoWait)

Le programme:

/*
    Name:       ARDFR_euromagie_2servo.ino
    Created:	27.08.2023
    Author:     jpbbricole/euromagie
*/
#include <VarSpeedServo.h>     // https://github.com/netlabtoolkit/VarSpeedServo

const int servoGauchePin = 9;
const int servoDroitePin = 10;

VarSpeedServo servoGauche;    // creation servo gauche
VarSpeedServo servoDroite;    // creation servo droite

const int servoSpeed = 100;     // Vitesse 0-255
const boolean servoWait = false;     // Les servo tournent en même temps

void setup()
{
	servoGauche.attach(servoGauchePin);
	servoDroite.attach(servoDroitePin);
}

void loop()
{
	servoGDangle(0, servoSpeed, servoWait);
	delay(1000);
	servoGDangle(90, servoSpeed, servoWait);

	servoGDangle(90, servoSpeed, servoWait);
	delay(1000);
	servoGDangle(0, servoSpeed, servoWait);

	delay(1000);
}

// Servo en rotation opposée wait si true, mode bloquant
void servoGDangle(int angle, int speed, boolean wait)     
{
	servoGauche.write(angle, speed, wait);
	servoDroite.write(90 - angle, speed, wait);
}

Je te laisse découvrir et poser les bonnes questions :wink:

Cordialement
jpbbricole

1 Like

Merci pour ce code. Il fonctionne bien, sauf au début. Je ne comprends pas pourquoi le servomoteur droite part tout seul en premier à grande vitesse et revient en position 0 pour commencer le cycle avec le servomoteur gauche. Il y a qu'au début, car après la boucle est normale avec les deux servomoteurs.

Bonsoir euromagie

Je pense que cela provient du fait que, au démarrage du programme le servo n'est pas à 0°, au démarrage du signal PWM, équivalent à 0°, le servo se met à 0° en dehors de tout réglage de vitesse.
Tu peux essayer de mettre manuellement ton servo à 0° et voir si cela se produit toujours.
Il est bon d'adapter les paramètres la bibliothèque pour ce qui est des valeurs minimum et maximum du PWM aux valeurs de tes servo, ça se fait via la commande attach,

servoGauche.attach(servoGauchePin, pwmMin, pwmMax);
servoDroite.attach(servoDroitePin, pwmMin, pwmMax);

par défaut c'est 544 2024 microsecondes.

A l'arrêt du programme, il faut prêter attention à la position des servo et s'arranger qu'il soient à 0+.

A+
Cordialement
jpbbricole

Bonjour.

J'ai finalement trouvé comment modifier mon code et il fonctionne parfaitement. Je suis parti de mon idée de base et j'ai ajouté les lignes:

for (angle = 90; angle <= 91; angle += 1) {
 servo1.write(angle);
 servo2.write(angle);
delay(1000);

en début de loop.

Voici le code complet, si quelqu'un en à besoin comme moi un jour:

/* Ouverture boite automatisée 2 servomoteurs. */
// Inclure la librairie servomoteurs:
#include <Servo.h>
// Création des servomoteurs:
Servo servodroite;
Servo servogauche;
// Définir les entrées PIN:
#define servodroitePin 9
#define servogauchePin 10
// Création des variables de position initiale des servomoteurs:
int angle = 90;
void setup() {
 // Attribution des numéros de PIN:
 servodroite.attach(9);
 servogauche.attach(10);
}
void loop() {
 // Instructions d'angle des servomoteurs:
for (angle = 90; angle <= 91; angle += 1) {
 servodroite.write(angle);
 servogauche.write(angle);
  delay(1000);
}
 // Parcourir de 0 à 90 degrees:
for (angle = 90; angle <= 180; angle += 1) {
 servodroite.write(angle);
 servogauche.write(180-angle);
delay(80);
}
 // Instructions d'angle des servomoteurs:
 servodroite.write(angle);
 servogauche.write(180-angle);
delay(20000);
 // Retour en sens inverse de 90 à 0 degrees:
for (angle = 180; angle >= 90; angle -= 1) {
 servodroite.write(angle);
 servogauche.write(180-angle);
delay(80);
}
delay(1000);
 servodroite.detach();
 servogauche.detach();
}

Merci de vos messages où j'ai pu avoir des réflexions en piochant dans chacune.

Loop est appelée en boucle. Après les "detach", l'instruction qui va suivre est le début de loop qui commence par un write au servo.

La boite va s'ouvrir et se refermer sans arrêt ou c'est une seule fois? Dans le premier cas, il ne faut pas mettre le detach, dans le second, il faut ne pas boucler.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.