PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Servos per Hardware PWM ansprechen



MiniMax
29.03.2012, 19:43
Moin Zusammen,
es geht "einfach" nur um die Ansteuerung von 6 Servos mit nem Mega48.
Nun habe ich es bisher immer mit der Timer und Schleifen Methode gemacht. Da ich aber für mein aktuelles Projekt Zeit zum Rechnen brauche ohne Interrupts wollte ich das über die 6 Hardware PWM's machen. Nun finde ich über die Hardware Methode mit den Timern kaum was im I-Net (zumindest mit meinen Suchbegriffen wie "Hardware Servo PWM" usw.)
Daher wollte ich euch fragen ob ihr mir da nen bissel auf die Sprünge helfen könnt.
Freue mich auf eure Antworten :D

Torrentula
29.03.2012, 20:42
Per Hardware ist das eigentlich noch einfacher, weil du dich nur ein mal um die Konfiguration kümmern musst und dann einfach immer den Compare-Wert verändern musst.

Du musst eben die Timer so konfigurieren, dass du eine PWM-Frequenz von 50Hz bekommst (bei analogen Servos) und dann die Compare-Werte für die Pulsbreite berechnen / durch ausprobieren feststellen.

Ich weiß nicht wie man die Timer in Bascom konfiguriert aber hier ist die grundlegende Vorgehensweise ganz gut erklärt:

*Click (https://www.roboternetz.de/community/threads/55285-Servo-ansteuerung-durch-pwm?p=528562&viewfull=1#post528562)*

Besserwessi
29.03.2012, 21:33
So wirklich einfach geht die Erzeugung des PWM Signals per Hardware PWM leider nur mit dem 16 Bit Timer. Nach der Konfiguration des Timers auf etwa 50 Hz und PWM Mode muss man nur noch den Wert in das OC1... Register schreiben. Beim Mega48 hat man aber nur 2 PWM Kanäle mit 16 Bit Auflösung. Mit den 8 Bit Timern geht das leider nicht so gut. Da ist die Auflösung doch sehr eingeschränkt: um auf etwa 20 ms Period zu kommen entspricht ein Schritt für den Timer und die Auflösung für den PWM Puls dann etwa 50-100 µs. Bei einer Pulsbreite von 1,5-2,5 ms für den Servo sind das also nur 10-20 Stufen die man einstellen kann. Teils ist der Bereich sogar noch kleiner.

Wenn man die Softwareversion richtig macht, also die Pulse nach einander, und mit nur je 1 Interrupt je Puls, hält sich die Belastung durch Interrupts in Grenzen und man hat noch den größten Teil der Rechenleistung zur Verfügung. Da stört mehr der zusätzliche Bedarf auf dem Stack.

Torrentula
30.03.2012, 09:45
Wenn man die Softwareversion richtig macht, also die Pulse nach einander, und mit nur je 1 Interrupt je Puls, hält sich die Belastung durch Interrupts in Grenzen und man hat noch den größten Teil der Rechenleistung zur Verfügung. Da stört mehr der zusätzliche Bedarf auf dem Stack.

Gibt es dazu auch ein Beispiel? Du hast mich jetzt auch neugierig gemacht :)

Besserwessi
30.03.2012, 11:58
Passenden Code gibt es im RN-wissen unter Servoansteuerung.

MiniMax
30.03.2012, 18:50
Also haltet ihr die Hardwaremethode nicht vorteilhaft? Dann mache ich es einfach so wie immer? :


Servoirq:
If Kanal = 0 Then
If Portb.0 = 0 Then 'wenn port low
Timer1 = Servo(1) 'dann timer auf entsprechende verzögerung
Portb.0 = 1 'und port anschalten
Else 'das hier passiert erst bei dem darauf folgenden interrupt
Portb.0 = 0 'dann port wieder ausschalten
Incr Kanal 'und den nächsten kanal bearbeiten
End If
End If
[...]
If Kanal = 6 Then
Timer1 = 40000 'eine pause von ca. 12ms bis zum nächsten interrupt. Bei guten Servos oder Brushlessreglern kann man hier bis auf 65530 gehen ==> ansteuerfrequenz von ~ 200Hz
Kanal = 0
End If
Return

Besserwessi
30.03.2012, 19:34
Wenn man mit der Ansteuerfrequenz höher gehen kann, wie im Kommentar oben im Code angedeutet, kann man ggf. auch mit 8 Bit PWM noch brauchbare Ergebnisse (z.B. 40 Stufen) bekommen.

Bei dem Basic Code hätte man dann zur Not noch die Möglichkeit für die Servos inline ASM zu nutzen - das bringt gegenüber BASCOM schon ein merkliche Beschleunigung und weniger Speicherbedarf (Interrupts sind nicht gerade die Stärke des BASCOM Compilers). Hat man für die Servos einen ganzen Port reserviert, kann man auch den Basic-Code noch kürzer machen (array Zugriff statt der if then else Konstruktion) .

MiniMax
30.03.2012, 22:42
Mhmm Ok also fasse ich zusammen:
1. Servoansteuerung wie gehabt mit 16 bit Timer & Interrupts
2. Bei mehr Geschwindigkeitsbedarf ASM inline nehmen

Ich werde das dann erstmal aufs Board bringen und dann Testen ob und in wie weit mir der Interrupt dazwischen funkt.

Vielen Dank an euch alle

Besserwessi
31.03.2012, 12:55
Bei der Softwarelösung braucht man nicht unbedingt einen 16 Bit timer, das geht auch mit einem 8 Bit Timer nicht so viel schlechter. Mehr als etwa 50-100 Schritte könnte die meisten Servos mechanisch nicht Auflösen, und dafür reicht auch ein 8 Bit Timer, denn hier muss der Timer nur die Pulslänge auflösen, nicht die ganze Periode - für die Wartezeit am Ende kann man wenn nötig den Vorteiler umstellen.