Nabend
Ich habe ein Problem mit der Ansteuerung eines HS-475HB Servos von HiTec
Der Servo verlangt eine High-Low-Periode von 20ms mit einem Puls
zwischen 0,9ms und 2,1ms (wobei 1,5ms die Ruhelage ist). Soweit so gut.
Ich liefere dem Servo EXAKT dieses Signal (mit Pulsdauer 1,5ms).
Mit Logic-Analyzer kontrolliert: High-Low-Periode: 20,0102ms
Pulsbreite: 1,49952ms
Also viel besser geht echt nicht.
Trotz allem rattert der Servo beängstigend. Zwar bewegt er sich, aber es
hört sich so an, als wäre er gerade dabei sich selbst zu zerstören. Auch
die Welle "zittert" sich sichtbar.
Habe das ganze mit C programmiert, hier der Code:
Warum geht das nicht, das Signal ist wirklich ausgezeichnet (zumindest
sofern es mir mein Logic-Analyzer zeigt. Die Stromversorgen wurde
zwischen 3 und 6V vareiert -> keine Änderung.
Wäre super wenn ihr mir helfen könntet, ich sehe da absolut nichts...
Hier das Datenblatt:
http://www.hitecrcd.com/product_file/file/21/Servomanual.pdf
Hi,
Nur mal so...evtl. braucht das/der Servo invertierte Logik, also 1-2ms
low anstatt high. Hab mir allerdings nicht das Datenblatt
durchgelesen.Ist zu spät zum nachdenken^^
MfG
und3rt4ker
Hallo Budd, (?)
wie kommst Du denn bei einem CPU-Clock von 8MHz, einem Vorteiler von 8
und einem ICR1 von 9220 auf eine Periodendauer von 20ms? Da stimmt doch
was nicht.
Gruß,
Peter
Hey!
Ich hatte irgendwann die Nase voll von Berechnungen ohne "etwas zu
sehen". Darum hab ich meinen LA rausgeholt und ICR1 "von Hand" so
angepasst, dass eine Pulsbreite von 20ms dabei raus kam.
Aber trotzdem, auch wenn ich es nachrechne komme ich auf die 20ms:
(8*10^6)/8 = 1*10^6 (Clock nach Prescaler)
Maximum Count: 9220
9220 / 1*10^6 = 9,92ms
Da der Counter OC1A toggelt, braucht man 2 Durchläufe, also
9,92 = 2 = 19,84ms
Was sich in etwa mit meiner gemessenen Zeit deckt.
Oder habe ich da was falsch verstanden?
> Da der Counter OC1A toggelt, braucht man 2 Durchläufe, also
Nee, da hast Du was falsch verstanden. Im Fast-PWM Mode wird der Pin
OC1A beim "Nulldurchgang" des Timers gesetzt, bei Erreichen von OCR1A
zurückgesetzt. Der Timer selbst läuft hoch bis zum Erreichen von ICR1.
Also nix mit Toggeln.
Schreib einfach eine 20000 ins ICR1 und eine 1500 ins OCR1A, dann wird
auch Dein Servopuls stimmen.
Gruß,
Peter
Das ist doch aber kein Fast-PWM-Mode sondern CTC-Mode.
Ich habe mal deine Werte ausprobiert. Da erhalte ich eine Periode von
ca. 43ms und der Servo zittert weiter :-(
Bisher hab ich das nur auf 8051 und PC ausprobiert, das hat ganz
ordentlich funktioniert, zu deinem AVR-Programm kann ich allerdings
nicht viel sagen.
Die 20ms, (->50 Hz Refresh), sind unkritisch, im Zweifel lieber weniger
als mehr nehmen, z.B. 18ms oder 15ms, (bei den meisten Digitalservos
beträgt der Refresh ohnehin 100Hz -> 10ms). Soweit ich mich erinnere
läuft das bei einem "realen" Fernsteuerungsempfänger, (z.B. einem
Standardempfänger von Jamara), so, dass der komplette Zyklus max. 20ms
dauert, d.h. Wartezeit + Pulsdauer = max. 20 ms. Also wenn der Puls 2ms
lang ist (2ms + 18ms = 20ms) und wenn der Puls 1,5ms lang ist (1,5ms +
18ms=19,5ms), ich weiß nicht ob das einen tieferen Sinn hat oder einfach
nur von der jeweils verwendeten Schaltung herrührt.
Trotzdem funktioniert es auch, wenn man fix z.B. alle 20ms einen
Interrupt auslöst und dann, (im einfachsten Fall mit einer
Delayschleife), das Servosignal auf High setzt und dann nach z.B. 1500us
wieder auf Low, also so, dass alle Zyklen unabhängig von der Pulsbreite
immer 20ms dauern.
Das mit den Standard-Delayschleifen ist am Anfang, wenn man überhaupt
noch nicht weiß warum das mit dem Servo nicht klappen will, sowieso eine
gute Idee.
Irgendwas in der Art:
ServoPin(low)
loop:
delay(18000us)
ServoPin(high)
delay(1500us) ;wahlweise 1000us oder 2000us
ServoPin(low)
goto loop
Dann den Servo im stromlosen Zustand vorsichtig in eine Richtung drehen
und einschalten, nach einer handvoll Versuchen sieht man dann ob
zumindest prinzipiell alles funktioniert, vor allem auch elektrisch.
Apropos elektrisch, beim 8051 hab ich immer noch wahlweise einen
Treiber, Transistor oder Optokoppler zwischen Portpin und
Servosignaleingang geschaltet, der Servosignaleingang braucht zwar kaum
Strom, aber geschadet hat das zumindest nicht und das Rechteck hatte so
auf dem Oszilloskop "schäfere" Kanten, ohne Treiber sah es manchmal so
aus als hätte man einen kleinen Kondensator zwischen Signalpin und Masse
geschaltet, möglich, dass das bei den AVRs komplett überflüssig ist, die
können glaube ich bei High auch schon ein bisschen Strom liefern, das
mit dem Optokoppler ist aber nach wie vor eine Option, wenn man vor hat
Servo und Controller elektrisch soweit als möglich zu trennen, (so ein
Graupner Digitalservo zieht z.B. bis zu 2A Strom auf der
Versorgungsleitung).
Zu Bedenken ist eventuell auch noch, dass bei einer "richtigen"
Fernbedienung, normalerweise die Pulsbreite nie auf einen Schlag von
z.B. 1500us auf 2000us springt, sondern egal wie schnell man den
Steuerknüppel auch bedient, da immer noch kleine Zwischenschritte drin
sind, wieviele genau, hängt von Fernbedienung und Servo ab, (manche
Digitalservos haben angeblich eine Auflösung von 1024 Schritten, von
denen dann bei einer Knüppelbewegung von Neutralstellung bis
Vollausschlag gut die Hälfte durchlaufen wird). Ich schreib das nur,
weil ich manchmal schon das Gefühl hatte, dass wenn man von 1500us
direkt auf 2000us geht die Servos etwas zum "Überschwingen" neigen, d.h.
der Servo fährt mit Maximalgeschwindigkeit zum Vollausschlag und muss
dann am Ende der Bewegung minimal aber doch wahrnehmbar seine Position
korrigieren bevor er endgültig zum Stillstand kommt.
Ansonsten: Logikanalyzer ist sicher nicht schlecht aber Oszilloskop ist
besser, oder zeigt dir dein LA auch die Signalform an, z.B. irgenwelche
Ripple und Abrundungen?
Hallo und Danke für deinen Beitrag!
Ich habe leider nur einen LA, sonst hätte ich es schon mit dem Oszi
gemessen.
Ich habe jetzt mal so eine Schleife aufgesetzt:
1
DDRB=0xFF;
2
while(1)
3
{
4
PORTB=0x00;
5
_delay_us(18500);
6
PORTB=0x02;
7
_delay_us(1500);
8
}
Die Werte habe ich auch etwas vareiert.
Aber der Servo zittert einfach immer noch total. Ich versteh das einfach
nicht.
Ein I/O Pin eines AVR kann schon einige mA verkraften. Auch 10mA sind
noch drin.
Das wirft mir wirklich Rätsel auf...
Budd, in Deinem Quelltext oben hast Du WGM11, WGM12 und WGM13 gesetzt.
Damit arbeitet der Timer im Mode 14 und das ist nunmal der Fast-PWM
Modus. Steht so im Datenblatt.
Wenn jetzt der Servopuls nicht stimmt, ist was anderes faul. Eventuell
läuft der Prozessor nicht mit 8MHz. Hast Du mal die Fuses kontrolliert?
Schließe doch mal probehalber einen externen Quartz an.
Gruß,
Peter
Und nochmal...
Habe das ganze nun auch mal mit verschiedenen Pulswerten und Servos
ausprobiert.
Ergebnis: Alle Servos zeigen ähnliches Verhalten. Sie gehen außerdem
immer nur in die Nulllage. Egal welchen Pulswert man ihnen gibt.
Hallo Budd,
hast Du irgend ein anderes Gerät, an welchem Du den Servo testen kannst
?
Wenn ein Servo zwar in die richtige Position fährt, dort aber zittert,
dann ist entweder der Servo defekt (meistens das Poti) oder das
Steuersignal nicht konstant.
Wenn Du den Servo sicher als nicht defekt einstufen kannst, dann
verhaspelt sich wahrscheinlich der µC immer mal wieder.
Es kommt also zB. 10 mal ein Impuls mit der richtigen Länge und dann ein
(oder mehrere) Impuls(e) mit einer anderen Länge.
Falls Du keine Fensteuerung zur Hand hast um den Servo aus zu probieren,
dann bau Dir einfach mit einem NE555 einen Servotester. (Googel:
"Servotester ne555").
Als Modellbauer musste ich leider feststellen, dass immer öfter auch
schon fabrikneue Servos defekt sind (Made in China!?).
MfG
Ulli B.
Hallo
Ich habe leider keinen NE555 zur Hand :-(
Ich habe die Schaltung 3 Servos getestet. Einer davon ist fabrikneu und
alle zeigen das selbe Verhalten.
Wenn ich mir den Zeitverlauf des LA anschaue kann ich auch keine
unregelmäßigen Impulse erkennen. Die Pulse sind wirklich seeehr, seeehr
exakt.
Habe die einfachen Beispiele gerade mal in C und Assembler getestet, mit
einem Atmega88, mit externem 16MHz Quarz auf dem Pollin-Evaluationboard.
Ich habe das mit zwei Servos probiert, einem Miniservo aus einem
Esky-Lama-V3-Helikopter und einem uralten "Modelcraft-S22"-Servo, der
ohnehin eine leichte Neigung zum Zittern hat.
Funktioniert bei beiden Servos sozusagen problemlos: Schnelles Anfahren
der Position, leichtes Überschwingen, dann Stillstand ohne Zittern und
präzises Halten der Position bei Gegenkraft.
Wie siehts bei dir eigentlich mit Prozessortyp, externem Quarz,
Stromversorgung und Entwicklungsboard aus?
Hallo,
meinst du, du hast MEINEN Code getestet der deinen eigenen?
Ich habe grade keinen passenden Quarz da, beim nächsten Einkauf werde
ich das mal ändern.
Mein Entwicklungskit ist hier nur eine einfache Platine mit ATmega8 mit
ein paar Steckkontakten. Die Platine nutze ich wegen ihrer Einfachheit
schon seit Jahren erfolgreich.
Habe als Spannungsversorgung ein regelbares Labornetzteil. Max. Strom
bis 2,5A. Daran sollte es auch nicht scheitern...
Hallo Budd
Dieses Phänomen, welches du beschreibst kann ich bei mir auch
beobachten.
Ich bin aber auch noch auf keine Lösung gekommen.
Das komische dabei ist, programmiere ich die PWM in Software und nutze
nicht die Hardware generierte, dann funktioniert es ! Ohne jegliches
zittern.
Das ganze getestet auf nem STK500 und den Servo direkt am Port.
Budd wrote:
> Hallo,>> meinst du, du hast MEINEN Code getestet der deinen eigenen?
Den Code der unter meinem Beitrag steht, natürlich. Im Avrstudio muss
ich in C die Taktfrequenz "F_CPU" angeben und in Assembler das
Controller Include-File "m88def.inc", sonst gehts halt nicht, also nur
Copy&Paste von deinem Beispiel hätte sowieso nicht funktioniert.
>> Ich habe grade keinen passenden Quarz da, beim nächsten Einkauf werde> ich das mal ändern.
Den eingebauten Oszillator der AVRs habe ich noch nicht getestet, der
soll ja teilweise recht ungenau sein, wobei ich nicht weiß ob sich das
nur auf die absolute Frequenz bezieht oder auch auf die
Frequenzstabilität innerhalb eines bestimmten Zeitraums,
(Temperaturdrift, Spannungsabhängigkeit etc.). Du kannst ja einfach mal
mit dem LA die Oszillator-Frequenz deines AVR-Oszillators messen und
dann bei "F_CPU" angeben, aber es erscheint mir sinnvoller, erstmal
einen externen Quarz zu beschaffen.
>> Mein Entwicklungskit ist hier nur eine einfache Platine mit ATmega8 mit> ein paar Steckkontakten. Die Platine nutze ich wegen ihrer Einfachheit> schon seit Jahren erfolgreich.>> Habe als Spannungsversorgung ein regelbares Labornetzteil. Max. Strom> bis 2,5A. Daran sollte es auch nicht scheitern...
Also wenn meine beiden Beispiele bei dir problemlos funktionieren liegts
wohl weder am Board noch an der Stromversorgung.
Der nächste Schritt wäre dann, das Ganze, (immer noch mit einer normalen
Delayschleife für die Pulsbreite), in eine 18ms bis 20ms
Interruptroutine zu verpacken, denn so statisch bringt das ja alles
nichts und erst wenn das ebenfalls problemlos funktioniert, würde ich
mich an eine Lösung mit den ganzen Spezialfunktionen der AVR-Timer,
(OCRxx, PWM, etc.), wagen.
Die AVR-Timer bieten ja sehr trickreiche Möglichkeiten an, (soweit ich
das bisher gelesen habe), aber man muss wohl auch verdammt aufpassen,
dass man nichts übersieht, so einfach wie beim 8051 ist das auf jeden
Fall nicht, also z.B. dieser Prescaler, der läuft ja die ganze Zeit und
wenn man einen Timer auf einen bestimmten Wert setzt kann man erst mal
gar nicht sagen wann der erste Zählerimpuls vom Prescaler nun
tatsächlich kommt, es sei denn, man resetet den Prescaler vorher, dabei
ist aber zu beachten, dass sich zwei Timer denselben Prescaler teilen
usw. u.s.f., bei den 8051-Derivaten hatte man halt einfach drei
16-Bit-Timer, die man unabhängig voneinander starten konnte und gut
wars.
Nachtrag:
Zumindest weiß man ja, dass das alles irgendwie funktionieren muss, (und
schon funktioniert hat), hier im Forum als auch bei AVRFreaks gibts ja
genügend Codebeispiele bei denen ein AVR bis zu 20 Servos steuert sowohl
in C als auch in ASM. Es geht ja nur noch darum das alles zu verstehen
und seine eigene Lösung zu entwickeln und das ist es doch, was letztlich
auch den ganzen Spass an der Sache ausmacht :-)
Danke für deinen Post :-)
Ja du hast schon recht, aber der Spaß geht irgendwann auch flöten, wenn
man einfach jedes Detail schon 5x überprüft hat und doch nichts geht...
Ich mach jetzt die Radikallösung. Ich nehm Board samt Servo mit in meine
FH und werd das dort mit Oszi und ggf. Funktionsgenerator zerpflügen.
Mein Verdacht liegt langsam in der Flankensteilheit. Zwar zeigt mir mein
LA tolle Periodenzeiten an, aber wenn die Flankensteilheit "fürn Arsch"
ist, dann bringen die auch nicht mehr viel.
Naja ich werd dem morgen mal auf den Grund gehen und die Ergebnisse hier
posten.
Hat denn jemand von euch vielleicht einen Code für die Servoansteuerung
der bei euch sicher funktioniert und den ich möglichst wenig abändern
muss? So quasi als Referenztest mal.
Servoimpulse sind aus Sicht des Controllers so schnarchlangsam, dass man
sie ohne Weiteres in Software machen kann. Hier ein Beispiel in ASM, es
läuft mit internem Takt von 1 MHz:
http://www.hanneslux.de/avr/mobau/7ksend/7ksend02.html
...