Hi, Wie entsteht der Jitter beim ansteuern von Servos und wie verhindert man ihn? Habe ein Programm geschrieben zum ansteuern von 8 Servos mit einem AT90S2313. Jedoch ab und zu zittert das Servo und ich messe mit meinem Oszy eine "seltsame" Welle am ende des Rechtecksignals. Gruß Frank
Wie soll man denn sagen, wo der Fehler in Deinem Programm ist, ohne es zu sehen ? Peter
Eigentlich war die Frage eher auf das allgemeine Problem des Jitters bezogen. Das ist ja nicht nur ein spezielles Problems meines Programms. Es würde mich eben Interessieren wodurch der Jitter entsteht. Wenn das jedoch nur anhand meines Programmcodes zu beantworten ist: Programm ist im Anhang beigefügt. Frank
TCCR0=0x01; TCNT0=0xB0; Sowas guckt sich keiner an. Nimm bitte die Symbolnamen, damit man sieht, was Du machst. Das ist dann auch für Dich fehlersicherer. Warum schaltest Du im Interrupt die Registersicherung ab ? Bist Du wirklich sicher, daß nur R30 verwendet wird ? Die Jitter kommen daher, daß durchlaufzähler ein int (=2 Byte) ist, d.h. die Hauptschleife braucht 2 Zugriffe, aber dazwischen kann der Interrupt den Wert ändern und Du hast dann 2 nicht zusammen passende Bytes. Entweder Du machst die Servos mit im Timer Interrupt oder sperrst für jedes Auslesen des durchlaufzähler den Interrupt. Peter
ich habe das Programm nicht so recht durchschaut, aber wenn du eine Variable "Durchlaufzähler" sowohl in der Timer-ISR als auch als Schleifenzähler im Hauptprogramm verwendest/veränderst, ist Kuddelmuddel vorprogrammiert. Eine Lösungsmöglichkeit wäre, die Zählervariable zu kopieren und dann damit zuarbeiten. timer__isr: durchlaufzähler++; im Hauptprogramm dann: durchlaufzähler_bak=durchlaufzähler; einmal kopieren und dann damit weiterarbeiten. Und selbst das kann schiefgehen, wenn der Timer_int genau zwischen der Kopieraktion kommt, low-byte ist schon übertragen, dann kommt der Int, anschliessend wird das high-byte kopiert. Mögliches Szenario: die Variable bträgt 0x00ff, nach dem Kopieren hat man den völlig falschen Wert 0x01ff. Dagegen hilft entweder ausschalten des Int #asm ("cli") durchlaufzähler_bak=durchlaufzähler; #asm ("sei") oder das Synchronisieren des Programmablaufs durch Flags. Ich weiss jetzt gar nicht genau, wie das mit dem Vorteiler beim 2313 war, wenn TCNT1 geschrieben wird, das wäre eine weitere mögliche Fehlerquelle. Am allerbesten lässt du den Timer1 komplett durchlaufen und arbeitest nur mit dem OCR-Interrupt. In der ISR löschst du alle Servo-Pins, liest den TCNT1, addierst dazu den Wert des jeweils aktuellen Servos und setzt den entsprechenden Pin, fertig.
Hi Frank, was soll dein Programm eigentlich bezwecken? ...HanneS...
ohjeh, ich merk schon ich hätte das Programm nicht posten sollen. Kann mir den keiner ne allgemeine Antwort darauf geben, was das zittern (jitter) eines servos verursacht? Wenn ich einen Modellbau- empfänger kaufe steht im Datenblatt imm jitterfrei dabei, giebt es jemaden der mir sagen kann wie die das erreichen und wie die Problematik überhaupt entsteht? @peter dannegger: Welche Symbolnamen bitte? Ich habe den Namen verwendet wie das Register im Datenblatt verzeichnet wird. Timer/Counter0 Control Register - TCCR0 und Timer/Counter0 TCNT0, so steht es jedenfalls in meinen Datenblättern, ich denke es geht nicht eindeutiger. Ich schalte die Registersicherung ab da ich hierdurch enorm Zeit einspare den sonst sichert er von R26 bis R31. Ich habe mir den ASM code durchgesehen, es wird nur R30 verwendet. "ein int (=2 Byte)" - Bei mir ist ein int 8bit = 1Byte. Zudem tritt das zittern nur dan GELEGENTLICH auf wenn mithilfe der taster den Wert Position[0] verändere. Ist der Wert einmal eingestellt und das Servo zittert nicht, beginnt er auch nach Stunden nicht zu zittern, deswegen möchte ich deine Erklärung für das problem anzweifeln. Denn es muss doch im zusammenhang mit der wertveränderung stehen, oder? - ABer auch hier möchte ich nochmal erwähnen das mir eine allgemeine betrachtung des Servo zitterns lieber wäre. @Crazy horse: Ich sehe die Problematik ehrlich gesagt nicht mir dem Kuddelmuddel. Es wird ja nicht gleichzeitig auf diese Variable zugegriffen, entweder wird sie auf 0 gesetzt oder sie wird eins hochgezählt. Der Controller kann ja immer nur eins von beidem machen, wo sollte es da Probleme geben? Und ein Interrupt unterbricht den Controller ja nicht innerhalb der ausführung eines Befehls, also das das auf 0 setzen nur "halb" ausgeführt wird. @HanneS: Es steuert 8 servos an. Gruß Frank
ich weiss nicht, was du hören willst - du hast einige mögliche Schwachpunkte genannt bekommen, an denen es liegen kann, die willst du alle nicht oder meinst, das könne alles nicht sein. Ich kann dir nur sagen, du irrst dich, ob du es glaubst oder nicht, soll mir letzten Endes egal sein. Woher nimmst du die kühne Behauptung, der Controller würde nicht während eines Befehls unterbrochen? Das ist auf Assemblerebene richtig, aber niemals in einer Hochsprache (es sein denn, du hast einen C-Befehl, der tatsächlich nur einen einzigen Assemblerbefehl erzeugt). Ansonsten bestehen C-Befehle aus einer ganzen Reihe Assemblerbefehlen, oft sogar mit UP-Aufrufen (Code-Grössen-Optimierung). Und wenn bei dir eine int-Variable nur ein Byte gross ist, solltest du nochmal bei den Grundlagen anfangen.
Egal, ich schreib das Programm in Assebler neu und fertig. Danke euch
Hi Frank, wie hoch ist der Jitter? Tritt er immer auf und bei jedem Servo? Oder kann es sein, das der Fehler nur dann auftritt wenn mehrere Servos gleichzeitig bewegt werden? So weit ich das gesehen habe, stellst Du das Signal für alle Servos gleichzeitig zur Verfügung. Ich würde das Programm so ändern, das die Servos nacheinander bedient werden. GRUSS INGO
Hi Ingo, "wie hoch ist der Jitter?" - Schwer zu beschreiben, er zittert schon sehr, optisch sichtbar. Mit dem oszy ist das Signal schwer zu messen, mein trigger versagt hier- habe leider kein speicher oszy. Das Zittern tritt nur selten auf, in 80% der Fälle (neuer Wert eingestellt) funktioniert das Programm fehlerfrei. Wenn ich die Werte gleich beim Flashen übertrage, Funktioniert es immer, nur wenn ich sie mit den tastern verändere kommt es gelegentlich zum zittern. Ich habe onehin nur ein Servo hier, kann also nicht sagen wie sich die Schaltung mit mehreren Servos verhällt. Nochmal ein Versuch die Intention meines Posts darzulegen: Da mir onehin klar ist das mein Programm noch Prototypenstaus hat und noch ettliche Fehler aufweisst, wollte ich es eigentlich gar nicht posten. Ich war/bin eben der Meinung das das Problem mit dem Jitter ein allgemeines ist und nicht speziell ein Problem meines Programms. Schlieslich werden, wie schon erwähnt, Modellempfänger ausdrücklich als Jitterfrei verkauft, somit hatte/habe ich die Vermutung das es auch mit der Hardware eines Servos und/oder einer speziellen Art der Programmierung/Aufbau eines Empfängers zu tun hat. Wenn ich mich hier irre, dann sagt mir das. Die Definition von Jitter lautet: "In der Informationstechnik bezeichnet man den abrupten und unerwünschten Wechsel der Signalcharakteristik als Jitter. Dies kann sowohl die Amplitude als auch die die Frequenz betreffen." Leider wird nirgends näher beschrieben was diesen "unerwünschten Wechsel der Signalcharakteristik" auslöst, bzw wie mann ihn verhindert. - Worauf ich hinaus will: Ich sage nicht das mein Programm fehlerfrei sei, im Gegenteil! Aber: Das mit dem Jitter ist doch offenbar ein allgemnein bekanntes, villeicht nichteimal software speziefisches Problem, somit muss es doch auch eine allgemeine, villeicht nichteimal softwaremäsige, Lösung geben, oder sehe ich das falsch? Deswegen habe ich diese Thema begonnen, ich wollte mich erstmal allgemein mit der Jitterproblematik und deren lösungsansätze auseinander setzen bevor ich den Fehler in meinem Programm suche. Dies würde mir möglicherweise helfen, Fehler die andere schon begangen und behoben haben nicht nochmals zu wiederhohlen. Wenn ihr meiner Intention jedoch nicht folgen könnt, vergesst diesen Post. Danke, Gruß Frank
Hi Frank, "wat ein Jitter is wees icke" -- griinnzz -- Spass bei Seite, wenn Du das "Jitter" Problem bereits so weit eingegrenzt hast, dann liegt es ganz klar am Programm!! Ich hatte die Vermutung das der Jitter (in Deiner Schaltung) dann auftritt, wenn Du mehrere Servos gleichzeitig änderst!!! Die Servos (so klein sie auch sind) verursachen mit unter enorme Lastspiten auf der UB. Deshalb der Tipp die Servos nicht gleichzeitig bewegen, sondern Einer nach dem Anderen. Was nun das Problem angeht, (ich hab nicht mehr in den Code gesehen --SORRY--) so vermute ich mal, das die Änderungen die mit den Tastern eingestellt werden sofort und in vollem Umfang an die Servos weitergeleitet werden. Wenn die Änderung der Signalbreite mitten im Senden an den Servo vorkommt, kann das einen Jitter produzieren. Du solltest dafür sorgen, das die Impulsbreite während sie an den Servo gegeben wird nicht verändert werden kann. guke gleich noch mal in den Code (jetzt muss erst der Wurzelzwerg in die HEIA)wenn ich noch was finde poste ich noch mal!!! GRUSS INGO
Moin Frank, vielleicht ist das Problem tatsächlich nicht im Programm zu suchen. Ich hatte das gleiche Problem beim Ansteuern eines Servos, der relativ stark zitterte. Neben dem Servo waren noch etliche weitere Verbraucher an den selben Akku angeschlossen. Ich vermutete das Problem bei einer schwankenden Akkuspannung, die über die Potentiometerrückkopplung des Servos diesen zittern lassen. Ein eigener Akku nur für Servo und den Servotreibenen µC brachte dann auch den gewünschten Erfolg, vielleicht hätte es aber auch ein vernünftiger Elko getan. Vielleicht ist der Fall bei Dir ja ein ähnlicher. Gruß, Jörn
So ich habe jetzt noch mal in den Code gesehen! Dabei habe ich zwei Fehlerquellen entdeckt, die für den Jitter in Frage kommen. 1. Der Interupt: Da ich aus der PIC-Welt komme bin ich mir nicht 100% sicher. Deshalb den Fehler als Frage: Ist die Anzahl der auftretenden Interupts während der Zeit des Zählerduchlaufs konstant? Wenn nicht, dann können mehr oder weniger Interupts die Impulsbreite verändern -- Jitter -- 2. Die Tasterabfrage: Du fragst die Taster während der Zählerdurchläufe ab. Wenn nun der Zähler mit Position[0] gleich ist, setzt Du den Pin auf Low. Soweit OK! Wenn nun aber unten am Ende der WIHLE-Schleife Position[0] inkrementiert wird, dann wird im nächsten Zählerdurchlauf der Pin wider auf High gesetzt. -- BÖSER JITTER -- Vorschlag zu 2. while . . . . } for(Durchlaufzaehler1 = 0; Durchlaufzaehler1 <= 10; Durchlaufzaehler1++) { for(Durchlaufzaehler = 0;Durchlaufzaehler <= 128;) { PORTB=0x00; } } if (PIND.4 == 0 ) Slave[0]+= 1; if (PIND.6 == 0 ) Slave[0]-= 1; if (PIND.4 == 1 && PIND.6 == 1) Postion[0] = Slave[0]; }; Ich hoffe ich konnte Dir ein wenig helfen GRUSS INGO
Hi ! Ein jittern ist erstmal von Haus aus dabei . Die einfachen , billigen , Fernsteuerungen sind zwar auch " digital " ( weil Impulse , und nicht Pegel ) , aber ansonsten analog . MC's haben die einfachen weder im Sender noch im Empfänger drin . Das Zittern ( Ursache = Impulsjitter ) wird in den Servos zum Teil mit mehr oder weniger gross eingestellter Hysterese unterdrückt . ( alles analog ! ) Habe eine menge Billigservos . Sehr grosse Hysterese , für Höhenruder nicht zu gebrauchen . Dafür musste ich mir ein paar bessere kaufen . ( kleine Hysterese , immer noch ruhig ) Für die Lenkung am RC-Car habe ich paar ultraschnelle Servos . Die sind schon ziemlich nervös . ( immer noch alles analog ) Softwaremässig lässt sich eine ( beliebig grosse ) Hysterese proggen ! Viel Spass .
"Wenn ihr meiner Intention jedoch nicht folgen könnt" Du bist doch derjenige, der hier alle Hilfe ignoriert. Wenn int = 8Bit ist dann ist wohl char = 4Bit oder wie ? Steck Deine Nase ruhig mal in ein C-Buch. Und wenn 2 Leute genau das gleiche posten, sollte man es doch erstmal ausprobieren, statt nur rumzulamentieren. Peter
Hallo Frank... Entschuldige bitte, dass ich nach dem Zweck des Programms gefragt hatte. Dass es 8 Servos ansteuern soll, hatte ich schon verstanden. Mir war allerdings unklar, woher die Information kommen soll, die die Stellung der 8 Servos bestimmt. Auch war mir nicht klar, warum du einen 16-Bit-Wert (int) als Zähler verwendest, den du dann noch mit 8-Bit-Werten deines Arrays vergleichst. Naja, ist ja eigentlich auch egal. Ich habe mal ein Programm angehängt, das auch Servos ansteuern kann. Allerdings kann es nur 7 Servos ansteuern und ein HF-Modul. Das Programm läuft bei mir in einem "Testsender", also einem RC-Sender, der auch ohne HF-Teil (dem eigentlichen "Sender") und Empfänger zum Testen von Servos, Fahrtreglern und anderen Modellbau-Komponenten dient. Deshalb erzeugt der AVR neben dem Sendertastimpuls auch noch die 7 Kanalimpulse, was für ein Sender-Impulsteil eigentlich unüblich ist. Das Programm mag noch Mängel und Fehler enthalten, tut aber zuverlässig seinen Dienst. Mir ist (inzwischen) auch klar, dass mein Programmierstil noch lange nicht optimal ist. Auch ich verwende noch zu selten die Symbolnamen für die Bits der Register im I/O-Bereich, werde aber in Zukunft etwas mehr darauf achten. (Danke, Peter...) Jitter (also flatternde Servos oder Fahrtregler) sind mir bei meinem Programm bisher nicht aufgefallen. Allerdings haben die von mir programmierten Fahrtregler eine Art Hysterese in der Impulsbreitenmessung und eine gewisse (gewollte) Trägheit, die verhindert, dass abrupte Änderungen der Impulsbreite sofort an der Motor-PWM wirksam werden... Es ist in Assembler, da mir (noch) die Kompetenz für C fehlt... Bit- & Bytebruch... ...HanneS...
@Frank, schlage vor, dass Du mit Deinem Oszi die Impulslänge kontrollierst ohne ein Servo anzuschließen. Ist die Impulslänge konstant, liegt es am Servo bzw. an der Stromversorgung für das Servo. Eigentlich sollte die Form des Rechtecksignal keine Auswirkungen haben solange die Impulslänge konstant bleibt. In der Regel wird mit der Vorderflanke des Impulses ein Referenzgenerator (monostabiler Multivibrator) angestoßen, der einen Vergleichsimpuls liefert. Die Länge des Vergleichsimpuls ist abhängig von der Stellung des Poti im Servo. Sind beide gleich, bleibt das Servo stehen, bei Ungleichheit wird solange nachgestellt bis beide wieder gleich sind. Dieser Regelkreis wird zur Vermeidung des Pendeln um die Nullage elektronisch bedämpft. Ist die Dämpfung unzureichend, kommt es zu Schwingungen. Da das Pendeln nicht immer auftritt, tippe ich auf unkonstante Impulslänge. Wenn Du mehrere Servos hast, probier mal ein anderes Servo aus. Ist die Impulslänge nicht konstant, liegt es am Programm, Sender oder Empfänger; aber das könnte man mit dem Oszi wiederum einkreisen. Wolfgang
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.