Hallo ich würde gerne n bißchen Kritik an meinenm Programm und evtl.
Hilfestellung von euch bekommen.
Ich möchte über ein poti einen Servo ansteuern und habe das jetz erstmal
wie folgt gelöst oder versucht bin absoluter Anfänger also seid bitte
nicht zu hart :-)
Ist das so richtig und stimmen meine berechnungen ?
Vielen Dank !
Du machst den klassischen Anfängerfehler aller Servoansteuerer.
Du klebst an den 20ms.
Dadurch ergeben sich für die Servo-PWM bei dir nur noch 9 mögliche
Servopositionen, weil du nur 9 gültige Werte für die PWM hast.
Vergiss die 20ms! Sieh zu, dass du den Einstellbereich der PWM für die 1
bis 2ms vernünftig ausnutzen kannst. Und was dann noch übrig bleibt -
das Servo ist damit zufrieden.
Wenn du es so hindrehen kannst dass zb du die 1 bis 2 ms mit 64 Werten
abbilden kannst, dann kannst du den ADC Wert in den OCR Wert umrechnen
und bist nicht mehr auf lediglich 3 Servowerte fixiert. Dein Servo
bewegt sich dann einigermassen flüssig mit dem Poti mit anstelle bei nur
3 Servopositionen 'einzurasten'.
Modellbauservo Ansteuerung
Karl heinz Buchegger schrieb:> Vergiss die 20ms! Sieh zu, dass du den Einstellbereich der PWM für die 1> bis 2ms vernünftig ausnutzen kannst. Und was dann noch übrig bleibt -> das Servo ist damit zufrieden.
Leider ist das in der Allgemeinheit nicht richtig. Die meisten Servos
mögen keine Pausenzeit unter ca.15ms. Selbst bei den neuen
Fernsteuerungen, die mit sehr geringer Pausenzeit < 10ms arbeiten, kann
man auf 20ms umstellen, damit alte Servos verwendet werden können.
Ich habe mit meinen Weichenantrieben ca. 50 Servotypen getestet, und nur
ganz wenige konnten Pausenzeiten <10ms.
Eigentlich doch kein Problem: Man nehme 2 Timer, einen 16-Bit-Timer mit
PWM und einen anderen 8-Bit-Timer für die Wiederholung. Das PWM wird auf
rund 1ms bis rund 2ms limitiert (mit einer Auflösung von mindestens
8Bit) und im Compare-Interrupt wird der PWM-Timer dann abgeschaltet und
der Wiederholtimer gestartet. Dieser läuft mit einem Overflow oder
Compare auf 20ms. Ist der 2. Timer abgelaufen, wird in dessen Interrupt
der 2. Timer gestoppt und der PWM-Timer wieder angestossen. Somit hat
man eine komplett in Hardware laufende Ausgabe und muss lediglich noch
die OCR-Register für das PWM updaten. Wenn man 2 oder mehr PWM-Ausgänge
an dem 16-Bit-Timer hat, kann man die entsprechende Zahl an Servos fast
komplett in Hardware steuern. Die CPU kann dann andere Peripherie (ADC,
UART) bedienen oder Werte auf Display oder PC ausgeben.
Wenn man einen 16-Bit-Timer hat, lässt man den mit ca. 20ms Zyklus
laufen. In meinen Weichenatrieben habe ich den Timer einfach bis 20000
zählen lassen. Mit den Compare-Registern hat man dann eine PWM mit 1µs
Auflösung. Das sind dann, bezogen auf den Impuls, 0,1%. Diese Auflösung
wird von keinem servo erreicht, und der Totbereich eines Servos liegt
typisch bei >2µs.
In einem ATMega8 kann man dann ohne jeden Interrupt o.ä. 2 Servos
steuern. Die Software setzt einfach nur die Compare-Register.
Erstmal vielen Dank
dann muss ich mich mal noch dahintersetzen,
momentan habe ich allerdings nur einen Attiny13 der hat nur 8bit Timer ?
ist es mit dem 13er überhaupt möglich Servos vernünftig anzusteuern oder
kann ich das mit dem eher vergessen ?
Es geht auch mit 8-Bit Timern.
Allerdings darfst du dann nicht mehr auf Hardware PWM setzen, sondern
musst dem Teil mit einer ISR etwas unter die Arme greifen und die Pins
in Software ansteuern.
Aber ansonsten ist das kein Problem. Ich steuere mit einem 8-Bit Timer
12 Servos (allerdings nicht mit einem Tiny, der hätte nicht genug Pins).
Ich hab mal ein wenig gerechnet.
Mit den 9.6Mhz geht sichs nicht besonders gut aus.
4.8Mhz wären besser
Bei 4.8Mhz Taktfrequenz und einem Vorteiler von 64 hast du eine
Durchlauffrequenz des Timers von 0 bis 256 mit 292.9 Hz
Das sind 3.4 ms
Das heisst um Zeiten zwischen 1 und 2 ms einzustellen, bewegt sich der
Comparewert zwischen 75 und 150. Das wären dann immerhin 75 Positionen,
die das Servo anfahren kann. Sollte eigentlich reichen.
Meine Strategie wäre deshalb:
Ich klemm mich an den Overflow Interrupt
Ich zähle die Aufrufe der ISR mit. Bei jedem 5.ten Aufruf mache ich:
Den Servo-Pin auf 1 schalten
Ins Compare Register den Vergleichswert für die Zeit laden
Sicherheitshalber das Interrupt Flag für den Compare Interrupt
löschen
Den Compare Interrupt einschalten
Im Compare Interrupt
Den Pin wieder auf 0 setzen
den Compare Interrupt ausschalten.
Dadurch ergibt sich automatisch ein Timing, dass einen Puls mit der
gewünschten Länge erzeugt und eine Pause hinten nach, die sich im
Bereich von ca 17ms bewegt. Und damit sollte jedes Servo zufrieden sein.
Der Trick besteht darin, dass der Pulsanfang vom Overflow Interrupt
erzeugt wird und das Pulsende vom Compare Interrupt. Der Overflow
Interrupt richtet gleichzeitig auch alles so ein, dass der Compare
Interrupt zum gewünschten Zeitpunkt nach dem Pulsanfang aufgerufen wird.
also software PWM wie im Beispiel:
http://www.mikrocontroller.net/articles/AVR-Tutorial:_PWM
mit den verschiedenen Helligkeitswerten, nur anstatt den Werten für
versch. Helligkeit, setze ich dafür meine verschiedenen positionen des
Servos verstehe ich das so richtig ?
und wie im Beispiel der PWMcount ist dann meine (20 oder 10ms) Pause ?
Man könnte auch (etwas einfacher), nur mit dem Compare Match (dem OCR0A
Register) arbeiten, indem man den CTC Modus benutzt.
Den stellt man so ein, dass der CTC die gewünschte Pulszeit ergibt.
Zusätzlich benötigt man noch einen Softwarezähler, der die Anzahl der
ISR Aufrufe mitzählt.
Ist der zähler auf 0, so wird der Ausgangspin auf 1 gesetzt
Ist er auf 1, so wird der Pin wieder abgeschaltet
Hat der Zähler 10 erreicht, so wird der Zähler wieder auf 0 zurück
gesetzt.
Auch das ergibt ein Timing, mit dem ein Servo etwas anfangen kann.
Mit dem ATTiny geht es sicher auch, bei meiner PIC-Version hatte ich
auch nur einen 8-Bit-Timer. Wenn der Prozessor nichts anderes zu tun
hat, kann man das per Software machen. Wenn allerdings, wie bei meinen
Weichenantrieben, alle 50µs noch ein Interrupt kommt, kann man alle
Softwarelösungen vergessen, denn ein Jitter von > 4µs bringt das Servo
zum Brummen oder sogar Zappeln. Wenn Du es also einfach und sicher haben
willst, nimm so etwas wie den ATMega8 und mache es in Hardware.
Michi K------ schrieb:> also software PWM wie im Beispiel:> http://www.mikrocontroller.net/articles/AVR-Tutorial:_PWM>> mit den verschiedenen Helligkeitswerten, nur anstatt den Werten für> versch. Helligkeit, setze ich dafür meine verschiedenen positionen des> Servos verstehe ich das so richtig ?
Nicht ganz.
> und wie im Beispiel der PWMcount ist dann meine (20 oder 10ms) Pause ?
Nicht wirklich.
Das Prinzip ist ähnlich, aber doch ganz anders.
Kurt Harders schrieb:> Jitter von > 4µs
das bedeutet bei 4.8Mhz eine Verzögerung von 20 Takten.
Die hat er nie (wenn die Anwendung so bleibt, wie sie sich im Moment
abzeichnet)
Wichtig ist nur, dass man die Servo-Pins direkt nach dem Einsprung in
die ISR beeinflusst und bedingte Sprünge, die zwischendrin unbedingt
sein müssen, mit "NOP" Instruktionen ausgleicht, so dass sich immer
gleiche Codelaufzeiten ergeben, wenn das Timing kritisch ist. Einen
Interrupt-Jitter von 0...3 Takten hat man ohnehin immer.
Knut Ballhause schrieb:> Wichtig ist nur, dass man die Servo-Pins direkt nach dem Einsprung in> die ISR beeinflusst und bedingte Sprünge, die zwischendrin unbedingt> sein müssen, mit "NOP" Instruktionen ausgleicht, so dass sich immer> gleiche Codelaufzeiten ergeben, wenn das Timing kritisch ist. Einen> Interrupt-Jitter von 0...3 Takten hat man ohnehin immer.
Hattest du bei deiner Lösung damit Probleme?
Meine Erfahrung ist eher: die Unterschiede sind so minimal, das lohnt
nicht, sich da groß den Kopf zu zerbrechen. Ob ein Puls mal 1/10 µs
länger oder kürzer ausfällt, lässt das Servo völlig kalt. So genau sind
die Potis (als mechanisches Bauteil) in den Servos gar nicht.
Du hast recht, aber es sind nicht die Potis, sondern die eingebauten
Elektroniken haben ca. 4µs Totzeit. Bei Digitalservos kann man diese
Totzeit einstellen, bekommt dann aber eventuell massives Brummen des
Servos mit sehr hoher Stromaufnahme.
Ich hab mich mal an den Assebmler geklemmt
benutzt hab ich die Variante: Alles im Compare Interrupt mit CTC.
Leider hab ich keinen Tiny13 da, sondern nur einen Mega16.
Daher kann ich den auch nicht mit 4.8Mhz laufen lassen, sondern nur mit
4Mhz :-)
Die Timer Einstellung sollte aber sonst identisch sein. Vorteiler: 64
Das Servo wird verstellt, indem man an OCR0 neue Werte zuweist. Bei dir
müssten das rein rechnerisch Werte zwischen 75 und 150 sein. Die im
Programm momentan verwendeten 100, sind bei mir in etwa Mittelstellung
meiner Servos, aber ich hab ja auch 4Mhz und nicht 4.8
Ach ja, ich erzeuge an PortA, Pin 7 das Signal. Hat keine besonderen
Gründe, ausser dass ich da leicht mit dem Servokabel rankomme.
Da der Wertebereich damit so ca 75 Werte umfasst, würde es sich
anbieten, den Wert vom ADC (den du ja mittels ADLAR schon auf 0..255
eingeschränklt hast) noch durch 4 zu dividieren (einfach um 2 Bit nach
rechts schieben), noch 75 dazuzählen und ab damit ins OCR Register. Das
ergibt dann 64 Servo Stellungen, die mit dem Poti abgefahren werden
können.
Karl heinz Buchegger schrieb:> Da der Wertebereich damit so ca 75 Werte umfasst
Bei 75 Schritten auf 90° Drehwinkel sind das 1,2° pro Schritt. Das ist
sehr grob. Eine Auflösung von 512 Schritten sollte es für
anspruchsvollere Bewegungen schon sein. Die Totzeit macht es schon
schwer genug, langsame Bewegungen umzusetzen.
Kurt Harders schrieb:> Karl heinz Buchegger schrieb:>> Da der Wertebereich damit so ca 75 Werte umfasst>> Bei 75 Schritten auf 90° Drehwinkel sind das 1,2° pro Schritt. Das ist> sehr grob.
Zugegeben. Ich seh bei meinen Servos deutlich den Schritt (auch wenn es
dann in Natura weit weniger dramatisch aussieht als es sich hier anhört)
Allerdings ist es mit den vorhandenen Mitteln nicht mehr so einfach,
diese Auflösung zu erreichen.
Machbar ist es, keine Frage.
Aber lass den Fragesteller erst mal mit Timern und den Möglichkeiten
vertraut werden und wie man mit ISR und Softwarezählern längere
Zeiträume bei gleichzeitig hoher zeitlicher Auflösung abzählt.
Gegenüber seinen ursprünglich 9 Servostellungen sind 75 schon recht viel
:-)
Karl heinz Buchegger schrieb:> Knut Ballhause schrieb:>> Wichtig ist nur, dass man die Servo-Pins direkt nach dem Einsprung in>> die ISR beeinflusst und bedingte Sprünge, die zwischendrin unbedingt>> sein müssen, mit "NOP" Instruktionen ausgleicht, so dass sich immer>> gleiche Codelaufzeiten ergeben, wenn das Timing kritisch ist. Einen>> Interrupt-Jitter von 0...3 Takten hat man ohnehin immer.>> Hattest du bei deiner Lösung damit Probleme?> Meine Erfahrung ist eher: die Unterschiede sind so minimal, das lohnt> nicht, sich da groß den Kopf zu zerbrechen. Ob ein Puls mal 1/10 µs> länger oder kürzer ausfällt, lässt das Servo völlig kalt. So genau sind> die Potis (als mechanisches Bauteil) in den Servos gar nicht.
Jitter kann sich im ungünstigsten Fall addieren. Bei einem mit
4Mhz-Controller kann der Jitter dann im Bereich von 2µs liegen, bei
einer Software-Pin-Ansteuerung über Interrupt-Service. Ausserdem darf in
dem Fall nur ein einziger Interrupt zu einer Zeit erlaubt sein, da sonst
der Interrupt mit dem PWM auf einen anderen warten muss. Hier kann der
Jitter dann so groß werden, dass das ganze Signal zusammenbricht. Bei
einer Hardware-Steuerung des PWM über einen Timer und dessen
OCR-Register ist der Jitter der steigenden PWM-Flanke praktisch "Null"
und da das OCR mit dem Timerumlauf übernommen wird, gilt dies auch für
die fallende Flanke. Am Oszi steht solch ein Signal wie eine 1 ;-).
Software-PWM für Servos macht also nur auf einem Controller Sinn, der
recht schnell getaktet ist und wo das Addieren von
Interrupt-Reaktionszeit plus Portausgabe dann nicht mehr in´s Gewicht
fällt.
Vielen vielen Dank für die Antworten ich muss jetz wenn ich wieder ein
bißchen Zeit habe mich nochmal dransetzen und mir alles genau durchlesen
und dann kommen bestimmt noch viele Fragen :-) wünsche jetz aber erst
mal nen guten Rutsch !