Servo reagiert auf Servotester, nicht auf Mikrocontroller. Signale sehen gleich aus

Ich habe ein TowerPro MG90D Servo ( Hersteller Link ) ( ServoDatabase Link ).
Es hat einen Bereich von 180 Grad (nicht kontinuierlich).

TowerPro MG90D

Es reagiert großartig auf meinen Servotester:
Servotester

Beachten Sie den folgenden 7 % Arbeitszyklus (ca. 90 Grad) auf dem Tester:

Scope Servotester

Scope Servotester

Servo reagiert gut.


Wenn ich jedoch servo.write()mit meinem Arduino Mega 2560-Klon verwende, reagiert das Servo auf keine Winkelausgabe. Ich habe mehrere andere Servos, die mit dem gleichen Code auf den gleichen Pins gut funktionieren.

Beachten Sie die folgenden 7% Duty Cycle auf dem Arduino mit servo.write(90):

Bereich Arduino-Servo 90 Grad

Keine Antwort. Das Servo ist "schlaff"; es hält keine Position.


Während ich diese Frage schrieb, dachte ich daran, es zu versuchen servo.writeMicroseconds().

Hier ist servo.writeMicroseconds(1450):

Bereich Arduino-Servo 1450 ms

Servo reagiert!

Hier ist servo.writeMicroseconds(1472)(working), das die gleichen Zeitintervalle hat wie das vorhergehende non-working servo.write(90)!

Bereich Arduino-Servo 1472 ms

servo.writeMicroseconds(1550)(Arbeiten):

Bereich Arduino-Servo 1550 ms


Was ist der Unterschied?
Der Servotester arbeitete bei 49,5 Hz, während servo.write()er bei 49,9 Hz versagte. Ich habe mich gefragt, ob 0,4 Hz irgendwie einen Unterschied machen, aber dann sehe ich, dass das servo.writeMicroseconds()auch bei 49,9 Hz funktioniert hat.

In den obigen Bereichsaufnahmen ist zu sehen, dass sowohl servo.write(90)als servo.writeMicroseconds(1472)auch die gleichen Zeitintervalle haben:
 1,474,560ns HIGH
18,544,640ns LOW

Die Signale sind so ähnlich ... Was könnte dazu führen , dass es servo.write()nicht funktioniert?

Mein Code ist so einfach wie möglich:

#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);
}

schematisch

Simulieren Sie diese Schaltung – Mit CircuitLab erstellter Schaltplan

Ich habe sowohl ein lineares Tischnetzteil als auch versucht, einen Abwärtswandler zu verwenden, um von 9 V herunterzusteigen.
Sind Sie sicher, dass Sie während der gesamten 3 Sekunden eine stetige Welle haben, wenn Sie verwenden write? Es gibt wirklich keinen Grund, warum das Servo nicht funktioniert, daher würde ich Ihre Signale in Frage stellen.
@DmitryGrigoryev Es sieht für mich ziemlich stabil aus. Kein Ruckeln oder Flackern auf meinem Zielfernrohr, das ich sehen kann.
@Bort Dann fällt es mir schwer, deine Geschichte zu glauben.
@DmitryGrigoryev Ich auch. Aber ich kneife mich immer wieder und ich fühle, dass dies kein Traum ist.
Ich würde die Masse zwischen dem Servo und dem Arduino überprüfen. Vielleicht ist der Stecker ein wenig daneben und stellt einen besseren Kontakt zu den Pins des Servotesters her.
@JRE Masse spielt keine Rolle, servo.write()sendet aus irgendeinem Grund ein anderes Signal als der Servotest und servo.writeMilliseconds(uS) . Ich denke, das OP sucht nach dem tatsächlichen Unterschied zwischen den Signalen, da sie in jeder Hinsicht gleich zu sein scheinen.
@BigHomie: Die Signale sind identisch, was die Oszilloskopbilder betrifft. Neben dem Signal passiert noch etwas. Schlechte Masse ist eine Sache, die zu unterschiedlichen Reaktionen auf nominell identische Signale führen kann.
Wo schließt du dein Oszilloskop an? am Servoeingang oder auf der Platine?
@laptop2d Es gibt einen ~ 8 cm langen Draht von der Platine, der an den ~ 8 cm langen Draht des Servos angeschlossen wird. An dieser Kreuzung ist mein Zielfernrohr angebracht.
Wenn man sich den servo.write()Code ansieht , ruft er auf servo.writeMicroseconds(). Es ist also sehr überraschend, dass Sie sagen, dass es writeMicroseconds()funktioniert und write()nicht funktioniert.
Nehmen Sie nach Möglichkeit zwei Oszilloskopspuren auf der Servosignalleitung mit angeschlossenem Servo auf . Ein Trace nur mit serv1.write() und ein Trace nur mit serv1.writeMicroseconds(). Poste beide Traces. Für zusätzlichen Charme werfen Sie eine dritte Spur von Ihrem Tester mit angeschlossenem Servo ein .
Du hast erwähnt, dass andere Servos funktionieren, richtig? Sind das die gleichen Servos? Haben Sie sie an dieser speziellen Nadel ausprobiert?
Ich stimme JRE zu. Irgendwo gibt es einen Unterschied, den Sie nicht berücksichtigen.

Antworten (2)

Zuerst eine kurze Seite. Sie scheinen ein kleines Missverständnis darüber zu haben, wie Servos funktionieren. Servos werden nicht von PWM gesteuert, und sie wissen oder kümmern sich nicht darum, dass Sie Impulse mit 49 Hz senden. Sie wissen nicht, dass der Puls ein gewisser Prozentsatz einer willkürlichen Periode ist. Dem Servo ist es egal, wie lange die Zeit zwischen den Impulsen ist. Ich sage das, weil Sie sich ungewöhnlich auf Dinge zu konzentrieren scheinen, die eigentlich keine Rolle spielen.

Servos wissen oder kümmern sich nicht einmal wirklich darum, ob die Spannung zu einem bestimmten Zeitpunkt hoch oder niedrig ist. Sie interessieren sich nur für eines: die Zeit zwischen einer steigenden Flanke und einer fallenden Flanke.

Der Servo wird gesteuert, indem eine steigende Spannungsflanke erkannt wird und die Zeit gemessen wird, bis eine fallende Flanke auftritt. Gültige Zeiten liegen normalerweise zwischen 1,0 und 2,0 ms, können aber von Servo zu Servo variieren.

Sie können es mit 1 Hz, 10 Hz, 50 Hz, 100 Hz steuern. Die meisten reagieren auf noch höhere Pulsfrequenzen, aber auch dies ist variabel. Was ich zu sagen versuche, ist, dass die Frequenz, das Tastverhältnis, die Dauer zwischen den Impulsen für Ihr Problem nicht weniger relevant sein könnten, dh dass das Servo nicht reagiert, wenn Sie es erwarten.

Das einzige, was relevant ist, sind Kanten Ihres Pulses, denen Sie keine Aufmerksamkeit geschenkt haben. Wenn Sie das herausfinden wollen, beginnen Sie bitte damit, sich die Dinge anzusehen, die wichtig sind, machen Sie Nahaufnahmen Ihrer Pulsflanken und so weiter. Sie haben in diesen Screenshots nichts Nützliches erfasst, weshalb es wahrscheinlich kein Problem oder Unterschied zu geben scheint. Es gibt viele Probleme oder Unterschiede, die mit dem, was Sie gemessen haben, niemals sichtbar wären.

Was ich sehen kann, ist, dass die Erfassung des nicht funktionierenden Impulszugs merklich schmutziger ist, sowohl der Impuls als auch der Boden, als alle anderen. Was seltsam ist, da es dieselbe Funktion wie die anderen aufrufen sollte. Warum ist der so viel lauter?

Noch wichtiger ist, dass Sie sich in der nicht funktionierenden Erfassung die „Fallzeit“ ansehen. 809µs? Ihr Oszilloskop glaubt, eine Abfallzeit von 0,8 ms zu sehen. Das ist schlecht. Das ist natürlich falsch, aber Tatsache bleibt, dass es genau das misst.

Das ist ein klassisches Zeichen für eine schmutzige Kante. Denk darüber nach. Wenn dieser Impuls Ihr High-End-Testgerät, das Ihr Oszilloskop ist, dazu bringt, eine lächerlich lange Flanke oder Abfallzeit zu sehen, oder vielleicht so schmutzig, dass es die abfallende Flanke nicht immer richtig erkennen kann (oder wer weiß), dann Welche Chance hat dieser arme beschissene kleine 8-Dollar-Servo, eine anständige fallende Flanke zu bekommen?

Wenn ein Servo innerhalb des akzeptablen Impulsbereichs keinen gültigen Impuls erhält (z. B. wenn die fallende Flanke zu lange dauert, zu schmutzig ist oder ausgelassen wird), und wenn die Servos anhand der Flanken rechnen, die möglicherweise etwas haben oder nicht tun, was Sie für die Impulsflanken halten, dann reagiert es genau so, als wäre es ausgeschaltet.

Mit anderen Worten, es bewegt sich nicht nur nicht, sondern widersetzt sich auch nicht der Bewegung seiner Welle. Es wird einfach schlaff sein, genau wie Sie sehen.

Nun, das wirft die Frage auf .... warum sollte der Aufruf von servo.write die Kantenqualität beeinflussen?

Du sagtest ein Klon. Wie dieser?Geben Sie hier die Bildbeschreibung ein

Gerade diese Klone neigen aufgrund der unglaublich schlechten Entkopplung dazu, sich unregelmäßig zu verhalten. Es sollten Entkopplungskondensatoren an jedem Stromanschluss und so nah wie möglich am Mega2560 vorhanden sein. Und auf dem eigentlichen Arduino gibt es tatsächlich welche. Auf diesen Klonen sind sie jedoch viel zu weit entfernt oder fehlen vielleicht, es ist schwer zu sagen. Wenn man sich das Board ansieht, ist es offensichtlich, dass es sich nicht zuverlässig verhalten wird, das ist das Wichtigste.

Was ist aber der Unterschied?

Wenn Sie servo.write aufrufen, wird der Stapel höher verschoben, als wenn Sie writeMicroseconds aufrufen. Angesichts des 3-Byte-Stapelzeigers (17 Bit) des Mega2560 muss er eine Reihe kritischer Bits umdrehen, die er nicht muss, wenn Sie writemicroseconds aufrufen. Ich weiß, dass dies ein unwahrscheinlicher Unterschied zu sein scheint, aber ich habe meinen fairen Anteil an schlecht entkoppelten Mikrocontrollern erlebt, und insbesondere Atmegas scheinen ein merkwürdiges Verhalten zu zeigen, insbesondere wenn Timer verwendet und / oder der Stapel verschoben oder geknackt werden. Bei mir ist etwas Ähnliches passiert, nur der Stapel war beschädigt, als ich versuchte, LEDs mit PWM anzusteuern, aber wenn ich alles inline legte, ohne den Stapel zu verschieben, funktionierte es. Schlechte Entkopplung war letztlich das Problem.

Ich würde voll und ganz erwarten, dass eine schlechte Entkopplung aus Gründen, die atmega2560 und sonst niemandem bekannt sind, sich nachteilig auf die Kantenqualität dieses Impulses auswirken kann, aber nur, wenn Sie den Stapel direkt davor schieben. Dieses Servo ist einfach nicht in der Lage, mit der Art und Weise umzugehen, wie diese Kanten beschmutzt werden, daher sieht es in diesem Fall keine gültigen Impulse. Andere Servos schaffen das offensichtlich.

Dinge zu entkoppeln ist immer so bizarr und hyperspezifisch. Deshalb ist die Entkopplung so wichtig. Halten Sie die alptraumhaften Höllenprobleme in Schach, die Sie durch Kapazitätsmangel verursachen können, mit schönen dicken Keramikkappen und so nah wie möglich am Chip.

Dies kann mit den Ausgangspineinstellungen zusammenhängen, die von der .write()-Routine vorgenommen werden. Bitte versuchen Sie es mit einem 1K-Pulldown-Widerstand, wenn er nicht funktioniert, entfernen Sie ihn und verwenden Sie ihn als Pullup-Widerstand. dies gleicht den Effekt jedes internen Wochen-Pull-up/Pull-down-Widerstands aus, der durch die Routine gesetzt werden kann. Wenn Sie das Signal mit Ihrem Oszilloskop messen, wirkt der Innenwiderstand der Sonde als Pulldown.
Die meisten Servos geben den Strom auch an den internen Motor ab, wenn das Signal nicht für 10 Impulse hintereinander voreingestellt ist. Dies wird verwendet, um Strom zu sparen.

Ich fürchte, Ihre Antwort ist nicht richtig. servo.write() nimmt einen Winkel als Eingabe, nicht die Zeit. Die Leute sollten nicht blind für Antworten abstimmen.
Ja, mein Fehler, ich habe den Code nicht gut gelesen. Dies kann mit den Ausgangspineinstellungen zusammenhängen, die von der Routine .write() vorgenommen werden.
Dies wäre mein erster Gedanke gewesen, die Scope-Spuren scheinen dies jedoch zu widerlegen. Eine fehlende Masse und eine andere Pull-up/-down-Situation können dafür verantwortlich sein, dass dasselbe Signal gesendet wird, aber nicht dort ankommt (nach der Sondenposition).
Ich denke, @KallieMP hat wahrscheinlich Recht. Pullup/Down-Widerstände könnten sehr wohl die Antwort sein. Sie könnten den Strom begrenzen. Die Pulse können korrekt geformt werden, jedoch mit zu wenig Antrieb. Unabhängig von der jeweiligen Funktion von servo.write() müssen die Strompegel also genau mit der Ausgabe des Servotesters übereinstimmen, um das gleiche Ergebnis zu erzielen.