Forum: Mikrocontroller und Digitale Elektronik Servo mehrere Male ansteuern


von jb (Gast)


Lesenswert?

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

von Peter II (Gast)


Lesenswert?

ein servo wird eh sehr oft pro sekunde mit "daten" versorgt, du änderst 
dann nur die werte und schon macht er etwas.

von B e r n d W. (smiley46)


Lesenswert?

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.

von jb (Gast)


Lesenswert?

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.

von Hannes L. (hannes)


Lesenswert?

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.

...

von Magnus M. (magnetus) Benutzerseite


Lesenswert?

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.

von Timmo H. (masterfx)


Lesenswert?

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.

von Hannes L. (hannes)


Lesenswert?

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...

...

von ... (Gast)


Lesenswert?

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

von Michael A. (Gast)


Lesenswert?

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.

von Timmo H. (masterfx)


Lesenswert?

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

von Wim (Gast)


Lesenswert?

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.

von spess53 (Gast)


Lesenswert?

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

von Simon K. (simon) Benutzerseite


Lesenswert?

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.

von Hannes L. (hannes)


Lesenswert?

spess53 schrieb:
> Wann hat jb etwas von einem XMega geschrieben?

Na unter dem fängt man doch heutzutage gar nicht mehr an... :-))

...

von spess53 (Gast)


Lesenswert?


von Karl H. (kbuchegg)


Lesenswert?

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.

von jb (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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

von Udo S. (urschmitt)


Lesenswert?

jb schrieb:
> ich habe den irgendwo kopiert, wo genau weiß ich nicht mehr. habe
> bisschen rumexperementiert, aber naja.

Programmieren heute?

von jb (Gast)


Lesenswert?

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.

von Timmo H. (masterfx)


Lesenswert?

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...

von jb (Gast)


Lesenswert?

sondern?

von Timmo H. (masterfx)


Lesenswert?

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.

von jb (Gast)


Lesenswert?

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.

von jb (Gast)


Lesenswert?

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

von STK500-Besitzer (Gast)


Lesenswert?

jb schrieb:
> Ist es auch möglich ohne irgendwelche Taster, Poti, Schalter etc. einen
> Servo zu steuern?

Ja.

von jb (Gast)


Lesenswert?

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?

von µC-Bastler (Gast)


Lesenswert?

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.

von Hannes L. (hannes)


Lesenswert?

µ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.

...

von Moritz M. (avrprogger)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Hannes L. (hannes)


Lesenswert?

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...

...

von jb (Gast)


Lesenswert?

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.

von Vn N. (wefwef_s)


Lesenswert?

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?

von jb (Gast)


Lesenswert?

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.

von Wolfgang (Gast)


Lesenswert?

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.

von jb (Gast)


Lesenswert?

wenn ich dem Servo die Impulse vorgebe im welchen winkeln er sich drehen 
soll, brauch ich mehr als nur PWM.

von spess53 (Gast)


Lesenswert?

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

von jb (Gast)


Lesenswert?

...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?

von Werner (Gast)


Lesenswert?

jb schrieb:
> wann erhält der servo sein Imupls um sich zu bewegen und
> von wem?
Bei jedem Durchlauf der Programmschleife

von jb (Gast)


Lesenswert?

ok, aber bei _delay_us stelle ich doch nur die Wartezeit ein und nicht 
den Winkel des Servos.

von spess53 (Gast)


Lesenswert?

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

von Michael A. (Gast)


Lesenswert?

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.

von spess53 (Gast)


Lesenswert?

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

von jb (Gast)


Angehängte Dateien:

Lesenswert?

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

von spess53 (Gast)


Lesenswert?

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

von jb (Gast)


Lesenswert?

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ß

von spess53 (Gast)


Lesenswert?

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

von jb (Gast)


Lesenswert?

alles klar. danke :)

von Vn N. (wefwef_s)


Lesenswert?

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?

von jb (Gast)


Lesenswert?

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ß

von jb (Gast)


Lesenswert?

fast PWM bzw. die anderen PWMs kann ich gar nicht benutzten, da die ja 
an bestimmte Pins angeschlossen sind.

von Hannes L. (hannes)


Lesenswert?

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.

...

von jb (Gast)


Lesenswert?

> 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?

von jb (Gast)


Lesenswert?

Mit welchen Befehl programmiere ich denn, dass der Servo in 
verschiedenen Positionen fahren kann (an PA0 Pin).

von michael_h45 (Gast)


Lesenswert?

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

von jb (Gast)


Lesenswert?

> 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

von Hannes L. (hannes)


Lesenswert?

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.

...

von Hannes L. (hannes)


Lesenswert?

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.

...

von Hannes L. (hannes)


Lesenswert?

jb schrieb:
> das buch habe ich vor mir liegen

Das kenne ich nicht, da kann ich nicht mitreden.

...

von jb (Gast)


Lesenswert?

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ß

von Hannes L. (hannes)


Lesenswert?

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"

...

von Karl H. (kbuchegg)


Lesenswert?

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.

von jb (Gast)


Lesenswert?

> 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ß

von Karl H. (kbuchegg)


Lesenswert?

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.

von Hannes L. (hannes)


Lesenswert?

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
Noch kein Account? Hier anmelden.