Forum: Mikrocontroller und Digitale Elektronik Servos zittern - Warum? Problemlösung?


von Florian S. (buddl)


Lesenswert?

Hallo

Ich habe ein Problem mit meinen Servos.

Ich verwende 2 Standard-Servos (HiTec HS425 o.ä.), die ich mit BASCOM 
BASIC ansteuern will. Das Ansteuern klappt eigentlich soweit gut.
Einziges Problem ist, dass die Servos im eigentlichen Ruhezustand 
zittern.

Versorgung ist 6V. Ich habe schon alle möglichen Steps (in µs) 
durchprobiert.
Die Servos sind direkt an einen ATmega128 angeschlossen und mit dem 
folgenden Code (BASCOM BASIC) initialisiert:

----------------------
'Initialisierungsroutine für die Servos
Config Servos = 2 , Servo1 = Portb.7 , Servo2 = Portb.4 , Reload = 14 , 
Timer = Timer0
Config Portb.7 = Output
Config Portb.4 = Output
----------------------

Dieses Zittern hört sich außerdem ziemlich ungesund an. Ist das für die 
Servos schädlich? Wie kann ich es beseitigen?

Für die, die Zeit und Lust haben habe ich ein Video gedreht. Ist leider 
25MB groß. Virenfrei und hier downloadbar:
http://flashcraft.de/MVI_1183.AVI
Evtl. müsst ihr den Lautstärkeregler etwas aufdrehen.

Vielen Dank schonmal!
Gruß
Florian

von 6638 (Gast)


Lesenswert?

Du verlangst ein Drehmoement und es wird nur alle Servopule 
nachgeregelt. Es gibt 2 Wege :
1) mehr Servopulse pro Zeiteinheit.
2) ein Digitalservo, das abeitet kontinuierlich.

von Florian S. (buddl)


Lesenswert?

Hallo!

Das Problem tritt aber auch auf, wenn die Servos nicht eingebaut sind, 
also frei herumliegen und kein Drehmoment bereitstellen müssen.

von Florian S. (buddl)


Lesenswert?

Oh und was ich gerade auch bemerke ist, dass die Strombegrenzung an 
meinem Labornetzteil anfängt zu "flackern" sobald ich die Servos 
zuschalte.
Sie springt nicht richtig an, sondern immer nur in bruchteilen von 
Sekunden.

von Michael H* (Gast)


Lesenswert?

vllt herstellungs- oder altersbedingt? wenn der interne poti schon zu 
abgeschliffen ist, könnte ich mir so ein zittern schon vorstellen.
oder ist dein timing im code vllt durch zu viele befehle nach dem 
timer-interrupt verschlechtert? so könnten rechts- oder linkslaufbefehle 
auftreten...

von Florian S. (buddl)


Lesenswert?

Die Servos sind eigentlich recht neu und wurden noch für nichts anderes 
benutzt. Ich kann mir auch fast nicht vorstellen, dass beide 
alterungsbedingt genau das selbe Symptom aufzeigen.

Ich habe in der Tat jede Menge Code in meinem Programm. Darunter jedoch 
nur 2 andere Interrupt-Routinen (für 2 konventionelle E-Motoren). Der 
ATmega ist mit rund 14,7 MHz getaktet, der sollte das eigentlich schon 
in den Griff kriegen.

Aber ich werds morgen, oder besser heute Nachmittag mal mit Minimal-Code 
versuchen.

von Alex B. (Firma: Ucore Fotografie www.ucore.de) (alex22) Benutzerseite


Lesenswert?

Hallo,
ich hab' mir das Video gerade angeschaut. Sieht aus wie der Moving-Head 
den ich auch mal gebaut hab' :-)
An und für sich sieht es ja schon ganz gut aus. Zwei Dinge fallen mir 
ein, die es sein könnten:
1) Die Servos sind einfach überlastet (Ist ja schon ne große Masse die 
die Servos da bewegen sollen)

2) Sendest du die PWM für die aktuelle Position kontinuierlich, d.h. 
auch wenn der Servo sich nicht verstellen soll musst du die alte 
Position immer weiter wiederholen

Schöne Grüße,
Alex

von Florian S. (buddl)


Lesenswert?

Hallo

Das ist weniger Last als nach was es aussieht ;) Vielleicht 400g oder 
sowas.
Aber wie gesagt, die Servos zittern auch OHNE Last. Das ist ja das 
komische.
Das Signal wird ständig gesendet.


Ich hab mal mit dem LogicAnalyzer das Signal getriggert und die 
Pulsbreiten gemessen. Heraus kam sowas hier:


-------------------
1
Pulsbreiten in Ruhelage:
2
1,71903ms
3
1,72412ms
4
1,71910ms
5
1,71910ms
6
1,71910ms
7
1,71910ms
8
1,71910ms
9
1,71909ms
10
1,71909ms
11
1,72696ms
12
1,71909ms
13
1,71909ms
14
1,71909ms
15
1,71909ms
16
1,71909ms
17
1,71909ms
18
1,71909ms
19
1,72465ms
20
1,72465ms
21
1,71909ms
22
1,71909ms
-------------------

Sieht eigentlich relativ vernünftig aus, aber es gibt vereinzelt 
Ausreisser.

Vielleicht sind sie das Problem. Der Unterschied zwischen dem kleinsten 
(1,71903ms) und größten (1,72696ms) Wert liegt bei 0,00793ms = 7,93µs. 
Bezogen auf die Ruhelage (1,71909ms) ist das 0,46% Abweichung.

Aus dem Datenblatt geht hervor, dass 400µs Pulsbreitendifferenz (zur 
Nulllage hin) 45° entsprechen. Dann entsprechen 7,93µs Differenz 0,89°.
Das könnte schon hinkommen...

Was mir aber nun auffällt, wenn man sich mal das Datenblatt anschaut:
http://www.hitecrcd.com/product_file/file/49/hs422.pdf

Die neutrale Lage sollte bei 1,5ms liegen.
Nun sind die Servos zwar nicht in Ruhelage aber auf das Zittern wirkt 
sichs  ja nicht aus.

EDIT: Beitrag etwas geändert

von Falk B. (falk)


Lesenswert?

Die Servoansteurung nutzt je einen Timer. Vielleicht kollidert da was 
mit anderen Interrupts. Was sagt das BASCOM Handbuch zu mehreren Servos 
gleichzeitig?

MFG
Falk

von Mathi (Gast)


Lesenswert?

Wenn ich das Datenblatt richtig interpretiere, sind die Ausreißer wohl 
die Ursache. Das sind fast 8µs wie in der Dead band width angegeben. 
Kann aber auch sein das ich das völlig falsch interpretiere...

von Alexey (Gast)


Lesenswert?

Hallo,

Poste doch mal das Programm, eventuell kann man den Fehler dann 
ausmerzen.
Ich habe selbst schon mit Bascom mehrere Servos angesteuert und das 
ging, nur ist das Interrupt-Handling da etwas kritisch.

von Florian S. (buddl)


Lesenswert?

Ich denke auch, dass es daran liegt.
Aber ich weis nicht was ich dagegen tun kann.


Das BASCOM Programm ist ziemlich groß. Das HEX-File stemmt 66KB. Das 
sind mehrere tausend Zeilen Code...

Daran lässt sich im Wesentlichen auch nichts ändern. Außer ich schalte 
einen zusätzlichen Mega dazwischen, der nur für das Servosignal 
zuständig ist.

von Florian S. (buddl)


Lesenswert?

Ich werde mal kurz ein Programm machen, das nur die Servoansteuerung 
enthält und sonst nichts mehr. Mal schauen wies dann so aussieht.

von Michael K. (mmike)


Lesenswert?

Bei Servos muss das Signal super stabil sein, sprich die 1.5ms für die 
Neutrallage. Änderungen der Pulsweite von wenigen µs reichen da schon, 
dass sie das zittern anfangen !! Also am besten die Hardware PWM outputs 
verwenden, dann ists das Problem gegessen !
Grüße,
Michael

von Florian S. (buddl)


Lesenswert?

Hallo mal wieder


Also auch bei einem neuem Programm, das nur die Servos ansteuert bleibt 
das Zittern bestehen. Ich verstehs echt nicht. Vor allem weil ich mir 
mal recht sicher war, dass ich es irgendwann vor einiger Zeit mal 
wegbekommen habe...

An der Pinbelegung kann ich nichts drehen. Zudem sind die PWM Ports an 
dem Mega sowieso schon vergeben.

Ich werds wohl so lassen, immerhin weis ich nun an was es liegt.

von Mathi (Gast)


Lesenswert?

mach nochmal die Messungen... Schau ob die Zeiten noch immer schwanken.

von Luis (Gast)


Lesenswert?

Schalt' doch mal dein handy aus und versuche die verbindung zu den 
servos mit etwas masse abzuschirmen. Bei mir hat's geholfen...


mfg

von Florian S. (buddl)


Lesenswert?

Das wird immer kurioser.
Eine Messung habe ich jetzt noch nicht gemacht, folgt später, muss jetzt 
aber gleich weg.

Aber was mich gerade verblüfft hat: Ich lade das Testprogramm (indem der 
Mega nur den Servo ansteuert) und schau mir die Motorspannung an. Die 
lag bei rund 5,94V. Okay. Aus Spaß habe ich die Motorspannung einfach 
mal etwas verringert und bei ca. 5,04V hörte das zittern schlagartig 
auf!!
Es ist aber nur bei ca. 5,04V so, und nur bei einer bestimmten 
Pulsbreite. Erniedrige ich die Spannung weiter oder veränderte die 
Pulsbreite fängt das Zittern wieder an.

Mittlerweile weis ich gar nichts mehr. Ich werd mir, sobald ich Zeit 
habe mal eine Messung bei ca. 5,9xV machen und eine bei 5,04V (jeweils 
bei selber Pulsbreite) und diese miteinander vergleichen.

von Florian S. (buddl)


Angehängte Dateien:

Lesenswert?

So, ich bin wieder etwas weiter gekommen.

Ich habe was interessantes feststellen können.

Ich habe jetzt das Signal vom Testprogramm des ATmega128 aufgezeichnet. 
Zusätzlich habe ich noch meine CMUCam die Servos steuern lassen und auch 
dieses Signal aufgezeichnet. Die CMUCam ist eine Kamera, die Servos 
ansteuern kann, völlig unabhängig von meinem AVR.


Das Ergebnis seht ihr im Anhang.
-  Der AVR sendet die Pulse im Abstand von 31,9ms
-  Die CMUCam sendet mit einem Abstand von nur 19ms!!


Nachdem ich den Code so umgeschrieben habe, dass die Senderate vom AVR 
gleich der, der CMUCam entspricht hört sich das Signal schon wesentlich 
ruhiger an. Es brummt nun teilweise immer noch. Erinnert aber eher an 
starkes Netzbrummen als an Zittern. Teilweise verschwindet das Zittern 
auch komplett.

Jedoch ist dieses Brummen auch da, wenn ich die Servos mit der CMUCam 
ansteuere, und deren Signal ist EXTREM präzise. Daher denke ich liegt es 
nun nur noch an den Servos. Naja aber damit kann ich leben. Vor allem da 
ich jetzt weis woran es liegt ;)

Danke für die Hilfe!

von user (Gast)


Lesenswert?

Die Frequenz sollte normalerweise bei rund 50Hz liegen. Die Graupner 
Sender senden mit einer Periode von 22.5 ms.

von Florian S. (buddl)


Lesenswert?

Und es geht weiter...

Ich glaube dieses abnormale Verhalten hat einen weitaus tieferen Grund.
Ich war gerade dabei das normale Programm wieder zu laden - Mit 
veränderter Frequenz - Und schon hatte ich dieselben Probleme wieder.

Also habe ich erstmal alles was ich nicht gebraucht habe im Code 
auskommentiert, mit dem Ergebnis, dass es dann wieder "klappte" (eben 
mit Brummen und so). Nun habe ich Komponente für Komponente wieder 
reaktiviert und geschaut woran es liegt.

Anscheined hat der I2C Bus sowie der A/D Konverter sehr große 
Auswirkungen. Sobald ich einen von denen aktiviere geht die Geschichte 
wieder los.

Ich verstehe aber nicht wieso. Auf der PCB kreuzen sich die Leitungen 
nicht. Im Gegenteil - Räumlicher getrennt kann es kaum sein.
Auch dem A/D Konverter habe ich, wie es Atmel empfielt, ein L und ein C 
spendiert.

Die Leitungen sind zwar nicht abgeschirmt aber auch daran kanns nicht 
liegen. Eine Servoleitung ist in einem Kabelbündel mit diversen anderen 
Leitungen, eines dagegen liegt frei herum - Und beide zeigen das selbe 
Phänomen.

von Bernhard M. (boregard)


Lesenswert?

Für mich sieht das so aus, daß da die Interrupts zeitweise blockiert 
sind (vielleicht von einer anderen Interruptroutine, die läuft), und 
deshalb etwas verzögert werden....

von Falk B. (falk)


Lesenswert?

@ Florian Scherb (buddl)

>Anscheined hat der I2C Bus sowie der A/D Konverter sehr große
>Auswirkungen. Sobald ich einen von denen aktiviere geht die Geschichte
>wieder los.

Wahrscheinlich dauern die Interrupts für diese Module recht lange, 
dadurch kommt das Timing der Servos aus dem Tritt.

Ergo. Es geht nichts über echte PWM-Ausgänge. Ändere dein Pinout.

MfG
Falk

von Florian S. (buddl)


Lesenswert?

Das Pinout kann ich wie gesagt nicht ändern. Zudem die Hardware-PWM 
Ausgänge schon von anderen Motoren beansprucht werden.

Dazu kommt, dass der A/D Konverter kein Interrupt besitzt, genau wie die 
I2C Routine.

Was auch auffällig ist, ist dass einer der Servos nun sehr sehr ruhig 
ist. Der führt seine Aktionen fast ohne Brummen aus. Nur mit einem hab 
ich noch diese Probleme. Ich denke langsam wirklich, dass es an den 
Servos liegt. Wenn die Servos durch irgendwelche Interrupts gestört 
werden würden, müssten davon ja beide betroffen sein, das ist aber nicht 
mehr der Fall. Und mit der CMUCam brummen sie ja auch, und deren Signal 
ist perfekt.

Ich werd noch etwas rumdoktorn und mir mal einen neuen Servo kaufen. Das 
ist doch nicht mehr normal...

von Volker (Gast)


Lesenswert?

Hallo, wie sieht denn die Spannungsversorgung der Servos aus? Ist da 
vielleicht schon eine Brummspannung drauf?


Gruß Volker

von Florian S. (buddl)


Lesenswert?

Puh...

Jetzt hab ich den Fehler doch endlich gefunden.
Eure Vermutung war richtig. Es liegt an der UART, jedoch nicht an I2C, 
A/D Wandler und dem Rest.

Ich habs jetzt geschafft, dass die Servos absolut ruhig ihre Position 
halten, jedoch mit deaktivierter UART.

Die einzige Lösung, die ich sehe ist, dass ein zusätzlicher AVR die 
Ansteuerung übernimmt und der zentrale AVR nur einen Bitcode senden 
muss.

Die Problemlösung war wesentlich komplizierter weil hier 3 AVRs und 1 PC 
miteinander vernetzt sind.

Dann mal ran an den Lötkolben ;)

von Εrnst B. (ernst)


Lesenswert?

UART ohne Interrupts nur mit Polling betreiben geht nicht?

von Florian S. (buddl)


Lesenswert?

Nein, das geht leider nicht.
Dazu kommt auch noch, dass ich beide UART-Schnittstellen des Mega128 
nutze.

von Falk B. (falk)


Lesenswert?

@ Florian Scherb (buddl)

>Dazu kommt auch noch, dass ich beide UART-Schnittstellen des Mega128
>nutze.

Mann-O-Mann. Was für ein hochkomplexes System hast du denn?

<Ketzerei>
Wenn man es mit Koff Hoff in C gemacht hätte würde es wahrscheinlich ein 
einzelner AVR locker schaffen.
</Ketzerei>

;-)
MFG
Falk

von Michael H* (Gast)


Lesenswert?

http://www.4finger.net/cms/servomaster.html
stammt auch hier irgendwo ausm forum. falls es wirklich nicht ohne gehn 
sollte.
was tut denn deine uart interrupt routine? mal probiert, die empfangenen 
daten inder ISR einfach nur in einem dicken array zu speichern und erst 
in einer funktion im main() auszuwerten?

grüße, holli

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.