PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Servo mit Atmega8 ansteuern?



kif
13.01.2011, 21:47
Hey,

ich habe ein kleine Atmega8 Platine, mit der ich schon erfolgreich LEDs angesteuert habe.

Nun möchte ich einen Servo ansteuern, jedoch klappt das nicht!

Der Servo wird seperat mit 6V betrieben. Die Massen von Servoversorgung und Atmega8-Versorgung hab ich verknüpft.

Der Signaleingang des Servo hängt an PORTC.0.

Das Programm sieht so aus:
Ich habe es von der Seite
http://mikrocontroller.jacob-pirna.de/myavr_modellbau_servo_bascom.html

und habe die Ports auf meine Platine angepasst.


' Taktfrequenz des Quarzes einstellen (3,686411 MHz -> 1 Takt=0,00000027127s=0,27127ys)
$crystal = 3686411
' Verwendete CPU festlegen (ATmega8)
$regfile = "m8def.dat"
' alle Pin's an Port C als Ausgang festlegen
Config Portc = Output
' alle Pin's an Port B als Eingang festlegen
Config Portd = Input
' Interne Pullup Widerstände setzten für Taster Pin 0 & 1
Portd = &H03

' 65536-56320 = 9216*0.27127us = 2,5ms * 8(Vorteiler) = 20ms
Const Reload = 56320
' 1 Timertakt = 2,17us
Config Timer1 = Timer , Prescale = 8
Timer1 = Reload
On Timer1 Timer1_isr
Enable Timer1
Enable Interrupts

Dim Winkel As Word
Winkel = 700

' Hauptprogrammschleife
Do
If Pind.6 = 0 Then
' ist Schalter an Pin 2 Port D gedrückt
If Winkel > 300 Then Winkel = Winkel - 10 ' 0,65 ms
Elseif Pind.7 = 0 Then
' ist Schalter an Pin 3 Port D gedrückt
If Winkel < 1100 Then Winkel = Winkel + 10 ' 2,38 ms
End If
Waitms 2
Loop

End

Timer1_isr:
If Pinc.0 = 1 Then
' Pause ca. 20 ms
Portc.0 = 0
Timer1 = Reload
Else
' Impuls 0ms bis 2ms
Portc.0 = 1
Timer1 = 65536 - Winkel
End If
Return


Aber leider funktioniert es nicht. Der Servo steuert immer bis fast ganz nach links. Auch wenn ich den Startwert für "Winkel" ändere, dreht er sich bis fast ganz nach links.

Hat jemand eine Idee wo der Fehler liegen könnte?
Wäre nett wenn mir jemand helfen könnte.

Mfg kif

TobiKa
13.01.2011, 22:17
Wozu so kompliziert? Bascom bringt doch schon alles mit: http://www.rn-wissen.de/index.php/Servoansteuerung

kif
14.01.2011, 15:08
Hab jetzt das Programm versucht:

$regfile "m8def.dat"
$baud = 19200
$crystal = 16000000
$framesize = 64
$swstack = 64
$hwstack = 64
Config Timer1 = Timer , Prescale = 8 'timer für servos
Enable Timer1
Timer1 = 62535
Config Portb = Output
Config Portc = Output
Portb.0 = 0 'hier hängt servo1
Portb.1 = 0 'hier hängt servo2
Portb.2 = 0 'hier hängt servo3
Portb.3 = 0 'hier hängt servo4

On Timer1 Servoirq 'servo

Enable Interrupts

Dim Kanal As Byte
Dim Servo(4) As Word 'min: 61535, mitte 62535, max 63535 = 2000 schritte

Do
Servo(1) = 63535 'Mitte
Servo(2) = 63535 'Mitte
Servo(3) = 63535 'Mitte
Servo(4) = 63535 'Mitte
Loop

Servoirq:
If Kanal = 0 Then
If Portc.0 = 0 Then 'wenn port low
Timer1 = Servo(1) 'dann timer auf entsprechende verzögerung
Portc.0 = 1 'und port anschalten
Else 'das hier passiert erst bei dem darauf folgenden interrupt
Portc.0 = 0 'dann port wieder ausschalten
Incr Kanal 'und den nächsten kanal bearbeiten
End If
End If
If Kanal = 1 Then
If Portb.1 = 0 Then
Timer1 = Servo(2)
Portb.1 = 1
Else
Portb.1 = 0
Incr Kanal
End If
End If
If Kanal = 2 Then
If Portb.2 = 0 Then
Timer1 = Servo(3)
Portb.2 = 1
Else
Portb.2 = 0
Incr Kanal
End If
End If
If Kanal = 3 Then
If Portb.3 = 0 Then
Timer1 = Servo(4)
Portb.3 = 1
Else
Portb.3 = 0
Incr Kanal
End If
End If

If Kanal = 4 Then
Timer1 = 40000 'eine pause von ca. 12ms bis zum nächsten interrupt. Bei guten Servos oder Brushlessreglern kann man hier bis auf 65530 gehen ==> ansteuerfrequenz von ~ 200Hz
Kanal = 0
End If
Return
End


Doch wieder steuert des Servo ganz nach links, nur diesmal in sehr kleinen SChritten. Bei dem Startwert 62535 steuert er auch ganz nach links, sowie bei dem Wert 61535.

Jaecko
15.01.2011, 00:26
Passt denn die $Crystal-Angabe zur tatsächlichen Controller-Frequenz?
Einmal heissts 16MHz, beim anderen 3,nochwas.

kif
15.01.2011, 19:58
Was heißt tatsächliche Controller-Frequenz?
Der Atmega hat ja einen Frequenzbereich bis zu 16Mhz.
Wird diese durch den Befehl $Crystal festgelegt oder muss ich die iwo anderst ändern?

Jaecko
15.01.2011, 21:12
Ok, erklärt, dass es nicht geht *g*.

Ein jungfräulicher AVR hat eine Standardfrequenz von 1 MHz.
Mit $Crystal sagst du nur dem Programm, mit welcher Frequenz der AVR läuft, damit im Programm Warteschleifen etc. richtig berechnet werden.
Wenn die echte Frequenz 1MHz ist, im Programm aber 16MHz angegeben sind, dann laufen UART/Warteschleifen/etc. um Faktor 16 zu langsam.

Ohne zusätzlichen Quarz kann ein Mega8 mit 1, 2, 4, und 8 MHz laufen. Mit externem Quarz geht "jede" Frequenz, die der Quarz vorgibt.

Wenn du also 16MHz haben willst, muss ein ext. Quarz mit 16MHz dranhängen und in den Fuses aktiviert sein.

Wichtig in jedem Fall: $crystal und der tatsächliche Wert müssen zusammenpassen. Servo ansteuern sollte auch mit den ursprünglichen 1MHz gehen.

kif
16.01.2011, 12:01
Ok Danke, obwohl das mein Problem nicht direkt löst, ist mir schon viel geholfen.

Also ohne Quarz funktionieren nur 1, 2, 4 oder 8Mhz, hab ich das richtig verstanden also 1,5Mhz geht nicht?

Also einen Quarz hätt ich noch, nur noch nicht angeschlossen weil ich nicht genau weiß wie und weil ja bis jetzt alles auch ohne funktioniert hat.

Und wie genau kann ich jetzt z.b. 2Mhz einstellen (ohne Quarz). Sorry wenn das jetzt vllt eine dumme Frage ist, aber ich kenn mich halt net so aus.

Danke schonmal für die Hilfe, zu wissen wo der Fehler ist, ist schon mal gut und erspart mir viel Ärger und Aufregung.

hardware.bas
16.01.2011, 12:09
Ohne Quarz ist mit bis ca. 2% Ungenauigkeit zu rechnen.
Im AVR-Buch von R.Walter steht beschrieben, wie man diesen
internen Osc. kalibrieren kann. So genau, wie mit dem Quarz
wirds jedoch nicht und den Temperaturkoeffizient kriegt man
dabei auch nicht weg. Wenn Du die UART unbedingt nutzen musst,
nimm diesen Quarz - den Wert hast Du ja schon dimensioniert - und
2 Cs mit 22pF und fuse den AVR entsprechend um, denn die UART
braucht die Genauigkeit.
Wenn nicht, gehts sicherlich auch mit 1MHz freilaufend. VG Micha

kif
16.01.2011, 12:27
Nein UART brauch ich nicht. Ich will nur einen Servo (später drei) ansteuern.
Was heißt nun fuse den AVR um?
Ich versuchs aufjedenfall mal mit 1Mhz.

Edit: Bevor ich Bascom-AVR öffne erscheint immer der Tipp des Tages.
Da steht nun das ich mit $Crystal die Frequenz nicht ändern kann!
Das hätte können auch früher da stehen!

hardware.bas
16.01.2011, 16:38
Na dann .... brauchst Du ihn NICHT umzufusen, bzw. die
Werkseinstellungen der Fusebits SO LASSEN! VG Micha

kif
16.01.2011, 17:25
Jop, habs jetzt mit der 1Mhz Taktfrequenz probiert.

Und alles hat geklappt.

Fals es jemand interessiert, hier ist das Programm.

$regfile "m8def.dat"
$crystal = 1000000

Dim Winkel As Word
Const Reload = 63036
Winkel = 189

Config Portc.0 = Output
Config Portd.6 = Input
Config Portd.7 = Input


Portd.6 = 1
Portd.7 = 1


Config Timer1 = Timer , Prescale = 8
Timer1 = Reload

Enable Timer1
Enable Interrupts

On Timer1 Timerinterrupt


Do
If Pind.6 = 0 Then
If Winkel < 300 Then Incr Winkel
Waitms 20
End If



If Pind.7 = 0 Then
If Winkel > 75 Then Decr Winkel
Waitms 20
End If
Loop

Timerinterrupt:

If Pinc.0 = 1 Then
Portc.0 = 0
Timer1 = Reload + Winkel
Else
Portc.0 = 1
Timer1 = 65536 - Winkel
End If

Return

Zwar ohne Kommentare, aber das Programm ist ja noch überschaubar.

Also danke für die schnelle Hilfe.

Mfg Kif