PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Servosteuerung ohne Arduino und Co



Strawhat
20.02.2015, 21:16
Hallo zusammen,

ich baue gerade eine UselessBox für eine Projektarbeit und bräuchte dringend Hilfe beim Verständnis der Servosteuerung.
Ich möchte die Steuerung nicht durch Bibliotheken wie Arduino etc. realisieren, sondern die Signale verstehen und mit C allgemein funktionell programmieren.

Ich nutze einen Atmega328p IC und habe bereits herausgefunden, dass ich die Position der Servos mit PWM Steuersignalen festlegen kann. Leider verstehe ich die umfangreichen englischen
erklärungen der PWM Signalerzeugung/manipulation nicht gut genug. Man muss ja irgendwelcher TimerBits etc setzen und das schien mir immer zu umständlich erklärt.

Kennt Ihr ein gutes Tutorial zur PWM Erzeugung und Manipulation für die Steuerung von Servos oder gibt es bessere Verfahren?

Geistesblitz
20.02.2015, 21:43
Ne einfache klassische Useles-Machine funktioniert auch ohne Mikrocontroller, einfach mit Schaltlogik. Dazu ließe sich die Elektronik aus dem Servo entfernen und dieser wie ein Getriebemotor steuern. Wann und in welche Richtung er läuft, ist dann von diversen Schaltern abhängig, da bräuchte man dann neben dem Hauptschalter noch zwei Endschalter, an welche der Servo anschlägt. Den Rest macht dann die richtige Verdrahtung. Irgendwo hatte ich dafür schonmal einen Schaltplan, muss ich nochmal suchen, vielleicht kommst du aber auch selber drauf ;)

Hmm, die PWM für einen Servo würde ich in Software erzeugen, da die Harware-PWM nureine recht grobe Auflösung von bis zu 10 Bit hat. Sind zwar 1028 Schritte, allerdings kannst du dich ja nur in dem Bereich von 1-2ms von 20ms bewegen, was einem Tastverhältnis von 0,05 bis 0,1 entspräche. Kämen also nur die Schritte von 52 bis 103 in Frage, das hieße du könntest deinen Servo nur in ca. 52 Schritten bewegen, dazwischen ginge nix. Daher wäre es besser, das Servosignal dann mit einem Timer selber aufzubauen. Der Timer funktioniert ja so, dass er in einem bestimmten Takt hochzählt und bei einem Überlauf eine Unterfunktion auslöst. In dieser Unterfunktion wird dann meist der Timer auf einen gewünschten Wert gesetzt, damit dieser das nächste mal dann in der gewünschten Zeit überläuft. So lassen sich ziemlich präzise Zeiten einstellen. Da müsstest du dann einstellen, wie lange der Pin für die PWM an sein soll und beim nächsten Mal, wie lange er dann aus sein soll.

Strawhat
20.02.2015, 22:11
Ich will ne Useless Machine mit komplexeren unterschiedlichen Bewegungsabläufen machen, deshalb fällt dein Ansatz leider flach ^^

Mit Software-PWM meinst die Erzeugung durch Unterbrechungen(delays) von Dauersignalen?
Würde mich wundern, wenn die Hardware PWM nur so geringe Schrittzahlen unterstützen würde, aber wenn das so ist, muss ich wohl auf die Software-PWM zurückgreifen.

Hast ja irgendwelche Tutorials oder ein Testprogramm? Ich nutze übrigens 180° Servos (nicht umgebaut) und würde diese auch gern so belassen, brauch eh keine 360° Drehungen :)

oberallgeier
20.02.2015, 22:14
... die PWM für einen Servo würde ich in Software erzeugen, da die Harware-PWM nureine recht grobe Auflösung von bis zu 10 Bit hat ...Das verstehe ich jetzt nicht wirklich. Ich habe meine Hardware-PWMs für Servos überwiegend mit nem 16bittigen Timer laufen, davon nutze ich aber nur 12 bis 13 Bit, genauer: Auflösungen von rund 4000 und drüber für den möglichen bzw. genutzen Schwenkbereich des Servos. Ne Auflösung mit rund 4000 bis 6000 Ticks ist etwa zehnmal so fein wie meine billigen Servos überhaupt fahren können - aber sie können das. (https://www.roboternetz.de/community/threads/61379-Kopfsache-und-ein-m1284-etliche-Servos-viel-Alu?p=577672&viewfull=1#post577672)

Geistesblitz
20.02.2015, 22:36
Wo hat ein Atmega328 denn 16 Bit HW PWM? Ich war jetzt jedenfalls der Meinung, dass sich die Hardware-PWM nur bis 10 Bit Auflösung hochschrauben ließe und das auch nur über den gesamten Stellbereich für das Tastverhältnis. Für ein Servosignal braucht man allerdings nur einen kleinen Teil davon, daher würde sich ja eigentlich die Auflösung reduzieren, oder? So hab ich das jedenfalls bisher verstanden.

oberallgeier
21.02.2015, 07:59
Wo hat ein Atmega328 denn 16 Bit HW PWM? ...Aufm Chip, wo sonst - die Frage verstehe ich nicht. Es macht jedenfalls Sinn das Datenblatt zu lesen, z.B. ATmega48A-bis-328-328P_8271G-02-2013. Dort gibts ein sechzehntes Kapitel mit dem Titel

16. ... 16-bit Timer/Counter1 with PWM
16.1 ..... Features
............ • True 16-bit Design (i.e., Allows 16-bit PWM)

Schau Dir mal die Pinbelegung von PB1 und PB2 an.


... Ich war jetzt jedenfalls der Meinung, dass sich die Hardware-PWM nur bis 10 Bit Auflösung hochschrauben ließe ...Im Umfeld "C" bzw. AVRGCC ist das nicht der Fall, wie es mit Bascom oder arduinos IDE ist weiß ich nicht.

Geistesblitz
21.02.2015, 12:01
Gut, ok, das war mir bisher nicht so bewusst gewesen. Damit sollte das dann doch funktionieren.

Strawhat
21.02.2015, 12:52
Leider bringt mich diese Tatsache nicht weiter x)
Kennt keiner von euch eine möglichst deutschsprachige Seite, die die Funktion von PWM in Verbindung mit Servos erklärt?

radbruch
21.02.2015, 14:21
Hallo

Die Funktion ist schnell erklärt. Das Servo reagiert auf die Impulslänge. Eine Impulslänge von ca. 1 Millisekunde stellt das Servo in die Mitte, 0,5ms ist Anschlag auf der einen Seite, 1,5ms auf der anderen Seite. Der Impuls wird alle 20ms wiederholt. Das wars schon.

Die Werte variieren bei den Servos, Die Wiederholung kann bei digitalen Servos oder Brushless-Reglern deutlich häufiger sein. Der Impuls ist fast immer positiv. Da das Puls-Pause-Verhältnis verändert wird, nennt man es PWM.

Ein Servo mit einem Timer anzusteuern ist nicht so sehr kompliziert. Man nimmt einen Mode mit einstellbarem TOP. Dieses TOP wählt man so, dass das Zählregister 20ms braucht um es beim verwendeten Kontrollertakt und gewähltem Vorteiler zu erreichen. Dann schreibt man in das Vergleichsregister den Wert, der der gewünschten Impulsdauer entspricht:


// Timer1 für 16MHz-ATMega256
# define OC1A PB5
# define OC1B PB6
TCCR1A = 0;
TCCR1B = (0<<CS12)|(1<<CS11)|(0<<CS10); // prescaler /8

TCCR1A |= (1<<WGM11)|(0<<WGM10); // Mode 14: FastPWM mit ICR1 als Top
TCCR1B |= (1<<WGM13)|(1<<WGM12);

TCCR1A |= (1<<COM1A1)|(0<<COM1A0); // OCR1A set on Botton, reset on Match
TCCR1A |= (1<<COM1B1)|(0<<COM1B0); // OCR1B set on Botton, reset on Match

TCNT1 = 0; // Timer1 zurücksetzen;
ICR1 = 40000; // 16MHz/8/20mS für 20ms-Zyklus
OCR1A = 3000; // Match und OC1A auf Low nach 1,5ms
OCR1B = 3000; // Match und OC1B auf Low nach 1,5ms

DDRB |= (1<<OC1A) | (1<<OC1B); // PWM-Pins sind Ausgang...
PORTB &= ~((1<<OC1A) | (1<<OC1B)); // ...und low

(Code für zwei Servos an einem Mega256 mit 16MHz)

Natürlich gibt es noch unzählige andere Möglichkeiten ein Servo anzusteuern.

Gruß

mic

Strawhat
21.02.2015, 17:14
Danke dir, sowas hatte ich gesucht :) kannst du mir nur erklären wie es bei nem 8MHz Atmega aussähe bzw. was es mit den Prescaler und der Zyklusberechnung ICR1 auf sich hat?

Was müsste ich wie manipulieren um den einen oder anderen Servo anzusteuern?

radbruch
21.02.2015, 18:09
Hallo

Mit dem Prescaler erzeugt man den heruntergeteilten Takt für den Timer aus dem Takt des Kontrollers. Der Takt des Timers ist um der Faktor des Vorteilers geringer als der Kontrollertakt. Ein 8MHz-Mega8 zählt mit Prescaler /8 in 20ms bis 8000000/8*0,020=20000. In einer Millisekunde zählt er bis 1000.

Weil es so einfach ist, wählt man den Mode 14 "Fast-PWM mit ICR1 als TOP" und begrenzt den Zählbereich mit dem IRC1-Register auf 20000. Das Zählregister TCNT1 zählt dann von 0 (Bottom) nach 20000 (Top) und wird beim Erreichen von Top wieder auf Bottom gesetzt. Ein Zyklus dauert nun 20ms.

Das Vergleichsregister OCR1A (A für Kanal A) wird mit 1000 geladen und der Ausgang OC1A wird so eingestellt, dass der Ausgang (beim Mega8 ist OC1A der Pin PB1) bei TCNT1==Bottom auf High und bei TCNT1==OCR1A wieder auf Low gesetzt wird. Wenn dann noch das Datenrichtungsregister auf Ausgang konfiguriert ist, wird am Pin PB1 ein Impuls ausgegeben,der 1ms dauert. Wenn man nun den Wert in OC1A ändert, ändert sich auch die Impulsdauer.

In den Registern TCCR1A und TCCR1B (hier bezeichen A und B die zwei Register und nicht die zwei Kanäle!) werden der Prescaler (CS), der Modus (WGM) und die Ansteuerung des Ausgang (COM1A0 und COM1A1, A ist hier wieder der Kanal) durch setzen der entsprechenden Bits ausgewählt.

Ich habe die Datenblätter nur überflogen, aber ich denke, die Register vom Mega8 und vom Mega256 stimmen in etwa überein. Bis auf das Setup des Pins kannst du deshalb die Konfiguration von oben übernehmen.


Was müsste ich wie manipulieren um den einen oder anderen Servo anzusteuern?
Mit OCR1A beeinflußt man die Impulsdauer an OC1A (PB1). Mit OCR1B funktioniert das dann auch mit OC1B an PB2, wenn du COM1B0 und COM1B1 und das DDR für Pin PB2 auch konfiguriert hast. Der Prescaler, der Mode, das Zählregister und die Einstellung für Top gilt für beide Kanäle.

Übrigends läuft das alles automatisch im Hintergrund ohne dein Programm zu beeinflussen oder gar zu bremsen.

Gruß

mic

Strawhat
21.02.2015, 18:39
Vielen Dank für die ausführliche Erklärung, damit kann ich mal was Anfangen. Hier wäre wohl ein Oszi nicht schlecht ... leider sind die ja so teuer =/

Hab mal einen gesehen, der es über einen PC laufen ließ, gibts da Oszi Hardware für PC? Was haltet ihr davon?

Sisor
21.02.2015, 18:55
Hab mal einen gesehen, der es über einen PC laufen ließ, gibts da Oszi Hardware für PC? Was haltet ihr davon?
Google mal nach: Logic Analyzer
Die Teile gibts zum Teil erstaunlich günstig zu haben.

Strawhat
21.02.2015, 19:35
Und was taugen diese Logic Analyzer im vergleich zu normalen Digital Oszis?

radbruch
21.02.2015, 19:43
Hier wäre wohl ein Oszi nicht schlechtDas Oszi ist dein Servo. Letztlich ist es doch egal, wie lange der Impuls ist. Wichtig ist nur, dass das Servo in erkennt.

Strawhat
21.02.2015, 19:52
Schon, es geht mir eher um das Verständnis des Ganzen. Das Oszi würde mir Zeigen, wie das Signal sich verändert und würd sicherlich mehr aushalten als mein Servo im Falle eines Fehlers.
Je tiefer ich in die elektronik Themen eintauche, desto bewusster wird mir, dass das absolut kein billiges Hobby ist =/