PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : RN-Beitrag Servoansteuerung und Atmega8 Probleme?



erik_wolfram
24.03.2010, 20:37
Hallo,
habe folgendes Problem:
ich habe mir erfolgreich eine Platine samt Programmer für einen Atmega 8 gefertigt und wollte darüber 4 Servos ansteuern. Dann bin ich prompt auf den RN Beitrag gestoßen und wollte das Script testen.
Doch leider funktioniert das Ganze nicht so wie es soll - die Servos bewegen sich zwar, dies aber nur in kurzen ruckligen Schritten (wenn überhaupt). Habe schon mit dievrsen anderen wartezeiten für die Timer probiert doch alles erfolglos. Auch das Umschreiben des Scriptes für nur einen Servo hat mir nix gebracht...

Verwenden tue ich:
einen Atmega 8PU
einen NimH-Akku mit 4,8V (Spannung konstant -> gemessen)
C* Standard Servo (Billigteil)

Kann das eventuell am Atmega8 liegen (die Werte im Kopf des scriptes habe ich angepasst)? Leider konnte ich laut Datenblatt keine relevanten Unterschiede feststellen...

MFg Erik

radbruch
24.03.2010, 20:45
Hallo

Es gibt im RN-Wissen mehrere Servoprogramme. Zeig uns doch einfach deine Version mit den geänderten Kopfdaten, dann müssen wir nicht lange suchen und raten.

Tipp aus der Hüfte: Mit dem Kontrollertakt stimmt etwas nicht. Bei interener Taktquelle Vorteiler /8 aktiv, dann ist der Takt nur 1MHz anstatt 8MHz. Oder bei externer Taktquelle Fuses auf intern gesetzt.

Gruß

mic

erik_wolfram
24.03.2010, 20:48
okok, hier der Code:



$regfile "m8def.dat"
$crystal = 16000000
$framesize = 24
$swstack = 8
$hwstack = 32
Config Timer1 = Timer , Prescale = 8 'timer für servos
Enable Timer1
Timer1 = 62535

Config Portc = Output
Portc.5 = 0 'hier hängt servo1
Portc.4 = 0 'hier hängt servo2
Portc.3 = 0 'hier hängt servo3
Portc.2 = 0 'hier hängt servo4

Config Portb.1 = Output
Config Portb.2 = Output
Portb.1 = 1
Portb.2 = 0


On Timer1 Servoirq 'servo

Enable Interrupts

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


Waitms 100
Portb.2 = 1
Portb.1 = 0

Do
Servo(1) = 63535

Servo(2) = 61535 'Mitte
Servo(3) = 62535 'Mitte
Servo(4) = 62535 'Mitte
Loop

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

If Kanal = 1 Then
If Portc.4 = 0 Then
Timer1 = Servo(2)
Portc.4 = 1
Else
Portc.4 = 0
Incr Kanal
End If
End If

If Kanal = 2 Then
If Portc.3 = 0 Then
Timer1 = Servo(3)
Portc.3 = 1
Else
Portc.3 = 0
Incr Kanal
End If
End If

If Kanal = 3 Then
If Portc.2 = 0 Then
Timer1 = Servo(4)
Portc.2 = 1
Else
Portc.2 = 0
Incr Kanal
End If
End If

If Kanal = 4 Then
Timer1 = 40000
Kanal = 0
End If

Return
End

radbruch
24.03.2010, 21:31
Hallo

Oje, "Bascom" hatte ich völlig überlesen. Und da bin ich eher Laie ;) Ich versuche es aber trotzdem mal:

Config Portc = Output
PC6 ist der Reset-Pin. Möglicherweise ein Problem.

Dim Kanal As Byte
Wird Kanal dann auch zu Null? Bei jedem Startwert der nicht 1, 2, 3 oder 4 ist würde die ISR nicht funktionieren.

Timer1 = 40000
Die Impulse sollten alle 20ms wiederholt werden. Das wären 25535+Servo(1)+Servo(2)+Servo(3) für Timer1 bei Servo(4).

Aber ich glaube nicht wirklich, dass hier ein Treffer dabei ist.

Gruß

mic

Sauerbruch
24.03.2010, 22:37
(die Werte im Kopf des scriptes habe ich angepasst)

Das ist sehr löblich, aber wenn Dein Controller mit irgeneiner anderen Frequenz als 16 MHz läuft, ist es damit nicht getan!

Die Werte 61535 für minimalen Ausschlag und 63535 für maximalen Ausschlag ergeben sich ja aus der Taktfrequenz des Timer1 (2 MHz, da Prescaler = 8 ) und der Zeit, die er bis zum Überlauf braucht (1 bzw. 2 ms).

Wenn Du den Mega8 also mit einem anderen Takt fährst, müsstest Du diese Werte für Servo(x) entweder neu berechnen - oder uns den Takt verraten, dann können wir sicherlich helfen :-)

Richard
25.03.2010, 04:56
Moin moin.

Warum so Kompliziert? Bascom hat dafür einen Befehl und
der klappt super!



'Servo's need a pulse in order to operate
'with the config statement CONFIG SERVOS we can specify how many servo's we
'will use and which port pins are used
'A maximum of 16 servos might be used
'The SERVO statements use one byte for an interrupt counter and the TIMER0
'This means that you can not use TIMER0 anymore
'The reload value specifies the interval of the timer in uS
'Config Servos = 2 , Servo1 = Portb.0 , Servo2 = Portb.1 , Reload = 10
$regfile = "2313def.dat"

Config Servos = 1 , Servo1 = Portb.0 , Reload = 10
'as an option you can use TIMER1
'Config Servos = 2 , Servo1 = Portb.0 , Servo2 = Portb.1 , Reload = 10 , Timer = Timer1


'we use 2 servos with 10 uS resolution(steps)

'we must configure the port pins used to act as output
Config Portb = Output

'finally we must turn on the global interrupt
Enable Interrupts

'the servo() array is created automatic. You can used it to set the
'time the servo must be on
Servo(1) = 10 '10 times 10 = 100 uS on
'Servo(2) = 20 '20 times 10 = 200 uS on
Do
Loop

Dim I As Byte
Do
For I = 0 To 100
Servo(1) = I
Waitms 1000
Next

For I = 100 To 0 Step -1
' Servo(1) = I
Waitms 1000
Next
Loop
End


Gruß Richard

Willa
25.03.2010, 14:38
Hi,
ja der Bascom interne Befehl geht gut wenn die Servos sich nur "irgendwie" bewegen sollen (das reicht wohl für 95% der Anwendungen). Wenns präziser und mit höherer zeitlichen Auflösung laufen sol ist der oben genannt Code schon geeigneter.
Mit welcher Frequenz läuft denn nun dein Mega8...?

erik_wolfram
25.03.2010, 15:59
sehe ich das falsch, dass mit
"crystal = 16000000" die Interne Frequenz gesetzt wird?
(Mit den Berechnungen ist mir mitlerweile alles klar)

Von Extern hätte ich noch einen Quarz mit 16Mhz zur Verfügung, wollte jedoch für die ersten Test erstmal so probieren.

Wollte den internen Befehl erstmal lassen und es selbst versuchen, aber vlt. kann ich es erstmal so probieren...


[edit]
Ich muss mich wohl bei euch entschuldigen, ich habe verpeilt, dass die interne Frequenz auf 1Mhz festgelegt ist! Habe das Script dementsprechend umgeschrieben und alles läuft flüssig!

Willa
25.03.2010, 16:26
"crystal = 16000000" sagt deinem Programm was du in den Fuses für eine Frequenz eingestellt hast. Wenn das nicht identisch ist kommt Murks raus. Standardmässig läuft ein Mega8 glaube ich auf 1MHz.

erik_wolfram
25.03.2010, 18:18
Ja danke - also die interne Frequenz ist wirklich 1Mhz - damit läuft alles bestens - habe jetzt 4 Servos ohne Probleme zu laufen gehabt.
Leider bin ich noch in totaler Anfänger und hab hier und da Wissenslücken!

021aet04
25.03.2010, 18:38
Wenn es jetzt funktioniert, dann passt es. Ich würde den µC auf 8Mhz oder mit externen Quarz laufen lassen. Dazu musst du die Fusebits umstellen. Wie das in Bascom funktioniert weiß ich aber nicht.
Stelle nichts um, wenn du nicht weißt für was das ist. Im schlimmsten Fall kannst du den µC nicht mehr programmieren.

MfG Hannes

erik_wolfram
25.03.2010, 18:50
Deshalb habe ich es erstmal gelassen - auf dem Board habe ich aber einen Quarz mit 16Mhz - da aber erstmal so alles funktioniert werde ich den noch nicht aktivieren.
In Bascom aber eine Kleinigkeit! (Häkchen setzten)

[EDIT]
Kann es eigentlich Probleme mit Quarzen geben? Ich habe einen mit 16Mhz und den laut Datenblatt empfohlenen 18pF Kondensatoren - nur leider viel Neues jetzt mit den Controllern und ich habe angst meinen zu "töten" da ich nur diesen einen hab...

Mein Roboter funktioniert auch soweit, doch leider kostet die geringe Auflösung der Ansteuerung über 1Mhz, Prescale 64 und 8Bit Timer viel Genauigkeit (und damit mögliche Geschwindigkeit)!