Hallo, nachdem ich schon seit Tagen mit dem Programm versuche mehrere Servos erfolglos anzusteuern (nicht wundern es sind gerade nur zwei angeschlossen)wollte ich nun hier mal fragen, wo denn mein Fehler liegt. Ich nutze einen Atmega328, dieser kann keine Probleme haben, da ich das Projekt in einem Simulationsprogramm namens Simulide aufgebaut habe. Ich nutze deshalb den CTC-Mode, da ich zu einem Zeitpunkt mit Multiplexern bis 18 Servos anschließen will.
Und was ist jetzt die Frage? Was geht nicht wie erwartet? BTW: Warum ist die Dateiendung "txt"?
Überprüfe die Servo-Signale mit einem Logic Analyzer und zeige und, was dabei heraus kam. Bist du sicher, dass dein CENTER Wert stimmt? Es muss 1,5ms sein. Und: Der Maximalwert ist keineswegs 2·Center sondern 2ms. Der Minimale Wert ist nicht 0,5·Center sondern 1ms. Ich würde mich aber n icht darauf verlassen. Viele Servos erreichen schon vorher die Endanschläge und gehen kaputt wenn du sie dagegen drücken lässt. Ist dir bewusst, dass die Pausen zwischen den Impulsen sehr viel länger dauern müssen, als die Impulse?
Ja, die Servos bewegen sich nicht. Hat keinen bestimmten Grund nächstes Mal lade ich sie als .c hoch:)
Ich sehe gerade: Dein Programm geht sogar davon aus, dass der linke Anschlag 0 ms ist - falscher geht es nicht.
Stefan ⛄ F. schrieb: > Überprüfe die Servo-Signale mit einem Logic Analyzer und zeige > und, was > dabei heraus kam. > > Bist du sicher, dass dein CENTER Wert stimmt? Es muss 1,5ms sein. > > Und: Der Maximalwert ist keineswegs 2·Center sondern 2ms. Der Minimale > Wert ist nicht 0,5·Center sondern 1ms. Ich würde mich aber n icht darauf > verlassen. Viele Servos erreichen schon vorher die Endanschläge und > gehen kaputt wenn du sie dagegen drücken lässt. > > Ist dir bewusst, dass die Pausen zwischen den Impulsen sehr viel länger > dauern müssen, als die Impulse? Der Logic Analyser zeigt nichts an jedoch sieht man in der MCU das im Hintergrund wohl der timer abläuft. https://www.mikrocontroller.net/articles/Modellbauservo_Ansteuerung#Signalerzeugung_f%C3%BCr_1_Servo_mittels_Timer_(C) Habe mich an folgendem Artikel orientiert, werde mir die Impulse nochmal anschauen.
Das geht nicht:
1 | SERVO_DDR = ServoPuls[0] | ServoPuls[1] | ServoPuls[2] | ServoPuls[3] | |
2 | ServoPuls[4] | ServoPuls[5] | ServoPuls[6] | ServoPuls[7]; |
Dein Array hat nur zwei Elemente. Wenn du Timer 1 startest, musst die ISR auch für Timer 1 (nicht Timer 0) sein:
1 | ISR (TIMER0_COMPA_vect) |
Steve M. schrieb: > Habe mich an folgendem Artikel orientiert Da hast du aber einiges missverstanden. Da werden mehrere Servos nacheinander angesteuert, so dass jeder Servo ungefähr alle 20 ms einen Impuls bekommt. Wenn du nur zwei Servos im Wechsel ansteuerst ohne zusätzliche Pause dazwischen, kommst du nicht auf die 20 ms.
Jetzt habe ich es geschnallt: MILLISEC_BASE ist 1 ms und wird immer zum ServoValue addiert. Daher muss der ServoValue zwischen 0 ms (links) und 1 ms (rechts) liegen. Das wird die Berechnung der ServoValue Werte wohl so passen. Aber wie gesagt: Quäle den Servo nicht indem du ihn gegen die Anschläge fahren lässt. Das Beispiel von dem du abgeguckt hast nimmt jedoch überhaupt keine Rücksicht auf die 20ms Intervalle. Wenn alle 8 Servos nach links gefahren werden sind es nur 8ms und wenn sie alle nach rechts gefahren werden sind es 16ms. Finde ich nicht gut, damit provoziert man Probleme. Baue das lieber so, dass die 20ms wenigstens ungefähr eingehalten werden. Vielleicht magst du von meinem Projekt abgucken: http://stefanfrings.de/servocontroller/index.html
Okay vielen Dank schaue ich mir auf jeden Fall mal an! Das Projekt (das im Rahmen des Studiums stattfindet) wird leider Corona geschuldet vorerst nicht über die Simulation hinaus gehen, deshalb sind die Servos sowieso nur virtuell.
> MILLISEC_BASE ( F_CPU PRESCALER 1000 )
Welche Einheit hat MILLISEC_BASE laut dieser Berechnung?
Vielleicht sowas wie "Hz"?
Dann kann die restliche Rechnerei gar nicht funktionieren.
Ich kann mich aber auch irren, weswegen ich frage.
In meinem Projekt konfiguriere ich den Timer so, dass er alle 4 ms überläuft. Ich steuere damit 5 Servos im Wechsel an -> Macht zusammen 4 mal 5ms = 20 ms Intervalle aus Sicht der Servos. Bei mir beginnen die Impulse immer mit dem Overflow Interrupt (wenn der Zähler auf 0 geht). Die Impulse enden mit dem COMPA Interrupt, wenn die gewünschte Pulsbreite erreicht wurde. Den COMPB nutze ich parallel dazu um weitere 5 Servos mit gleichzeitig anzusteuern.
STK500-Besitzer schrieb: > Welche Einheit hat MILLISEC_BASE laut dieser Berechnung? MILLISEC_BASE sind die Anzahl der Timertakte für 1ms. Ergibt sich auch Systemtakt geteilt durch den Prescaler geteilt durch 1000. Ich denke, die Berechnung stimmt so.
Stefan ⛄ F. schrieb: > In meinem Projekt konfiguriere ich den Timer so, dass er alle 4 ms > überläuft. Ich steuere damit 5 Servos im Wechsel an -> Macht zusammen 4 > mal 5ms = 20 ms Intervalle aus Sicht der Servos. Die 20ms sind (inzwischen) irrelevant. Digitale Servos kann man noch schneller antreiben. Und die Aussage, dass 1ms und 2ms schon der Anschlag sind, ist auch überholt. Viele (moderne) Servos haben einen etwas gespreizteren Puls.
STK500-Besitzer schrieb: > Und die Aussage, dass 1ms und 2ms schon der Anschlag sind, ist auch > überholt. Dann ist es aber blöd, dass der Code von Steve (bzw. sein Vorbild im Artikel) wegen der hart codierten Addition von 1 ms niemals kürzere Impulse erzeugen kann. Da ist mein Code flexibler, er erlaubt alle Werte zwischen 0 und 4 ms. Allerdings (das will ich nicht verheimlichen) nur mit 8 Bit Auflösung, weil ich einen 8 Bit Timer verwende. Ich hate mal mit einem 16 Bit Timer experimentiert und dabei herausgefunden, dass zumindest meine Servos sich sowieso nicht feiner steuern lassen als diese 8 Bit her geben.
Und das ganze einem externen Controller zu überlassen scheidet aus? Ich werf mal den PCA9685 in den Ring, der könnte 16 Servos via TWI bedienen.
Stefan ⛄ F. schrieb: > Dann ist es aber blöd, dass der Code von Steve (bzw. sein Vorbild im > Artikel) 1 ms als minimalen Wert festlegt. Das ist ein sicherer Wert. Vielleicht verwendet er ja noch welche von anno dazumal. Grundig Varioprop (von Graupner vertrieben) hatte mWn eine invertierte Ansteuerung.
Crazy H. schrieb: > Und das ganze einem externen Controller zu überlassen scheidet aus? Ich > werf mal den PCA9685 in den Ring, der könnte 16 Servos via TWI bedienen. Ist leider leider nicht möglich da in dem Simulationsprogramm nicht vorhanden deshalb soll das ganze mit drei Multiplexern umgesetzt werden. Jeder soll dann 6 Servos ansteuern. Das ganze soll dann für einen Hexapod verwendet werden.
Worin liegt denn dein Problem genau, was geht nicht? Weißt du wie ein Servosignal auszusehen hat? Du sendest alle 20ms (25ms) einen Puls zum Servo der eine Länge von 1ms bis 2ms hat. Mittelposition sind 1,5ms. Versuche doch erst mal einen einzigen Servo anzusteuern und das kannst du dann später erweitern. Zum Timer: 12,288 MHz : 1024 (Prescaler) = 12000 Hz 1ms würde ja dann bei 12 maligem ausführen des Interrupts vergangen sein. Nach 24 Interrupts wären das dann 2ms. Ist das nicht eine etwas grobe Einstellmöglichkeit? "MILLISEC_BASE" wäre in deinem Fall ja dann 12. Rechne da doch noch mal nach ob er das macht was du möchtest.
Steve M. schrieb: > Ja, die Servos bewegen sich nicht. Hat keinen bestimmten Grund... WAS soll der Unsinn bedeuten: "hat keinen bestimmten Grund.." Natürlich HAT DAS einen Grund! Steve M. schrieb: > Der Logic Analyser zeigt nichts an... Dann fehlen eben die ServoSignale, falls Du den LA korrekt kontaktiert und ausgelesen hast. Also DA ERSTMAL ansetzen, solange KEINE Signale am Servo ankommen ist alles andere sekundär. Natürlich ist das Timing wichtig und in tausenden Online-Quellen hinreichend dokumentiert. Variiert teils aber je nach Servo-Typ etwas. Puls-Pausen-Verhältnis ist relevant, wie schon geschrieben wurde. Die Grundfrequenz ist aber eher unkritisch, manche Servos "knurren" weniger, wenn die Grundfrequenz "servo-abhängig" optimal gewählt ist. Wie auch bereits gesagt wurde: Projekt in PHASEN aufteilen, erstmal EIN Servo zum laufen bringen, DANACH skalieren, egal ob per MPX oder sonstwie. Dir fehlen (noch) völlige Grundlagen zu Servos, dennoch fängst Du als Anfänger direkt mit 18 Servos und MPX-Kram an. So arbeitet man nicht! UND, MIT VERLAUB: Reiss Dich jetzt bitte mal etwas zusammen, Steve! "...hat keinen bestimmten Grund..." "...Logic Analyser zeigt nichts an..." Das ist undefinierter Kokolores und hilft nicht weiter. GUT: Der STK500 Hinweis auf "alte GR..-Servos", die tatsächlich invertierte Signale wollten, eher unwahrscheinlich aber für Dein Projekt, bis auf Exoten arbeiten ModellbauServos heute mit pos. Impulsen. WICHTIG: Die Infos von STEFANUS wirst Du sehr zu schäzen wissen! Bei Schritt-2. ALS ALLER-ERSTES findest Du jetzt mal heraus, OB überhaupt Signale am Servo ankommen! Das ist Schritt-1, insofern verstehe ich die Vorredner wenig... DANN geht es weiter, und wenn Du Dich jetzt wirklich mal konzentrierst kriegst Du das auch hin! Hilfe wirst Du hier bekommen, Servos kriegt man absolut in den Griff!
Stefan ⛄ F. schrieb: > Das Beispiel von dem du abgeguckt hast nimmt jedoch überhaupt keine > Rücksicht auf die 20ms Intervalle. Wenn alle 8 Servos nach links > gefahren werden sind es nur 8ms und wenn sie alle nach rechts gefahren > werden sind es 16ms. Finde ich nicht gut, damit provoziert man Probleme. Nein, das darf kein Problem sein, denn das passiert auch an einer klassischen Fernsteuer-Anlage, wenn auch nicht dauerhaft, sondern mit starkem Jitter versehen.
:
Bearbeitet durch User
@Hermann Kokoschka Als erstens mal kein Grund von dir so aus der Haut zu fahren, verstehe wirklich nicht weshalb du so eine Umgangsformen ansetzt. Im übrigen war das "hat keinen bestimmten Grund" auf das Dateiformat bezogen, hättest du die Antwort ganz gelesen wüsstest du das. Bisher waren alle Antworten sehr konstruktiv und haben mir sehr weiter geholfen. Weshalb ich deine Herangehensweise hier nicht ganz verstehe.. Auf jeden Fall trotzdem noch eine Gute Nacht und Morgen frohe Weihnachten
@Steve M. Bleibe doch einfach ganz ruhig und erläutere PUNKT-FÜR-PUNKT (aber wirklich im Detail) wo ich mich Deiner Meinung nach irre... ;-) Gute Nacht und ein schönes Fest auch für Dich!
Steve M. schrieb: > Das ganze soll dann für einen Hexapod verwendet werden. Kannst du vielleicht mehr zur Anwendung schreiben? Wir steuern auch Hexapoden an, aber ein AVR würden wir hierfür nicht benutzen. Ist der fix? Wo passiert die Verrechnung der einzelnen Beine zum Koordinatensystem? Wie referenziert ihr, und gibt es vielleicht die Möglichkeit die Plattform anstatt der Beine mit einem Sensor zu messen?
Gerald M. schrieb: > Wir steuern auch > Hexapoden an, aber ein AVR würden wir hierfür nicht benutzen. Er wird die Servos mit dem AVR ansteuern und nicht die I/O-Pins des Controllers nehmen und damit dann auch Rechenaufwand und damit Komplexität auslagern. Ist doch schöner dem AVR nur die entsprechenden Soll-Positionen zu geben, dann ist das auch modularisiert und kann auch mal ausgetauscht werden.
Hermann Kokoschka schrieb: > Puls-Pausen-Verhältnis ist relevant, wie schon geschrieben wurde. Das stimmt doch nicht. Bei den meisten Modellbauservos wird die Position einzig durch die Länge eines positiven Pulses gesteuert. Die Wiederholfrequenz bestimmt die Aktualisierungsrate. Das Puls-Pausen-Verhältnis ist völlig unkritisch. Das verwechselst du wohl mit einer Helligkeitssteuerung o.ä. per PWM.
Mike J. schrieb: > Er wird die Servos mit dem AVR ansteuern Ja, ich muss sagen ich dachte bei servos an DC Motoren mit Encoder, und dass dieser geregelt werden muss. Einfach nur ein Signal stellen ist ok mit dem AVR, auch wenn ich hierfür einen ST Mikrocontroller genommen hätte, der einfach genug Timer hat. Dann muss man keine Klimmzüge machen. Das kann man in CubeMX konfigurieren und das einzige was man an Code schreiben muss ist der Timerwert ins Register des Timers schreiben.
Rolf M. schrieb: > Nein, das darf kein Problem sein, denn das passiert auch an einer > klassischen Fernsteuer-Anlage, wenn auch nicht dauerhaft, sondern mit > starkem Jitter versehen. Sollte aber nicht. Die klassische analoge Übertragung hatte 20ms. Und da die Servos heutzutage nicht aus der Zeit der steinzeitlichen Analoganlagen stammen, können die mit kürzeren Framelängen klarkommen, müssen aber nicht. Ist aber zunächst egal, denn Steve M. schrieb: > Der Logic Analyser zeigt nichts an jedoch sieht man in der MCU das im > Hintergrund wohl der timer abläuft. Oliver
Oliver S. schrieb: > Sollte aber nicht. Die klassische analoge Übertragung hatte 20ms. Und das steht wo genau? Beim gemultiplexten Analogsignal gibt es die Pulse, deren Dauer die Servostellung steuert und die festen Pausen dazwischen, von den eine länger ist, um die Synchronisation zu ermöglichen. https://www.multiplex-rc-history.de/technische_beschreibung_-101.htm
Wolfgang schrieb: > Beim gemultiplexten Analogsignal gibt es die Pulse, deren Dauer die > Servostellung steuert und die festen Pausen dazwischen, von den eine > länger ist, um die Synchronisation zu ermöglichen. Die Pause ist aber nicht füs Servo, sondern für den Empfänger, damit der den Kanalzähler resetten kann.
Oliver S. schrieb: > Rolf M. schrieb: >> Nein, das darf kein Problem sein, denn das passiert auch an einer >> klassischen Fernsteuer-Anlage, wenn auch nicht dauerhaft, sondern mit >> starkem Jitter versehen. > > Sollte aber nicht. Die klassische analoge Übertragung hatte 20ms. Das schon. Allerdings variiert die Lage der Servo-Pulse innerhalb des 20ms-Intervalls und damit auch die Pausendauer, die ein Servo sieht. Im Schnitt sind es 20 ms, aber das ist in einem Frame mal weniger, in einem anderen mal mehr. Das ist bei der klassischen PPM-Übertragung ein inhärenter Bestandteil, und daher müssen alle Servos zwingend damit klar kommen. Abgesehen davon waren auch die 20ms nicht fest vorgeschrieben. > Und da die Servos heutzutage nicht aus der Zeit der steinzeitlichen > Analoganlagen stammen, können die mit kürzeren Framelängen klarkommen, > müssen aber nicht. Wie gesagt: In gewissen Grenzen müssen sie.
:
Bearbeitet durch User
STK500-Besitzer schrieb: > Die Pause ist aber nicht füs Servo, sondern für den Empfänger, damit der > den Kanalzähler resetten kann. Das macht er mit der verlängerten Pause.
Um mal wieder aufs Thema zurückzukommen: Compilieren bringt bei mir ein gefültes dutzendmal die Warnung:
1 | ../main.c:71:55: warning: array subscript 2 is above array bounds of 'uint8_t[2]' {aka 'unsigned char[2]'} [-Warray-bounds] |
2 | 71 | SERVO_DDR = ServoPuls[0] | ServoPuls[1] | ServoPuls[2] | ServoPuls[3] | |
Solche grundlegenden Fehler solltest du als erstes Mal beheben. Oliver
Steve M. schrieb: > Der Logic Analyser zeigt nichts an jedoch sieht man in der MCU das im > Hintergrund wohl der timer abläuft. Unwahrscheinlich.
1 | // initialize counter
|
2 | TCNT1 = 0; |
3 | OCR1A = MILLISEC_BASE + ServoValue[0]; |
4 | TIMSK0 |= (1<<OCIE1A); |
5 | TCCR1B = (1<<WGM12) | PRESCALER_BITS; // CTC mode |
Finde den Fehler... Oliver
So und jetzt?? Nun haben wir zig-mal darüber gestritten, welche Pause und welches Signal das Servo nun haben möcht...auch die "modernen" digitalen Servos wurden angesprochen... Wolfgang schrieb: > von den eine > länger ist ...die Ente kommt nicht ins Wasser!
Hallo, an alle und noch ein schönes neues Jahr! Hab mein Programm nun, mit einigen Änderungen zum Laufen gebracht. Ich würde es mal hier reinstellen, eventuell hilft es ja noch jemandem der ähnlich Probleme hat. Danke für euere Hilfe Grüße Steve
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.