PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Servos am ATMega48



BlueEagle
08.08.2006, 18:52
Hallo!

Bin neu hier im Forum. Ich wollte mit Servos ein wenig experimentieren.

Im Forum habe ich gelesen dass es mehrere Möglichkeiten gibt Servos anzusteuern.

1. PWM-Kanäle der uCs
2. per Software die PWM-Signale erzeugen (über digital-Ports)
3. per Controller (z.B. SD20)

Nun meine Frage. Ich tendiere momentan dazu die 1. Möglichkeit zu verwenden indem ich die Servos an den uC hänge. Laut dem Datenblatt des ATMega48 hat er 6 PWM-Kanäle. Könnte ich damit auch 6 Servos ansteuern oder muss ich da was beachten?

Bei dieser Möglichkeit wäre doch die Auslastung des uC doch sehr gering sodass ich noch genügend Leistung für Berechungen übrig habe oder?

Bin momentan noch Anfänger auf dem Gebiet und würde mich über ein paar klärende Antworten freuen.

Grüße
BlueEagle

Hanni
08.08.2006, 19:37
Nun meine Frage. Ich tendiere momentan dazu die 1. Möglichkeit zu verwenden indem ich die Servos an den uC hänge. Laut dem Datenblatt des ATMega48 hat er 6 PWM-Kanäle. Könnte ich damit auch 6 Servos ansteuern oder muss ich da was beachten?

Bei dieser Möglichkeit wäre doch die Auslastung des uC doch sehr gering sodass ich noch genügend Leistung für Berechungen übrig habe oder?

Ja, damit hat man eigentlich so gut wie gar keine Hardware Auslastung (die PWM erzeugt der µC selbst ... jedenfalls wenn das einmal konfiguriert ist).

Zu beachten ist dabei das folgende:

Servos benötigen eine bestimmte Signalform um angesteuert zu werden.
Im Klartext heisst das, ein Impuls zwischen 1ms und 2ms Breite, der die Servoposition angibt und alle 20ms wiederholt wird.

Das heisst:
du müsstest die 3 Timer des ATmega48 so konfigurieren, das sie bei 20ms von vorne anfangen zu zählen (als Tip: Prescale und Timer Maximalwert)

Einen Tip kann ich dir noch geben, lies dir im entsprechendem Datenblatt einfach mal den Abschnitt zu Fast PWM durch und schau die die verschiedenen Timermodi an.

Grüße,
da Hanni.

BlueEagle
08.08.2006, 20:18
Hallo!

Danke für deine schnelle Antwort.

Ich müsste also bei den Interrupts die Pulslänge entsprechend anpassen dass die Servos in die richtige Position gehen.

Ich bin jetzt ein wenig verwirrt weil es doch 6 PWM-Kanäle gibt. Muss ich dann einfach bei jedem Timer alle 20 ms für 2 PWM-Kanäle die Pulslänge setzen? Oder kann ich nur 3 Servos anschließen entsprechend der Timerzahl?

Gruß
BlueEagle

Hanni
08.08.2006, 20:51
Also, wenn ich mich recht entsinne (hab jetzt grad das Datenblatt nicht bei der Hand), kann jeder Timer 2 PWM Kanäle ansteuern. Das macht dann in der Summe 6.

Zur Konfiguration des eines Timers:
Mal angenommen der µC rennt mit 4 MHz.

Dann macht der Timer ohne Prescaler in 20ms exakt 20000 Zählschritte.
Das ist natürlich für einen 8Bit Timer etwas viel (der kann nur bis 255 zählen ..).
Nun kommt der Prescaler ins Spiel. Dieser sagt dem Zähler: "Hör mal zu, du zählst nur jeden Xten Takt eins weiter.".

Also nehmen wir in unserem Beispiel einmal an, wir hätten den Prescaler auf 128 gesetzt.

Es ergibt sich also für den Zählerendwert: (20000 / 128) - 1 = 155

Nun kommt das nächste Problem:
Wir wollen einen Impuls erzeugen, der zwischen 1ms & 2ms lang ist.
also:
(1000 / 128) -1 ~ 7
(2000 / 128) -1 ~ 15

Dieser Wert kommt ins Kompare Register.

Die Genauigkeit mit der der Servo gesteuert werden kann ist natürlich sehr gering ... ich habe gerade mal 8 mögliche Positionen zur Auswahl ...

Mal eine andere Frage: in welcher Programmiersprache willst du das eigentlich realisieren ?

Grüße,
da HAnni.

BlueEagle
08.08.2006, 23:21
Hallo!

Auf die Programmiersprache habe ich mich noch nicht festgelegt.

Ich schwanke momentan noch zwischen Basic und C.

Grüße
BlueEagle

Hanni
08.08.2006, 23:44
Nuja, in Basic (Bascom) sind Servoroutinen integriert ....
nur sollte der µC dann auch mit min 8 MHz laufen ....

BlueEagle
09.08.2006, 10:23
Hallo!

Also in Basic habe ich ein wenig Erfahrung. Was mich an Bascom stört is halt das man in der Demo nur 4K Programme schreiben kann und das evt später knapp werden kann.

Und für 90 € die Vollversion zu kaufen, wenn ich mit WinAVR das für umsonst bekäme(müsste halt C lernen) will ich auch nich unbedingt...oder gibt es in diesem Bereich Probleme mit C?

Nun zurück zu den Servos:
Ich habe hier (https://www.roboternetz.de/phpBB2/viewtopic.php?t=14902) einen Beitrag von dir gefunden in dem du schreibst dass du zwei Servos mit 1001 Schritten ansteuern kannst und 4 Servos mit 125 Schritten.

Das mit den 1001 Schritten is mir klar da du den 16bit Timer verwendest und damit über 60000 Zählerschritte frei hast.

Doch die anderen Timer sind doch nur 8bit Timer - wie kannst du also mit diesen 125 Schritte einstellen?

Hab ich jetzt was falsch verstanden?

Grüße
BlueEagle

Hanni
09.08.2006, 13:44
oh je, frag mich bitte nicht, was damals der Grundgedanke war ... deer Post stammt vom 4:34 Uhr am Morgen ... wer weis. was ich mir damals dabei gedacht habe :D

BlueEagle
09.08.2006, 14:15
Hallo

Könnte man irgendwie die Genauigkeit erhöhen sodass ich so um die 64 Schritte zur verfügung habe?

Vielleicht könnte man bei Interrupts irgendeine Variable als Counter benutzen und so den Prescaler etwas kleiner wählen.

Man müsste dann zum Beispiel nur alle x Interupts den entsprechenden Wert in das Compare Register schreiben.

Somit müsste sich doch auch die Anzahl der möglichen Schritte erhöhen.

Ist jetzt nur so ne Idee von mir, wobei ich ned weiß ob die sich realisieren lassen würde...

Grüße
BlueEagle

Hanni
09.08.2006, 15:27
Hmm, folgende Idee:

Wenn man eine PWM konfiguriert, kann man ja einstellen, ob ein Pin wackeln soll oder nicht.

Daher könnte man das ganze wiederum in 20 Zeitslots a 1 ms einteilen und die PWM nur in der einen relavanten Millisekunde am Pin Wirksam werden lassen. die Restliche Zeit ist der Pin dann auf L (ausser in der 1 ms vor der PWM, da muss er H sein)

also, Möglichkeiten gibt es viele ...

BlueEagle
09.08.2006, 16:01
Hallo

Also wenn ich das richtig verstanden habe dann ist bei 4Mhz 1ms nach 1000 Takten "vorbei". Diese 1000 Takte kann man ja mit dem Prescaler für den Counter begrenzen also z.B. 1000 / 8 = 125. Dann setzt man alle 19 Timerdurchläufe den PWM-Kanal auf high. Dazu schreibe ich dann z. B. 62 in das Compare Register. Damit wäre rein rechnerisch die Pulslänge bei 0,496ms(+1ms also 1,496ms) und das Servo würde in die Mittelstellung gehen...oder?

Wie mache ich es am besten das der PWM-Kanal nur alle 19 mal aktiviert wird? Mein Ansatz wäre dass ich in einer Variable mitzähle...

Grüße
BlueEagle

Hanni
09.08.2006, 17:13
nuja ... bei 4 MHz sind 1 ms = 4000 Takte (war nen denk und tipfehler von mir da oben)

Der Ansatz mit der Variable könnte funzen ..
du musst halt alle 20 Durchläufe den Pin auf den Timer schalten ...

pebisoft
09.08.2006, 17:44
ich habe 4 servo(5 euro von conrad) am küchenbot und steuere die frei ,siehe beispiel (180 grad), frage den srf04ultra ab und sende die daten zum pc mit dem easy-radio-funkmodul , ich scanne den raum damit ab,
1 waitus braucht gemäss ausrechnung der asmlaufroutine 10us , darum sind die servowertzahlen um den teiler 10 kleiner :



Sub scan_vorn()
For servo_wert = 1 To 180
servo_wert1=servo_wert+50
servo_wert2=2000-servo_wert1
PORTB.0=1
WaitUs (servo_wert1)
PORTB.0=0
WaitUs (servo_wert2)
srf04_vorn()
Print #1,Str(srf04_w_vorn)
Next wert
For servo_wert = 180 To 1 Step -1
servo_wert1=servo_wert+50
servo_wert2=2000-servo_wert1
PORTB.0=1
WaitUs (servo_wert1)
PORTB.0=0
WaitUs (servo_wert2)
srf04_vorn()
Print #1,Str(srf04_w_vorn)
Next wert
End Sub