Forum: Mikrocontroller und Digitale Elektronik wie entsteht der "Jitter" bei Servos ?


von Frank (Gast)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

Wie soll man denn sagen, wo der Fehler in Deinem Programm ist, ohne es
zu sehen ?


Peter

von Frank (Gast)


Angehängte Dateien:

Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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

von crazy horse (Gast)


Lesenswert?

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.

von ...HanneS... (Gast)


Lesenswert?

Hi Frank,

was soll dein Programm eigentlich bezwecken?

...HanneS...

von Frank (Gast)


Lesenswert?

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

von crazy horse (Gast)


Lesenswert?

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.

von Frank (Gast)


Lesenswert?

Egal, ich schreib das Programm in Assebler neu und fertig.

Danke euch

von Ingo (Gast)


Lesenswert?

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

von Frank (Gast)


Lesenswert?

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

von Ingo (Gast)


Lesenswert?

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

von Jörn (Gast)


Lesenswert?

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

von Ingo (Gast)


Lesenswert?

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

von buz11 (Gast)


Lesenswert?

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 .

von Peter D. (peda)


Lesenswert?

"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

von ...HanneS... (Gast)


Angehängte Dateien:

Lesenswert?

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...

von Wolfgang (Gast)


Lesenswert?

@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
Noch kein Account? Hier anmelden.