www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik (Servo-) Impulse mit AVR intelligent ausgeben


Autor: UBoot-Stocki (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

meine ersten AVR Gehversuche sind gar nicht schlecht geworden. Ich habe 
z.B. einen AVR so programmiert, daß er die Gültigkeit eines 
Servo-Signals überprüfen kann (Capture-Interrupt und Timer)

Jetzt aber zu meiner Frage:

Was könnte eine intelligente Methode sein, einen 1-2ms langen Impuls 
alle ca. 20 ms wiederholt mit einem AVR auszugeben?

Das "dumme" ausführen einer Warteschleife kann ich nicht machen, da der 
AVR zwischenzeitlich noch andere Dinge machen soll ... Leider habe ich 
keine Methode über den Timer gefunden (das mit dem PWM-Ausgang scheint 
für meinen Anwendungsfall nicht geeignet zu sein ...)

Wer hat eine Idee ?

Gruß

UBoot-Stocki

Autor: André Füßer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Timerinterrupt alle 20ms aufrufen lassen, anfangs Pegel setzen, 1-2ms 
"dumm" warten, Pegel löschen... so bleiben fürs Hauptprogramm 18ms bis 
zum nächsten Interrupt übrig.

André.

--
CAN@home - http://www.CANathome.de - Hausautomation mit AVR + CAN

Autor: Siegfried (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aus der Hüfte geschossen würde ich sagen, mach doch einen 
Timer-Interrupt genügend klein um dann mit einem entsprechend 
softwaremässig eingestellten Counter die Impulsweite bzw. -Pause zu 
bestimmen.

Bei näherer Betrachtung taucht ein Problem auf:

1-2 ms = 1000 - 2000 µS.
Mal angenommen, zwischen den beiden Vollausschlägen des Servos sollen 
100 Schritte liegen !?. Dann muss die Software Impulsweiten von 1000, 
1010, 1020, .... 2000 µS. Mit anderen Worten, der Timer muss auf 10µS 
eingestellt werden. Die Zeit ist doch recht knapp, um den 
Interrupservice auszuführen. Ein Atmel mit 8 MHZ macht zwar 4 Befehle 
pro µS = 40 Befehle pro 10µS. Das wird immerhin noch knapp genug für die 
Anwendung.

Anderer Ansatz:
Mit einem Timer erzeugt man wie bereits von Andre beschrieben einen 20ms 
Interrupt und ein anderer Timer wird immer mit der jeweilig 
einzustellenden Impulszeit aufgezogen. Der 20 ms Timer sorgt dafür, das 
die gesammte Steuersequenz im 20ms Takt angeschossen wird.

Wieviel Servos sollen denn angesteuert werden?
Bei Fernsteuerempfängern folgen die Impulse nacheinander an die Servos. 
Falls der Impuls zeitgleich für alle Servos kommt, könnte es Probleme 
mit Stromspitzen geben.

Siegfried

Autor: UBoot-Stocki (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

vielen Dank für die Antworten. Sie haben mich doch schon nachdenklich 
gemacht....

@Siegfried: Ich arbeite an einem Regler für die UBoot-Tiefe. Über einen 
Drucksensor soll der Istwert (noch aufzubauendes ADC-Programm) ermittelt 
werden. Der Sollwert kommt von der Fernsteuerung ( Capture mit Timer 1 
s.o.). Ausgegeben werden soll das ganze an die Tauchzelle (das sind 2 
Ltg. eines Ports) und an die zwei Tiefenruder -> zwei Servos. Die 
Impulse für die Servos sollen nacheinander erzeugt werden.

Was haltet Ihr von folgender Idee:

Der 1-2ms Impuls wird mittels 8BIT-Timer (Timer 1) erzeugt. der 
"CPU-Teiler" wird so eingestellt, daß in 1 ms (2ms - 1ms = 1ms :-) ) 
möglichst 255 Schritte gemacht werden können.
Nach dem Timerüberlauf in der Interrupt-Routine wird die Timer-Zeit neu 
eingestellt  (für das 2. Servo).
Danach wird in der Int-Routine der Teiler und die Zeit so verstellt, daß 
ca. 16ms Ablaufen können.

Frage: Ist es "üblich / erlaubt" den Timer sowie den Teiler zur Laufzeit 
ständig zu verstellen ?

Gruß

Andreas

Autor: A.Füßer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Was haltet Ihr von folgender Idee:
gut.

>Frage: Ist es "üblich / erlaubt" den Timer sowie den Teiler zur Laufzeit ständig 
zu verstellen ?
Ja/ja. Anhalten während des Umstellens schadet nicht.

André.

--
CAN@home - http://www.CANathome.de - Hausautomation mit AVR + CAN

Autor: Siegfried (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gute Idee.

oder so:

1. 20000 merken (= 20 ms)
2. 20000 - 1500 (abzgl. Impulslänge 1,5 ms des Servo1)
3. 18500 - 1400 (abzgl. Impulslänge 1,4 ms des Servo2)
4. 17100 ( = 17,1 ms) Restzeit bis zum Schritt 1.

Ob es die Servos den Impuls nach genau 20ms brauchen, weis ich leider 
nicht. Es würde mich allerdings auch interessieren.

Siegfried

Autor: Björn Jonas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

es müssen nicht genau 20ms sein. Ich hab die Zeit mal auf 40ms 
hochgeschraubt, weil ich sonst nicht mehr genug Rechenleistung hatte.
Wenn der Servo keine Impulse bekommt bleibt er meist in Position, regelt 
aber nicht mehr nach. D.h. man kann den Servo dann verstellen.

-> Ausprobieren bis zu welchem Implusabstand das Ergebnis noch 
zufriedenstellen ist.

Bei Timern sollte man die Interruptlatenzzeit berücksichtigen, Stichwort 
Jitter. Ein rumzitternder Servo ist ja meist nicht erwünscht.

Björn

Autor: UBoot-Stocki (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich habe gestern mal ein bischen rumexperimentiert. Das Problem war 
folgendes:

Bei 4 MHz AVR-Taktfrequenz und 1ms Servo-Impuls (von ganz rechts bis 
ganz links) möchte ich schon die vollen 8 BIT Auflösung des Timers haben 
(-> 255 Servoschritte). Dies bedeutet das der Zähler auf 0,001s / 
1/4.000.000Hz = 4000 zählen müsste. Da er nur 8 BIT hat, brauche ich 
einen Teiler von 4000 / 256 = 15,.. = 16. Dummerweise bietet der Zähler 
aber nur einen Teiler von 8 :-(

Ich habe es erstmal so gelöst, daß ich mit Teiler 8 arbeite und die 
Interrupt-Routine einfach 4x aufrufe...  (2x um 1ms zu erzeugen und 2x 
für die Zeit für das Servo (0-1ms) ) :-)))
Die (in diesem Beispiel) 18ms bis zum nächsten impuls bekomme ich dann 
über den Teiler 1024 (0,018s / 1/4000000Hz)

Das funktioniert gut. Was mir nicht gefällt, ist die Tatsache, daß wenn 
man von zwei oder drei oder gar mehreren Servos ausgeht, die 
Interrupt-Routine ganz schön kompliziert wird. Ich müßte ja für jedes 
Servo quasi zuerst 1ms ausgeben und dann Servo-spezifisch den Impuls 
verlängern. Hätte also 8 (bei 8 Servos) Interrupt-Routinen oder eine mit 
einem gigantischen "if case" ......

Frage:

In C löst man sowas mit einer Routine und einem Zeiger ! Wie macht man 
einen Zeiger auf eine Tabelle (mit Werten für die Servos) in Assembler ? 
Wie legt man die Werte für die Servos in dieser Tabelle (RAM?) ab ?

Wer hat Anregungen ?

Gruß

UBoot-Stocki

Autor: H. Howey (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo...
beim durchstöbern von Zeitschriften, bin ich auf einen Bericht aus der 
Zeitschrift Elektor 09/2001 gestoßen. Dort wird über eine I2C 
Schnittstelle ein Servointerface mit acht Servos beschrieben 
(erweiterbar bis 64 Servos). Das Ganze besteht aus ein paar NE 555 bzw. 
NE 556 und dem I2C IC TDA8444 (mit D/A).
Diese Schaltung kann man auch so modifizieren, das man sich das 
Interface spart und sofort an den MC ran geht (wenn man will :-). Die 
Funktion ist, das die Timer (556) durch den Control Eingang CV die 
Impulsbreite vergrößert wird.
Zumindest reduziert sich der Aufwand durch den Einsatz von 
Hardware-Timern erheblich.
Gruß
H. Howey

Autor: H. van Gils (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
es gibt bijspiel code fur 8 servo stuerung im background auf seite 
http://www.dvanhorn.org/AvrSoftware/Index.php
.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.