Hallo zusammen,
ich baue einen I2C-gesteuerten Servocontroller mit einem tiny2313.
Um die PWM mit dem µC zu erzeugen, benutze ich Timer1 mit Prescaler 8
(F_CPU=8MHz).
OCR1B=5000 um alle 5ms die Pegel für die Servos auf High zu setzen (sind
Digitalservos, die können die 200Hz)
OCR1A = 800-2200 um die Leitung nach dem Impuls wieder auf Low zu legen,
aber:
weil ich mehr als ein Servo steuern will, und zwar mit einem Timer,
sortiere ich die Servoimpulse von kurz nach lang und stelle bei jedem
Interrupt für OCR1A den nächst größeren Wert ein.
Beispiel:
Servo 1: 1500, Servo 2: 1000, Servo 3: 1600
...
mit OCR1B-Interrupt wird alles auf High gezogen,
1000µs später: OCR1A-Interrupt -> Servo2-Line low, OCR1A auf 1500
stellen
500µs später: OCR1A-Interrupt -> Servo1-Line low, OCR1A auf 1600 stellen
100µs später: OCR1A-Interrupt -> Servo1-Line low, OCR1A auf 1000 stellen
...
(und wieder von vorne)
Soweit funktioniert das ganz gut. Die Servostellungen sollen natürlich
verändert werden können. Ich hab sie also in ein Array gepackt und das
der größe nach sortiert. Eine Index-Variable speichert, welcher
servo-wert gerade eingestellt wurde und wird bei jedem OCR1A-Interrupt
hochgezählt. In der ISR wird dann überprüft, zu welchem servo-Wert das
aktuelle OCR1A passt und die entsprechende Datenleitung geschaltet.
Aber jetzt das Problem: ich habe das gefühl, dass der Zugriff auf das
volatile uint16_t Array so langsam ist, dass die ISR verzögert wird.
Denn das Servo "rauscht" in seiner Position sehr stark! Das zittert sehr
munter in einem Bereich von umgerechnet so um die 500 µs.
Wenn ich statt ein Array zu benutzen, einfach die Servowerte unsortiert
der Reihe nach einstelle (OCR1A==Servowert1, also muss jetzt Servowert2
eingestellt werden, usw.), funktioniert das ansich ohne Probleme.
Nachteil: die reaktionszeit des Systems ver-n-facht sich mit der Anzahl
der Servos, weil das volle 5ms-Fenster für jeden Servo durchlaufen wird.
Meine Frage ist jetzt: Was mache ich falsch, dass der Zugriff auf das
Array so lange dauert? Oder habe ich ein anderes Problem übersehen?
Ich hoffe, ihr könnt mir helfen!
Gruß
peka
Hallo peka,
mit Deiner Methode kriegst Du aber arge Probleme, sobald zwei
Servopositionen sehr dicht beieinander sind. Beispielsweise hat ein
Servo 1500, das andere 1505. Dann stellst Du im 1500er Interrupt den OCR
auf 1505, der Timer ist dann aber möglicherweise schon viel weiter. Das
Ergebnis wäre ein 5500ms-Puls am zweiten Servo.
Peter
Hallo Peter,
da hast Du recht.
Auch wenn zweimal der selbe Wert vorhanden ist, gibts eine 5ms pause...
Ich hatte angenommen, dass die paar befehle nicht so lange brauchen. Das
wäre natürlich nur der Fall, wenn weniger als 8 Taktzyklen benötigt
werden (Timer-Prescaler 8). Aber das schaff ich wohl nicht.
Es gab hier mal einen genialen Ansatz mit einem Schieberegister.
Das Schieberegister kann intern oder extern in HW realisiert sein.
Die Such' macht klug.
Mehrere Servos macht man anders.
Jedes Servo kriegt seine Pause nach dem Puls, während gerade ein Puls
für ein anderes Servo abläuft. D.h. du brauchst nicht einen kompletten
Pulszyklus inklusive Pause danach abwarten, ehe du mit dem Puls für das
nächste Servo beginnst.
Also nicht
| |
| Servozyklus|
| Puls + Pause
| |
+---+ +---
| | |
Servo 1 --+ +-----------------------+
+---+
| |
Servo 2 ---------------+ +-----------
Sondern
+---+ +---+
| | | |
Servo 1 ---+ +-------+ +-----
+---+ +---+
| | | |
Servo 2 -------+ +-------+ +--
+---+ +---
| | |
Servo 3 -----------+ +-------+
D.h. du generierst aktiv gar keine Pausen. Die Pausen nach dem Puls
ergeben sich dadurch, dass in dieser Zeit die Pulse für die anderen
Servos erzeugt werden.
Modellbauservo Ansteurung
ganz unten, der letzte Abschnitt
Aha, das mit dem Schieberegister klingt sehr gut, danke für den Tipp!
Dass man die Servos nacheinander ansteuert ist natürlich ein Nachteil,
außer man benutzt mehrere Schieberegister parallel, muss ich mir mal
ansehen.
Von den 74HC164 hab ich auch noch einige da :)
Hallo Peka,
weder du noch Peter haben Recht.
Gerade bei digitalen Servos ist es ein Vorteil, wenn die Ansteuerung
gleichzeitig erfolgt. Streng genommen sollte die fallende Flanke genau
gleichzeitig sein, damit alle Servos 100% parallel laufen. Die guten
Empfänger können genau das.
Mit dem tiny müsste es auch gehen.
1. Du sortierst alle Werte
2. du fasst alle gleichen zusammen
3. du berechnest den Abstand der verbliebenen
3. wenn der Abstand zwischen den verbliebenen Impulsen zu klein ist um
den Interrupt zu verlassen und wieder einzutreten, verlässt du den
Interrupt nicht und machst mit NOPs die Verzögerung.
Falls Interesse besteht, kann ich den Code für einen ATMEGA beisteuern.
(Auflösung 1µs, Jitter < 0,5µs, möglich müssten sogar 16 Kanäle
gleichzeitig sein, bei mir sind es 2 * 4)
Gruß
Josef
Josef schrieb:> Gerade bei digitalen Servos ist es ein Vorteil, wenn die Ansteuerung> gleichzeitig erfolgt. Streng genommen sollte die fallende Flanke genau> gleichzeitig sein, damit alle Servos 100% parallel laufen. Die guten> Empfänger können genau das.
Wow.
Du kannst das erkennen, wenn ein Servo ein paar Millisekunden später zu
laufen anfängt? Und deine Anlenkungen sind alle absolut und zu 100%
spielfrei? Und deine Gestänge zeigen keinerlei Durchbiegung? Deine
Scharniere haben 0 Spiel in den Lagern? Deine Gabelköpfe sind sowohl
leichtgängig als auch spielfrei, genauso wie deine Kugelköpfe. Und
natürlich sind alle Ruderhörner bis auf den 10-tausendstel Millimeter
gleich lang und sitzen mit derselben Präzision von der Drehachse gleich
weit entfernt.
Respekt!
Also ich benutze den Code aus dem Artikel für 12 Servos und ich kann mit
freiem Auge absolut nicht erkennen, dass ein Servo etwas später zu
laufen anfangen würde. Scheint so, als ob das für meinen Hexabot nicht
wirklich wichtig wäre.
Nur damit wir uns richtig verstehen: Ich sag nicht, dass schlampig
arbeiten in Ordnung ist. Aber man muss auch wissen, ab wann noch mehr
Genauigkeit nur noch Mehraufwand bedeutet und in der Praxis einfach
nichts mehr bringt.
Natürlich kann ich das nicht erkennen, aber ich kann es messen. Und ob
es Sinn in der Praxis macht, muss jeder selbst entscheiden. Es gibt
genug Leute die genau deshalb manche Fernsteuerung bevorzugen. Genauso
wenig wie grundsätzlich digitale Servos besser sind. Es geht wie immer
um Aufwand und Nutzen.
Aber es ist technisch möglich gleichzeitig die Signale auszugeben und
genau darum geht es in diesem Fred