Le servo répond au testeur de servo, pas au microcontrôleur. Les signaux se ressemblent

8

J'ai un servo TowerPro MG90D ( lien Manufactuer ) ( lien ServoDatabase ).
Il a une gamme de 180 degrés (non continue).

TowerPro MG90D

Il répond très bien à mon testeur de servo:
Testeur de servo

Observez le cycle d'utilisation de 7% suivant (environ 90 degrés) sur le testeur:

testeur d'asservissement de portée

testeur d'asservissement de portée

Le servo répond bien.


Cependant, lorsque j'utilise servo.write()avec mon clone Arduino Mega 2560, le servo ne répond à aucune sortie d'angle. J'ai plusieurs autres servos qui fonctionnent très bien avec le même code sur les mêmes broches.

Observez le cycle d'utilisation de 7% suivant sur l'Arduino avec servo.write(90):

portée arduino servo 90deg

Pas de réponse. Le servo est "mou"; il ne tient aucune position.


Pendant que j'écrivais cette question, j'ai pensé essayer servo.writeMicroseconds().

Voici servo.writeMicroseconds(1450):

portée arduino servo 1450ms

Le servo répond!

Voici servo.writeMicroseconds(1472)(qui fonctionne), qui a les mêmes intervalles de temps que le précédent qui ne fonctionne pas servo.write(90)!

portée arduino servo 1472ms

servo.writeMicroseconds(1550) (travail):

portée arduino servo 1550ms


Quelle est la différence?
Le servo-testeur fonctionnait à 49,5 Hz, mais servo.write()échouait à 49,9 Hz. Je me demandais si en quelque sorte 0,4 Hz faisait une différence, mais je vois que cela servo.writeMicroseconds()fonctionnait également à 49,9 Hz.

Dans les captures de portée ci-dessus, on peut voir que les deux servo.write(90)et servo.writeMicroseconds(1472)ont les mêmes intervalles de temps:
 1,474,560ns HIGH
18,544,640ns LOW

Les signaux sont tellement similaires ... Qu'est-ce qui pourrait faire que ça ne marche pas?servo.write()

Mon code est aussi basique que possible:

#include <Servo.h>
Servo serv1;

void setup() {
  serv1.attach(3); // Pin 3
}

void loop() {
  serv1.write(90); // No response
  delay(3000);

  serv1.writeMicroseconds(1472); // Works
  delay(3000);

  serv1.write(0); // No response
  delay(3000);

  serv1.writeMicroseconds(1800); // Works
  delay(3000);
}

schématique

simuler ce circuit - Schéma créé à l'aide de CircuitLab

Bort
la source
J'ai essayé à la fois une alimentation linéaire de paillasse et j'ai également essayé d'utiliser un convertisseur abaisseur pour passer de 9V.
Bort
1
Êtes-vous sûr que vous avez une onde régulière pendant les 3 secondes complètes lorsque vous utilisez write? Il n'y a vraiment aucune raison pour que le servo ne fonctionne pas, alors je remettrais en question vos signaux.
Dmitry Grigoryev
1
@Bort Alors j'ai du mal à croire votre histoire.
Dmitry Grigoryev
2
@BigHomie: Les signaux sont identiques en ce qui concerne les images de l'oscilloscope. Il se passe quelque chose en plus du signal. Un sol pauvre est une chose qui pourrait provoquer des réactions différentes à des signaux nominalement identiques.
JRE
2
Si possible, capturez deux traces de portée sur la ligne de signal du servo avec le servo connecté . Une trace avec serv1.write () uniquement et une trace avec serv1.writeMicroseconds () uniquement. Postez les deux traces. Pour un charme supplémentaire, ajoutez une troisième trace de votre testeur avec le servo connecté .
neonzeon

Réponses:

0

Tout d'abord, un petit aparté. Vous semblez avoir un léger malentendu sur le fonctionnement des servos. Les servos ne sont pas contrôlés par PWM, et ils ne savent pas ou ne se soucient pas que vous envoyez des impulsions à 49 Hz. Ils ne savent pas que le pouls est un pourcentage d'une période arbitraire. Le servo se fiche du temps entre les impulsions. Je dis cela parce que vous semblez inhabituellement concentré sur des choses qui n'ont pas vraiment d'importance.

Les servos ne savent même pas ou ne se soucient pas vraiment que la tension est élevée ou basse à un moment donné. Ils ne se soucient que d'une chose: le temps entre un front montant et un front descendant.

Le servo est contrôlé en détectant un front de tension montant et en mesurant le temps jusqu'à ce qu'il y ait un front descendant. Les durées valides sont généralement comprises entre 1,0 et 2,0 ms, mais elles peuvent varier d'un servo à l'autre.

Vous pouvez le contrôler à 1 Hz, 10 Hz, 50 Hz, 100 Hz. La plupart réagiront à des taux d'impulsions encore plus élevés, mais là encore, cela est variable. Ce que j'essaie de dire, c'est que la fréquence, le rapport cyclique, la durée entre les impulsions, tout ne pourrait pas être moins pertinent pour votre problème, c'est que le servo ne répond pas quand vous vous y attendez.

La seule chose qui soit pertinente, ce sont les bords de votre pouls, auxquels vous n'avez prêté aucune attention. Si vous voulez comprendre cela, veuillez commencer par regarder les choses qui comptent, faire des captures rapprochées de vos bords d'impulsion, ce genre de chose. Vous n'avez rien saisi d'utile dans ces captures d'écran, c'est probablement pourquoi il ne semble pas y avoir de problème ou de différence. Il y a beaucoup de problèmes ou de différences qui ne seraient jamais visibles avec ce que vous avez mesuré.

Ce que je peux voir, c'est que la capture du train d'impulsions qui ne fonctionne pas est nettement plus sale, à la fois l'impulsion et le sol, que les autres. Ce qui est étrange, car il devrait appeler la même fonction que les autres. Pourquoi est-ce tellement plus bruyant?

Plus important encore, dans la capture non fonctionnelle, regardez le «temps de chute». 809µs? Votre oscilloscope pense qu'il voit un temps de chute de 0,8 ms. C'est mauvais. De toute évidence, c'est inexact, mais le fait demeure, c'est ce qu'il mesure.

C'est un signe classique d'un bord sale. Pensez-y. Si cette impulsion trompe votre équipement de test haut de gamme qu'est votre oscilloscope pour voir un front ridiculement long ou un temps de chute, ou peut-être si sale qu'il ne peut tout simplement pas détecter correctement le front descendant tout le temps (ou qui sait), alors quelle chance ce pauvre petit servo de 8 $ a-t-il de ramasser un bord descendant décent?

Si un servo n'obtient pas une impulsion valide (comme si le front descendant prend trop de temps, est trop sale ou est manqué) dans la plage d'impulsions acceptable, et par les servos, en tenant compte des bords qui peuvent ou non avoir quelque chose à faire avec ce que vous considérez comme les fronts d'impulsion, il répond comme s'il était éteint.

En d'autres termes, non seulement il ne bouge pas, mais il ne résistera pas au déplacement de son arbre. Ce sera tout simplement mou, exactement comme vous le voyez.

Maintenant, cela soulève la question .... pourquoi l'appel à servo.write affecterait-il la qualité des bords?

Vous avez dit un clone. Comme celui-ci?entrez la description de l'image ici

Ces clones en particulier ont tendance à se comporter de manière erratique en raison du découplage incroyablement pauvre. Il devrait y avoir des condensateurs de découplage sur chaque broche d'alimentation, et aussi près que possible du mega2560. Et sur l'arduino réel, en effet il y en a. Sur ces clones cependant, ils sont beaucoup trop éloignés, voire manquants, c'est difficile à dire. Il est évident en regardant le tableau qu'il ne se comportera pas de manière fiable, c'est l'important.

Mais quelle est la différence?

Lorsque vous appelez servo.write, il pousse la pile plus haut que si vous appelez writeMicroseconds. Étant donné le pointeur de pile de 3 octets du méga2560 (17 bits), il doit retourner un tas de bits critiques qu'il n'a pas à faire lorsque vous appelez des microsecondes écrites. Je sais que cela semble être une différence improbable, mais j'ai connu ma juste part de microcontrôleurs mal découplés, et les atmegas en particulier semblent présenter un comportement étrange spécifiquement lors de l'utilisation de minuteries et / ou en poussant ou en éclatant la pile. Quelque chose de similaire s'est produit pour moi, seule la pile était corrompue lorsque j'essayais de piloter des LED avec PWM, mais si je mettais tout en ligne sans pousser la pile, cela fonctionnait. Un mauvais découplage a finalement été le problème.

Je m'attends à ce qu'un mauvais découplage puisse, pour des raisons connues de cet atmega2560 et de personne d'autre, avoir un effet néfaste sur la qualité des bords de cette impulsion, mais uniquement lorsque vous poussez la pile juste avant. Ce servo n'est tout simplement pas capable de gérer la façon dont ces bords sont souillés, il ne voit donc aucune impulsion valide dans ce cas. D'autres servos le gèrent évidemment.

Le découplage est toujours bizarre et hyper spécifique comme ça. C'est pourquoi le découplage est si important. Gardez l'enfer cauchemardesque de problèmes Le manque de capacité peut vous mettre à distance avec de beaux capuchons en céramique grasse et aussi près de la puce que possible physiquement.

métacolline
la source
0

Cela peut être lié aux paramètres de broche de sortie effectués par la routine .write (). Veuillez essayer d'utiliser une résistance de rappel 1K, cela ne fonctionne pas, retirez-la et utilisez-la. cela équilibrera l'effet de toute résistance interne de pull-up / pull-down hebdomadaire qui peut être réglée par la routine. Lorsque vous mesurez le signal avec votre oscilloscope, la résistance interne de la sonde agit comme un pull-down.
La plupart des servos libèrent également l'alimentation du moteur interne si le signal n'est pas prédéfini pour 10 impulsions d'affilée. Ceci est utilisé pour économiser de l'énergie.

555
la source
Je crains que votre réponse ne soit pas correcte. servo.write () prend un angle en entrée, pas le temps. Les gens ne devraient pas voter à l'aveuglette.
Bort
Oui, mon erreur, je n'ai pas bien lu le code. cela peut être lié aux réglages des broches de sortie effectués par la routine .write ().
555
2
Cela aurait été ma première pensée, les traces de portée semblent cependant réfuter cela. Un sol manquant et une situation de pull-up / -down différente peuvent expliquer que le même signal soit envoyé mais n'y arrive pas (après l'emplacement de la sonde).
KalleMP
Je pense que @KallieMP a probablement raison. Les résistances pullup / down pourraient très bien être la réponse. Ils pourraient limiter le courant. Les impulsions peuvent être formées correctement mais avec un entraînement insuffisant. Quelle que soit la fonction particulière de servo.write (), les niveaux de courant doivent correspondre précisément à la sortie du servo-testeur pour obtenir le même résultat.
SDsolar