hallo, wenn ich einen Servo mehrere Male in einem Programmcode bewegen möchte, wie funktioniert das. Brauch ich da irgendein Timer oder Interrupt oder was ganz anderes? Gruß JB
ein servo wird eh sehr oft pro sekunde mit "daten" versorgt, du änderst dann nur die werte und schon macht er etwas.
Das Servo erwartet einen Positiven Impuls zwischen 1 und 2 ms. Bei 1,5 ms läuft es in die Mitte, mit 1 ms nach links und mit 2 ms nach rechts. Der Impuls muss sich alle ca. 20ms wiederholen. Es sind keine exakten 20 ms Wartezeit notwendig, es geht auch mit 15 oder 22 ms.
Wie programmiere ich ein servo der sich z.b. einmal nach links und dann nach rechts dreht. Ich weiß nur wie er sich in einer Richtung dreht, und dann muss ich wieder den Code ändern, damit sich in die andere Richtung dreht.
jb schrieb: > Wie programmiere ich ein servo Das kommt darauf an, was der Mikrocontroller sonst noch tun muss. > der sich z.b. einmal nach links und dann > nach rechts dreht. Ich weiß nur wie er sich in einer Richtung dreht, und > dann muss ich wieder den Code ändern, damit sich in die andere Richtung > dreht. Du brauchst als erstes zwei Zeitgeber, einer startet alle 20 ms einen Servoimpuls. Der zweite Zeitgeber nimmt diesen Impuls 1 bis 2 ms nach dem Start wieder weg, die genaue Zeit bestimmt die Servoposition, wobei 1,5 ms die Mitte ist. Dies brauchst Du ständig, also auch dann, wenn Dein Servo nicht bewegt werden soll. Um den Servo zu bewegen, musst Du den Wert der Impulsdauer verändern. Wie Du siehst, müssen (mindestens) zwei Dinge parallel nebenher laufen: Impulserzeugung und Bewegungsablauf. Meist muss der Mikrocontroller aber noch weitere Dinge nebenher erledigen, wie das Bedienen von Schnittstellen zum Übertragen von Sollwerten. Oder aber das Erfassen von Messwerten aus der Umgebung und Errechnen der daraus zu erfolgenden Servobewegungen. All das bringt einem zu dem Schluss, dass man Servoimpulse nur mit einem Timer-Interrupt vernünftig generieren kann, damit das Hauptprogramm genügend Freiheit hat, sich um den Rest der Aufgaben zu kümmern. ...
Hannes Lux schrieb: > All das bringt einem zu dem Schluss, dass man Servoimpulse nur mit einem > Timer-Interrupt vernünftig generieren kann Den Interrupt brauchts nicht unbedingt. Ein Hardware Timer kann das auch ohne Interrupt bewerkstelligen.
Du musst einfach in deinem gewünschten Bewegungszeitraum die "Ein-Zeit" variieren. Wenn du also bei 1ms anfängst, musst du als z.B. alle 0,1ms deinen "Zeitwert" um 0,1ms inkrementieren und dann bist du nach 1s anderem Anschlag (2ms). Natürlich ist die Bewegungsauflösung nichtbeliebig hoch, sodass er ggf. etwas ruckelig reagiert. Den Puls gibst du dann alle 20ms aus. Viele Servos kommen auch mit > 100 Hz zurecht. Ob du das jetzt per "_delay_us" oder per Timer-Interrupt machst, hängt vom Anwendungsfall ab. Nach möglichkeit sollte man das ganze per Hardware-PWM machen oder zumindest per Timer-Interrupt und Soft-PWM. Beim Atxmega hast du genug PWM-Kanäle um > 12 Servos per Hardware-PWM zu steuern. Da brauchst du dann nur das entsprechende TCxRyz neu zu schreiben und kannst nebenher andere dinge tun.
Magnus Müller schrieb: > Ein Hardware Timer kann das auch > ohne Interrupt bewerkstelligen. Klar kann ein 16-Bit-Timer das vorzüglich, allerdings wird es dann nix mehr mit mehreren Servos. Stand zwar nicht in der Frage, kommt aber mit Sicherheit nach... Timmo H. schrieb: > Beim Atxmega hast du genug PWM-Kanäle um > 12 Servos per Hardware-PWM zu > steuern. Das ist natürlich ein Argument. Den kann ja auch jeder Bastler aufs Steckbrett oder Lochraster stecken... ...
B e r n d W. schrieb: > Es sind keine exakten 20 ms Wartezeit notwendig, es geht auch mit > 15 oder 22 ms. ... oder 100 ms
Hannes Lux schrieb: > Klar kann ein 16-Bit-Timer das vorzüglich, allerdings wird es dann nix > mehr mit mehreren Servos. Stand zwar nicht in der Frage, kommt aber mit > Sicherheit nach... Na ja, schon in Hardware kann jedes Compare-Register vom Timer einen Servo bedienen, d.h. selbst der alte ATmega8 schafft schon mal zwei mit seinem Timer1.
Hannes Lux schrieb: > Timmo H. schrieb: >> Beim Atxmega hast du genug PWM-Kanäle um > 12 Servos per Hardware-PWM zu >> steuern. > > Das ist natürlich ein Argument. Den kann ja auch jeder Bastler aufs > Steckbrett oder Lochraster stecken... > > ... Jup, darum verwende ich den auch für meinen Quadcopter (der später auch noch Servos für die Kamera bekommt). Da hat man dann genug Rechenzeit für den anderen Kram übrig. Als Xmega Platine fürs Steckbrett gibts auch günstige Lösungen, z.B.: http://www.embedit.de/Mechanische-Bauteile/Platinen/Prototype-Leerplatinen/AVR-Xmega-A4-Modul-Leerplatine.html
An den Kopf faß: Xmega um einen Servo hin und her drehen zu lassen. jb schrieb: > Wie programmiere ich ein servo der sich z.b. einmal nach links und dann > nach rechts dreht. Ich weiß nur wie er sich in einer Richtung dreht, und > dann muss ich wieder den Code ändern, damit sich in die andere Richtung > dreht. Dann zeig doch mal deinen Code.
Hi
>An den Kopf faß: Xmega um einen Servo hin und her drehen zu lassen.
Wann hat jb etwas von einem XMega geschrieben?
MfG Spess
B e r n d W. schrieb: > Das Servo erwartet einen Positiven Impuls zwischen 1 und 2 ms. Bei 1,5 ms läuft es in die Mitte, mit 1 ms nach links und mit 2 ms nach rechts. Das ist aber sehr missverständlich ausgedrückt. Die Pulsbreite ist proportional zur Position des Servokopfes. Bei 1 bzw. 2ms läuft das Servo nicht ständig nach links oder rechts, sondern nimmt die linke oder rechte Maximalposition ein und versucht diese zu halten.
spess53 schrieb: > Wann hat jb etwas von einem XMega geschrieben? Na unter dem fängt man doch heutzutage gar nicht mehr an... :-)) ...
Hi Es geht eher um das Beitrag "MR-C3024 in C progammieren, mit ATmel Studio 6 und AVR Dragon über ISP-Schnittstelle" ein ATMega128 Board. MfG Spess
Timmo H. schrieb: > Jup, darum verwende ich den auch für meinen Quadcopter (der später auch > noch Servos für die Kamera bekommt). Da hat man dann genug Rechenzeit > für den anderen Kram übrig. Hast du auch dann, wenn man die Servopulserzeugung mit ein wenig Hirnschmalz angeht. Ein einzelner Timer mit einer ISR kann locker 12 Servos bedienen, ohne das das mehr als 1% Rechenzeit braucht. Das du noch andere Gründe für einen Atxmega haben wirst, bezweifle ich nicht. Aber jemandem der ein (paar) Servos ein wenig hin und her fahren lassen will, muss man nicht gleich zum µC Wechsel raten.
spess53 hat recht. Es geht um das MR-C3024 Board. In dem sitzt ein µC Atmega128L. Mit dem Board lässt sich ja auch 18 Servos ansteuern, sogar mehr. siehe Link: http://davidbuckley.net/DB/RoboNova/RoboNova_files/C3024-connectors.htm Da muss ich mir doch net extra einen anderen µC besorgen. Ich will erst mal, ein oder zwei servos ansteuern und dann würde ich mich langsam hoch arbeiten. Das ist der Code.
1 | #define F_CPU 7372800UL
|
2 | |
3 | #include <avr/io.h> |
4 | #include <util/delay.h> |
5 | |
6 | |
7 | int main() |
8 | |
9 | DDRA = (1<<PA5); |
10 | |
11 | while( 1 ) { |
12 | |
13 | PORTA |= (1<<PA5); |
14 | _delay_us( 2300 ); |
15 | PORTA &= ~(1<<PA5); |
16 | |
17 | _delay_ms( 18 ); |
18 | }
|
19 | |
20 | |
21 | return 0; |
ich habe den irgendwo kopiert, wo genau weiß ich nicht mehr. habe bisschen rumexperementiert, aber naja. Was genau wird denn jetzt benötigt? gruß jb
jb schrieb: > Das ist der Code. Mit dem Code kommst du aber nicht weiter. Der taugt gerade mal um die Funktionsfähigkeit eines Servos zu demonstrieren. Will man mehrere Servos ansteuern oder etwas komplexere Dinge machen, muss man ein bischen mehr Wissen investieren. Generell kann man eigentlich sagen: In den meisten Programmen kommt man ohne Timer nicht weiter. Timer sind sowas wie die Arbeitspferde in der µC-Programmierung. FAQ: Timer Modellbauservo Ansteuerung
jb schrieb: > ich habe den irgendwo kopiert, wo genau weiß ich nicht mehr. habe > bisschen rumexperementiert, aber naja. Programmieren heute?
Udo Schmitt schrieb: > jb schrieb: >> ich habe den irgendwo kopiert, wo genau weiß ich nicht mehr. habe >> bisschen rumexperementiert, aber naja. > > Programmieren heute? Was programmieren heute? wenn du damit meinst, ob ich heute damit angefangen habe. Nein, sind paar wochen her.
jb schrieb: > Udo Schmitt schrieb: >> jb schrieb: >>> ich habe den irgendwo kopiert, wo genau weiß ich nicht mehr. habe >>> bisschen rumexperementiert, aber naja. >> >> Programmieren heute? > > Was programmieren heute? wenn du damit meinst, ob ich heute damit > angefangen habe. Nein, sind paar wochen her. Nein, so hat er das nicht gemeint...
Lies dir doch mal das was Udo von dir zitiert hat und dann das Kommentar von Udo. Damit ist sicherlich nicht gemeint, dass du heute programmieren sollst oder programmiert hast. Sondern eher "ist das die Art von Programmieren heute?" Sprich, irgendwo stumpf kopieren und dann nicht verstehen was und warum das überhaupt gemacht wurde.
ach so. ist schon klar, dass das nichts bringt wenn man ein Code kopiert. Zum Verständis habe ich das gemacht. Ich gehe so dann jede einzelne Zeile nochmal durch. Ich vestehe es besser so.
Ist es auch möglich ohne irgendwelche Taster, Poti, Schalter etc. einen Servo zu steuern? Er soll z.B. 2 oder mehrere Positionen ansteuern können, also z.B. 30° dann rüber zu 70° und dann wieder zurück zu 20° usw. gruß jb
jb schrieb: > Ist es auch möglich ohne irgendwelche Taster, Poti, Schalter etc. einen > Servo zu steuern? Ja.
also irgendwie vestehe ich das nicht so, mit dem Timer, interrupt. kann man, in dem obrigen Code, nicht noch ein paar delays mehr einfügen und er dreht sich einfach auf mehrere Positionen?
jb schrieb: > Ist es auch möglich ohne irgendwelche Taster, Poti, Schalter etc. einen > Servo zu steuern? Ja. Position des Potis per ADC ablesen und mit dem passend umgerechneten Wert die Pulslänge für den Servo steuern. Wenn man das ganze in einer kleinen Schleife laufen läßt, folgt der Servo immer schön der Potistellung.
µC-Bastler schrieb: > Wenn man das ganze in einer > kleinen Schleife laufen läßt, folgt der Servo immer schön der > Potistellung. Hmmm, er will aber ohne Potis auskommen: jb schrieb: > Ist es auch möglich ohne irgendwelche Taster, Poti, Schalter etc. einen > Servo zu steuern? > Er soll z.B. 2 oder mehrere Positionen ansteuern können, also z.B. 30° > dann rüber zu 70° und dann wieder zurück zu 20° usw. Ja, das geht auch, dann musst Du dem Controller eben auf andere Art und Weise die gewünschten Servopositionen mitteilen. Z.B. über Schnittstellen wie UART, SPI, I2C... Oder Du definierst eine Tabelle mit vordefinierten Positionen, die dann in einer Schleife abgearbeitet werden können. Kernstück für diese Betriebsart ist aber das automatische Erzeugen der Servoimpulse im Hintergrund, also per Timer-Hardware oder Timer-Interrupt. Wenn das erstmal läuft, natürlich ohne rechenzeitvernichtende Wait- oder Delay-Warteschleifen, dann kannst Du mit Schleifen oder besser Statemachines die gewünschten Positionswerte ständig feinstufig verändern und z.B. Laufbewegungen eines Hexapod realisieren. Wenn dabei noch mittels veränderlicher Parameter die Servo-Wege der linken und rechten Seite unterschiedlich gestaltet werden, kann das Ding sogar Kurven laufen. Es gibt viele Möglichkeiten, Servos zu steuern, LEDs blinken zu lassen, Mikrocontroller irgendwas Sinnvolles tun zu lassen, doch es ist immer vorteilhaft, wenn man versteht, was man tut. Und das lernt man nicht, indem man sich unverstandene Codestücke kopiert oder zusammenbettelt, sondern indem man das Problem analysiert, in kleine, überschaubare Aufgaben zerlegt, und diese einzeln realisiert, ohne dabei den Blick auf das Ganze zu verlieren. ...
Hallo, also ich würde PWM nehmen. Das ist relativ einfach und man braucht keinen Interrupt um ein Servo hin und her zu bewegen. Wenn der µC (AVR?) noch andere Sachen erledigen muss dann vllt. doch einen Interrupt. Moritz
Moritz M. schrieb: > Hallo, > > also ich würde PWM nehmen. Das ist relativ einfach und man braucht > keinen Interrupt um ein Servo hin und her zu bewegen. Wenn der µC (AVR?) > noch andere Sachen erledigen muss dann vllt. doch einen Interrupt. Egal wie man es macht. Der springende Punkt ist, dass man ein paar Basistechniken lernen muss. Da führt kein Weg daran vorbei. Wer sich selbst ein Haus bauen will, muss eben auch lernen, wie man eine Wand mauert. Sich hinzustellen und zu sagen "Hilfe, kann mir das wer abnehmen" kann ich machen, wenn ich einen Mauerer bezahlen will. Aber dann 'baue' ich eben nicht mehr selbst das Haus, sondern der Mauerer statt mir. Ist auch ok, nur nennen wir dann aber auch bitte das Kind beim Namen. Dazwischen gibt es nun mal nichts. Entweder man will etwas tatsächlich selbst machen, dann muss man das eben lernen. Oder man macht es nicht selbst, dann muss man jemanden bezahlen, der die Zeit investiert hat, das zu lernen. Und dass sich der die (in Vorleistung investierte) Zeit dann auch bezahlen lässt, finde ich nur fair.
Moritz M. schrieb: > also ich würde PWM nehmen. Ich würde einen Compare-Interrupt eines 16-Bit-Timers nehmen. Denn der kann mit recht wenig Rechenzeit die komplette Impulsfolge für 8 bis 12 Servos (zur Not auch mehr) generieren. > Das ist relativ einfach und man braucht > keinen Interrupt um ein Servo hin und her zu bewegen. Zum Hinundherbewegen braucht es sowiso keinen Interrupt, höchstens für das regelmäßige Auslösen der Servoimpulse. > Wenn der µC (AVR?) Ja, Mega128 auf einem fertigen Board mit angeschlossenem Dragon. Sieht fast so aus, als wäre es ein Geschenk, in der Hoffnung geschenkt, dass es zur Förderung der Intelligenz beiträgt. Ist nur doof, dass man das dazu erforderliche Wissen nicht mitschenken kann. Vielleicht wäre ein Multimediakonsum-Spielzeug besser angelegtes Geld gewesen... ;-)) > noch andere Sachen erledigen muss dann vllt. doch einen Interrupt. Um die optimale Lösung zu finden, muss man die gesamte Aufgabe kennen. Karl Heinz Buchegger schrieb: > Der springende Punkt ist, dass man ein paar Basistechniken lernen muss. Eben... ...
Moritz M. schrieb: > Hallo, > > also ich würde PWM nehmen. Das ist relativ einfach und man braucht > keinen Interrupt um ein Servo hin und her zu bewegen. Wenn der µC (AVR?) > noch andere Sachen erledigen muss dann vllt. doch einen Interrupt. > > Moritz der soll nur servos hin und her bewegen. habe mir die Seiten mehrere male durchgelesen, was Timer und Interuppt bedeutet, aber leider verstehe ich immer noch nicht, was Servo mit Timer und Interrupt zutun haben, wenn ein Servo mit Impulsen gesteuert wird.
jb schrieb: > ist schon klar, dass das nichts bringt wenn man ein Code > kopiert. Zum Verständis habe ich das gemacht. Ich gehe so dann jede > einzelne Zeile nochmal durch. Ich vestehe es besser so. Irgendwie glaubt das jeder, aber dass es nicht funktioniert sollte dir zu deken geben. jb schrieb: > habe mir die Seiten mehrere male durchgelesen, was Timer und Interuppt > bedeutet, aber leider verstehe ich immer noch nicht, was Servo mit Timer > und Interrupt zutun haben, wenn ein Servo mit Impulsen gesteuert wird. Wie wäre es, zuerst C vernünftig zu lernen (sicher noch nicht geschehen) und dann das AVR GCC Tutorial abzuarbeiten?
vn nn schrieb: > jb schrieb: >> ist schon klar, dass das nichts bringt wenn man ein Code >> kopiert. Zum Verständis habe ich das gemacht. Ich gehe so dann jede >> einzelne Zeile nochmal durch. Ich vestehe es besser so. > > Irgendwie glaubt das jeder, aber dass es nicht funktioniert sollte dir > zu deken geben. Wieso soll das nicht funktioniern? Jeder lernt doch anders um es zu verstehen.Die einen mit Beipspielen die anderen ohne.
jb schrieb: > ... leider verstehe ich immer noch nicht, Servo mit Timer und > Interrupt zutun haben, wenn ein Servo mit Impulsen gesteuert wird. Ganz einfach. Der Timer des ATmega8 kann z.B. so konfiguriert werde, dass er völlig selbständig Servopulse für zwei Servos regelmäßig auf zwei getrennten Pina ausgibt.
wenn ich dem Servo die Impulse vorgebe im welchen winkeln er sich drehen soll, brauch ich mehr als nur PWM.
Hi >wenn ich dem Servo die Impulse vorgebe im welchen winkeln er sich drehen >soll, brauch ich mehr als nur PWM. Ja. Aber mit der PWM hast du fast nichts mehr mit der Impulserzeugung zu tun. Du schreibst den passenden Wert für den Winkel in das entsprechende Compare-Register und fertig. Dein 'Steuerprogramm' braucht nur diese Werte zu richtigen Zeitpunkt bereitstellen. MfG Spess
...und habe ein Frage zum oberen Code. _delay_ms und _delay_us sind doch wartezeiten. wann erhält der servo sein Imupls um sich zu bewegen und von wem?
jb schrieb: > wann erhält der servo sein Imupls um sich zu bewegen und > von wem? Bei jedem Durchlauf der Programmschleife
ok, aber bei _delay_us stelle ich doch nur die Wartezeit ein und nicht den Winkel des Servos.
Hi >...und habe ein Frage zum oberen Code. _delay_ms und _delay_us sind doch >wartezeiten. wann erhält der servo sein Imupls um sich zu bewegen und >von wem? Was werden wohl die Zeilen > PORTA |= (1<<PA5); und > PORTA &= ~(1<<PA5); machen? Nimm dir ein Blatt Papier und einen Bleistift und zeichne auf, was am Port passiert. MfG Spess
jb schrieb: > wann erhält der servo sein Imupls um sich zu bewegen und > von wem? Der Servo bekommt gar keine Impulse für die Bewegung. Mit den Impulsen, die er dauernd bekommt, wird die Servostellung festgelegt. Den Rest, d.h. die Umsetzung der Pulsdauer in eine Position, macht die Servoelektronik ganz alleine.
Hi >ok, aber bei _delay_us stelle ich doch nur die Wartezeit ein und nicht >den Winkel des Servos. Die Wartezeit ist der Winkel. MfG Spess
spess53 schrieb: > Hi > >>ok, aber bei _delay_us stelle ich doch nur die Wartezeit ein und nicht >>den Winkel des Servos. > > Die Wartezeit ist der Winkel. > > MfG Spess Aha verstehe jetzt. habe es mir mal aufgezeichent. Zum Verständnis nochmal. > PORTA |= (1<<PA5); ist auf 1 ,d.h. er hat eine Spg. von 5V >_delay_us(2300); wartet 2,3 ms > PORTA &= ~(1<<PA5); ist auf 0,d.h. er hat eine Spg. von 0V _delay_ms(18); wartet 18ms bis zum nächsten Impuls
HI So in etwa. Allerdings sind die 2,3ms für den Impuls schon etwas grenzwertig: http://www.mikrocontroller.net/articles/Modellbauservo_Ansteuerung Und nochmal: Die Verwendung von _delay_us und _delay_ms ist der falsche Weg. Erstens ist der Controller damit zu 100% beschäftigt und zweitens arbeiten diese Funktionen nur mit Konstanten. Willst du für jeden Winkel eine eigene Funktion schreiben? MfG Spess
1 | #define MILLISEC_BASE ( F_CPU / PRESCALER / 1000 )
|
den Code habe ich aus dem oberen Link und wollte mal fragen, warum hat man hier mit 1000 dividiert? gruß
Hi >den Code habe ich aus dem oberen Link und wollte mal fragen, warum hat >man hier mit 1000 dividiert? Wie viele ms hat den eine Sekunde? MfG Spess
jb schrieb: > Wieso soll das nicht funktioniern? Jeder lernt doch anders um es zu > verstehen.Die einen mit Beipspielen die anderen ohne. Was hat es mit Beispielen zu tun, dass du diese ganz offensichtlich nicht annähernd verstehst, weil dir die Grundlagen fehlen und du einfach blind zusammenkopierst?
für meine 2-3 servos, die ich mit CTC-Modus (Timer0) programmieren möchte, kann ich doch die Ausgänge frei wählen oder? Ich würde sie gerne an den Pins PA0-PA2 anbringen. Falls ja: In den Register OCR0 gebe ich doch dann die Werte ein. z.B. für 1ms den Wert 7 (links), 1,5ms -> 11 (mitte) und 2ms -> 14 (rechts). gruß
fast PWM bzw. die anderen PWMs kann ich gar nicht benutzten, da die ja an bestimmte Pins angeschlossen sind.
jb schrieb: > fast PWM bzw. die anderen PWMs kann ich gar nicht benutzten, da die ja > an bestimmte Pins angeschlossen sind. Das ist z.B. auch einer der Gründe, warum ich einen Timer-Interrupt (Compare) bevorzuge. Es macht die Sache bedeutend flexibler und ist auch für mehrere Servos geeignet. ...
> Das ist z.B. auch einer der Gründe, warum ich einen Timer-Interrupt > (Compare) bevorzuge. Es macht die Sache bedeutend flexibler und ist auch > für mehrere Servos geeignet. das heißt du machst das über den CTC-Modus?
Mit welchen Befehl programmiere ich denn, dass der Servo in verschiedenen Positionen fahren kann (an PA0 Pin).
jb schrieb: > Mit welchen Befehl programmiere ich denn, dass der Servo in > verschiedenen Positionen fahren kann (an PA0 Pin). du hast noch so ziemlich gar nichts von dem begriffen, was du hier umsetzen willst... es wird langsam einfach mal zeit, dass du dich auf deinen allerwertesten setzt und liest! z.B.: ISBN 3486589881
> es wird langsam einfach mal zeit, dass du dich auf deinen allerwertesten > setzt und liest! > z.B.: ISBN 3486589881 das buch habe ich vor mir liegen
jb schrieb: > das heißt du machst das über den CTC-Modus? Nein, ich lasse den Timer meist frei durchlaufen. Denn der CTC-Modus blockiert mir die restlichen Features des Timers. Du möchtest Timer0 benutzen, also gehen wir mal eine der Möglichkeiten durch. Timer0 ist ein 8-Bit-Timer, Zählumfang 0 bis 255. Nun muss man Taktfrequenz des AVRs und Vorteiler des Timers so einstellen, dass der Zählumfang die Zeiten 1,0 ms bis 2,0 ms (besser 0,7 ms bis 2,3 ms) als Zahlenwerte abbilden kann. Bei 1 MHz Controllertakt und Vorteiler 1:8 reicht der Zählbereich gerade mal für 2,04 ms. Das ist für normale Servobewegungen geradeso ausreichend, könnte aber knapp werden, wenn man Fertigungstoleranzen ausgleichen und möglichst viel Hub erreichen will. Aber bleiben wir erstmal bei 1 MHz und Vorteiler 1:8. Servoimpulse werden nacheinander generiert. Der Beginn einer solchen Sequenz ist nicht besonders zeitkritisch, sollte aber doch einen Abstand von etwa 20 ms haben und nicht alzuviel Jitter aufweisen. Um nun diese Sequenz anzustoßen, bietet sich der Überlauf-Interrupt an, der alle 2,048 ms erfolgt. Nach jeweils 10 dieser Interrupts, also alle 20,48 ms wird ein neues Servotelegramm angestoßen. Das ist in der Norm, damit müsste selbst das anspruchvollste Digitalservo klarkommen. Also bauen wir eine ISR für den Timer0-Überlauf. In dieser ISR muss dann Folgendes passieren: - Telegrammabstandszähler vermindern - wird dieser dabei 0, dann - Telegammabstandszähler auf Startwert setzen (hier 10) - Impulszähler löschen - ersten Servoimpuls einschalten (Bitmuster aus Tabelle über Impulszähler als Index holen und an Port ausgeben) - Impulsdauer aus Array (über Impulszähler als Index) holen und in das Compare-Register des Timers schreiben, also den Termin für den ersten Compare-Interrupt vereinbaren Den Rest des Servotelegramms übernimmt der Compare-Interrupt. Welcher von beiden (A oder B) benutzt wird, ist erstmal nebensächlich. In diesem Compare-Interrupt muss Folgendes passieren: - Impulszähler erhöhen, dabei auf Servoanzahl + 1 begrenzen - neues Bitmuster für die Ausgänge aus Tabelle holen (Impulszähler als Index) und an Port ausgeben - neue Impulsdauer aus Array holen (Impulszähler als Index) - Compare-Register (nicht Timer-Register, am Timer selbst wird nichts verstellt!!!) holen - Impulsdauer auf Compare-Wert aufaddieren und als neuen Interrupt-Termin ins Compareregister zurückschreiben Du brauchst also ein Array mit Variablen (im SRAM), in dem für alle Servos (und ein Dummy) eine Impulsdauer vorhält. In dieses Array schreibt Dein Hauptprogramm dann die Positionswerte, die das Servo in diesem Moment anfahren soll. Weiterhin brauchst Du eine Tabelle mit Konstanten (im Flash oder SRAM), die für jedes Servo und ein Dummy Bitmuster bereithält, in denen nur der gewünschte Ausgang H ist und alle anderen L. Dies erlaubt die völlig freie Zuordnung der Servoausgänge zu den vorhandenen Pins, sogar über mehrere Ports, wenn Du für jeden involvierten Port ein Bitmusterbyte nutzt. Die Overflow-ISR startet nun alle 20,48 ms ein Servotelegramm Die Compare-ISR schaltet nach Ablauf der Impulsdauer die Servoimpulse um (den alten aus, den neuen ein, aber in einem Rutsch durch Ausgeben des neuen Bitmusters). Nach dem letzten Servo wird der Dummy-Eintrag der Liste gefunden, in dessen Bitmuster sind dann alle Ausgänge ausgeschaltet, um den aktuellen Impuls zu beernden. In dessen Impulsdauer steht der Maximalwert, um nicht unnötig viele Dummy-Interrupts auszulösen. Und da der Impulszähler auf diesen Dummy-Eintrag begrenzt wird, werden solange Dummy-Impulse (also keine Impulse) ausgegeben, bis der Telegammabstandszähler zuschlägt, den Impulszähler löscht und ein neues Telegramm anstößt. Vom Telegrammabstand kannst Du Dir noch einen Merker für das Hauptprogramm setzen lassen, den Du als Zeitnormal für das Berechnen von Verzögerungen der Bewegungswegen nutzen kannst. Es gibt weitere Möglichkeiten der Realisierung, mir fehlt aber Zeit und Lust, Dir diese alle detailliert zu erklären. ...
jb schrieb: > Mit welchen Befehl programmiere ich denn, dass der Servo in > verschiedenen Positionen fahren kann (an PA0 Pin). Mit einer Zuweisung der neuen Position in das Array. Du legst einfach nur zur richtigen Zeit die neuen Positionswerte in das Array. Den Rest macht die State-machine in den beiden Timer Interrupts selbstständig im Hintergrund. ...
vielen danke hannes das du dir zeit genommen hast für so einen langen text. ich werde es in den nächsten Tagen in die Tat umsetzten und davon berichten. Danke nochmal. gruß
jb schrieb: > vielen danke hannes das du dir zeit genommen hast für so einen langen > text. Nun musst Du nur noch diesen langen Text lesen, verstehen, und in der von Dir beherrschten Programmiersprache umsetzen. Aber eigentlich könntest Du schon weiter sein, denn ich habe ich Dir diese Variante hier schonmal vorgeschlagen: Beitrag "Re: Servo mehrere Male ansteuern" ...
Hannes Lux schrieb: > Aber eigentlich könntest Du schon weiter sein, denn ich habe ich Dir > diese Variante hier schonmal vorgeschlagen: > Beitrag "Re: Servo mehrere Male ansteuern" > > ... Auchg in Modellbauservo Ansteuerung ist eine fix fertige Ansteuerung mehrerer Servos drinnen. Ich versteh jetzt ehrlich nicht, wo da jetzt noch Probleme sein sollen. Es sei denn natürlich, man versucht wieder den 25.ten Schritt vor dem ersten. jb, um Programmieren lernen kommst du nicht herum! Das funktioniert einfach nicht. Wer was bauen möchte, muss die Grundlagen lernen.
> Auchg in > Modellbauservo Ansteuerung > ist eine fix fertige Ansteuerung mehrerer Servos drinnen. > > Ich versteh jetzt ehrlich nicht, wo da jetzt noch Probleme sein sollen. > Es sei denn natürlich, man versucht wieder den 25.ten Schritt vor dem > ersten. jb, um Programmieren lernen kommst du nicht herum! Das > funktioniert einfach nicht. Wer was bauen möchte, muss die Grundlagen > lernen. ich habe ja vor zwei jahren mit dem programmieren angefangen, nur nicht so intensiv. Es gab zwischen durch mal große pausen, wo ich nichts gemacht habe, so dass ich manche sachen wieder vergessen habe. ich habe ja den letzten Code mit 8 servos geändert,so dass ich drei servos steuern kann. da ich mehrere positionen brauche, war ich mir nicht so sicher ob ich array oder was anderes benötige. gruß
jb schrieb: >> Auchg in >> Modellbauservo Ansteuerung >> ist eine fix fertige Ansteuerung mehrerer Servos drinnen. >> >> Ich versteh jetzt ehrlich nicht, wo da jetzt noch Probleme sein sollen. >> Es sei denn natürlich, man versucht wieder den 25.ten Schritt vor dem >> ersten. jb, um Programmieren lernen kommst du nicht herum! Das >> funktioniert einfach nicht. Wer was bauen möchte, muss die Grundlagen >> lernen. > > ich habe ja vor zwei jahren mit dem programmieren angefangen, nur nicht > so intensiv. INTENSIV? Was bitte ist an dem Code dort intensiv? Das ist funktionierender Code für jemanden, der die 5. Stunde C Programmierung hinter sich hat! Der eigentliche 'Trick' in der Ansteuerung ist fertig ausgeführt, den braucht man nur noch zu benutzen.
Karl Heinz Buchegger schrieb: > Der eigentliche 'Trick' in der > Ansteuerung ist fertig ausgeführt, den braucht man nur noch zu benutzen. Manch Einer möchte ihn aber auch durchschauen... ;-) Schnell weg hier, denn ich kann kein C... ...
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.