Ralentir un servo moteur [Résolu, pas de solution logiciel]

Bonjour,
Commander un servomoteur avec la librairie servo est simple.

void fermer() {
  digitalWrite(AlimServo, 0);
  for (int i = 30; i < 166; i++) {
    monServo.write(i);
    delay(20);  // trappe fermé en 3 secondes
  }
  digitalWrite(AlimServo, 1);
}

AlimServo commande un mosfet pour limiter la consommation hors action.

Le soucis est qu' à l'initialisation, sans fin de course, on ne connait pas la position de la porte.
Pour éviter un aller-retour violent, quelqu'un aurait une idée pour faire le même genre d'action ralentie sans donner une position de départ ?
La commande en pwm de l'alimentation du mosfet ne semble pas la solution ?
Il s'agit du MG996R Tower-Pro (electronicoscaldas.com)

Un MG996R se modifie facilement.

Il faut dévisser les 4 vis du servomoteur, enlever le capot du côté câble, et souder un fil sur le point milieu du potentiomètre (le fil blanc ci-dessus). Avant de refermer il faut agrandir de 1mm l'ouverture réservée au passage du câble, et refermer le tout.

Il vaut mieux éviter de retirer le capot du côté axe moteur, les engrenages risquent de tomber, et il serait dommage de perdre le petit axe du pignon central.

Le potentiomètre délivre environ 0V en position ZÉRO et 2.5V en position 180°.

Merci Henry,
J'avais déjà vu ton explication mais j'avais cru comprendre que c'était un signal numérique qui sortait de là, difficilement exploitable.
Si c'est une simple tension, il n'est pas difficile de lire cette valeur avant d'envoyer l'action alors.

Si il n'y a pas de solution software, je ferais cette bidouille. :wink:

Peut être une piste ici. Je vais essayer, je suis aussi intéressé.

Cordialement
jpbbricole

Bonsoir achess

Cette bibliothèque fonctionne super bien, la vitesse 1 un régal!
Il y a même une fonction wait.
J'ai essayé avec un servo digital Align DS610.
Avec un digital, ne pas descendre, en position, plus bas que 10, avec l'Align ça donne des accoups.

Cordialement
jpbbricole

Je crois que la question de fond porte sur le fait que lorsqu’il ferme sa porte il fait des pas de 1 Entre 30 et 166 toutes les 20ms

for (int i = 30; i < 166; i++) {
    monServo.write(i);
    delay(20);  // trappe fermé en 3 secondes
  }

Mais que la porte (le servo) n’est pas forcément à 30 au départ.

La bibliothèque VarSpeedServo fait en gros la même boucle for mais par interruptions et dépend de la dernière valeur passée à write pour connaître la position actuelle.

Au boot elle n’a aucune idée de là où se trouve le servo, donc on aura aussi potentiellement un comportement erratique.

Si on n’a pas de endstop, le seul moyen de connaître cette position initiale est d’aller la lire en bidouillant le servo. Ensuite on peut utiliser cette valeur pour le write avant d’attacher le servo et ensuite on peut soit faire un read() de la position pour la boucle for au lieu du 30

for (int i = monServo.read(); i < 166; i++) {
    monServo.write(i);
    delay(20);  // trappe fermé en 3 secondes
  }

soit utiliser la bibliothèque VarSpeedServo.

1 Like

Le seul problème est que lorsque l'ARDUINO redémarre on perd la dernière position envoyée au servo, d'où ma suggestion de bidouille hard (déjà testée par moi-même, et qui marche au poil).
Franchement, ajouter un fil n'est pas une opération lourde. Et certains servos possèdent ce fil supplémentaire.

Oui c’est la seule façon d’avoir la valeur initiale physique

Analogique intégral.
Oui, et je me contente de peu. Si la tension du potar est supérieure à la moitié de la tension maximale, je considère que la porte est ouverte, sinon qu'elle est fermée. On peut faire plus fin.

https://bitbucket.org/henri_bachetti/mysensors-gate/src/master/arduino/mysensors-gate/mg996r.cpp

Voir le code encadré par #ifdef USE_SERVO_POT #endif
Bête comme chou.

1 Like

Un exemple :

Exemple classique :
Au téléversement d'un nouveau sketch, la position vaut 0° (ou 180°, il faut bien faire un choix).
Le sketch veut positionner le servo à 180°. C'est sa décision.
Si le servo est piloté par un code qui positionne le servo de 0° à 180° avec un delai entre chaque pas, il va d'abord demander la position 0°, puis 1°, etc. jusqu'à 180°.
Si au départ le servo est en position 0° tout va bien.
Si au départ le servo est en position 180°, il va brutalement se positionner à 0°, et cela peut provoquer un désastre mécanique (emmêler une ficelle, un câble, laisser tomber violemment une charge, etc.).
La solution purement logicielle n'existe pas.

1 Like

Tout est dit, merci à tous

J'ai fait quelques essais, il est m'est apparu un gros problème, au moment de la commande myServo.attach(s), il se passe un à-coup systématique, mais conséquent je ne saurai dire de où à où. J'ai essayé de ralentire en travaillant sur myServo.attach(s, t1, t2) en mettant t1 et t2 au plus bas, mais la vitesse de l'à-coup ne change pas.

@jpbbricole c’est sans doute ce que l’on dit dans la discussion. Si vous n’avez pas fait un write pour établir la valeur initiale, quand vous faites un attach le servo reçoit la commande et se déplace d’un coup car le bras n’est pas forcément la ou le code pense qu’il est.

—-

Sinon rajouter des endstop ça permet de fiabiliser le système et c’est pas très coûteux

Oui, bien sur, je préfère la solution de Henry

PS : Cela fait un moment que je n'était pas venu et je me rends compte que le forum a changé mon pseudo Achess en Courge :upside_down_face:
Oupps ! j'était en mode traduction automatique :crazy_face:

Bonsoir J-M-L

Entre temps, j'ai effacé ce post, car ça. nécessite plus d'essais.
Mais, avec une bibliothèque, je pense que ça va être difficile.

Bonne nuit
jpbbricole

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