PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ??? Interrupt für Servos erzeugen ???



Typer
07.11.2010, 11:15
Hi,
mein plan ist es ein Quadpot zu bauen. Hab nun mal ein bein gebaut um zu testen wie das so wird.

Nun mein Problem....
In dem Bein sind 3 Servos verbaut, diese werden von einem atmega168 angesteuert.

Zum testen habe ich mal folgenden code verwendet


$regfile = "M168Pdef.dat" 'es handelt sich um einen ATmega168P
$crystal = 3686400 'der eingebauter RC-Oszillator läuft mit 3,6864 Mhz
$hwstack = 100 'im Speicher werden für den Hardware-Stack 100 Byte reserviert
$swstack = 100 'im Speicher werden für den Software-Stack 100 Byte reserviert
$framesize = 100 'im Speicher werden für den Frame 100 Byte reserviert
$baud = 19200

'Taster
S1 Alias Pind.2 'Taster1 an D.2
S2 Alias Pind.3 'Taster2 an D.3
S3 Alias Pind.4
Config Portd = Input 'Port D = input
Portd.2 = 1 'Pullup
Portd.3 = 1 'Pullup
Portd.4 = 1


'Servos
'Servo von 32 - 82
Config Servos = 3 , Servo1 = Portb.0 , Servo2 = Portb.1 , Servo3 = Portb.2 , Reload = 10
Config Portb = Output


Declare Sub Hoch
Declare Sub Runter
Declare Sub Mitte

Enable Interrupts

Dim X1 As Byte , X2 As Byte , X3 As Byte

X1 = 57
X2 = 57
X3 = 57

Servo(1) = X1
Servo(2) = X2
Servo(3) = X3

Bitwait S1 , Reset
Bitwait S1 , Set


Do

'Bitwait S1 , Set

If S1 = 0 Then Call Hoch
If S2 = 0 Then Call Mitte
If S3 = 0 Then Call Runter

Print "Servo1 = " ; Servo(1)
Print "Servo2 = " ; Servo(2)
Print "Servo3 = " ; Servo(3)
Waitms 50

Loop

End 'Ende des Programms




Sub Hoch
Servo(1) = 80
Servo(2) = 80
End Sub

Sub Mitte
Servo(1) = 57
Servo(2) = 57
End Sub

Sub Runter
Servo(1) = 35
Servo(2) = 35
End Sub


Config Servos = 1 , Servo1 = Portb.0 , Reload = 10
so gehts!

aber bei 3 Servos
Config Servos = 3 , Servo1 = Portb.0 , Servo2 = Portb.1 , Servo3 = Portb.2 , Reload = 10

fangen die Servos nach der bewegung an zu ruckeln.

Also habe ich versucht einen Interrupt über timer1 zu steuern
wie hier: http://www.rn-wissen.de/index.php/Servoansteuerung
(Anpassung der Frequenz mit rnAvr rechner)

jedoch zeigen die servos keine regung

wie kann ich herausfinden warum das nicht geht?
bzw kann mir jemand erläutern wie ein interrupt aussieht der nur einen servo ein paar cm in eine richtung und dann wieder zurück bewegt?!

Typer
07.11.2010, 15:24
Ok,
problem gelöst....

So gehts:


$regfile = "M168Pdef.dat" 'es handelt sich um einen ATmega168P
$crystal = 3686400 'der eingebauter RC-Oszillator läuft mit 3,6864 Mhz
$hwstack = 100 'im Speicher werden für den Hardware-Stack 100 Byte reserviert
$swstack = 100 'im Speicher werden für den Software-Stack 100 Byte reserviert
$framesize = 100 'im Speicher werden für den Frame 100 Byte reserviert
$baud = 19200


'Taster
S1 Alias Pind.2 'Taster1 an D.2
S2 Alias Pind.3 'Taster2 an D.3
S3 Alias Pind.4
Config Portd = Input 'Port D = input
Portd.2 = 1 'Pullup
Portd.3 = 1 'Pullup
Portd.4 = 1



'Hier wird der Timer und der Teiler festgelegt
Config Timer1 = Timer, Prescale = 8

'Servo 1-3
Config Portb.0 = Output
Config Portb.1 = Output
Config Portb.2 = Output

Servo1 Alias Portb.0
Servo2 Alias Portb.1
Servo3 Alias Portb.2

Servo1 = 0
Servo2 = 0
Servo3 = 0



On Timer1 Timer_irq


Declare Sub Hoch
Declare Sub Mitte
Declare Sub Runter



Dim Serv1 As Word
Dim Serv2 As Word


Dim Kanal As Byte


Kanal = 0
Serv1 = 57500
Serv2 = 57500


'Hier werden die Timer aktiviert
Enable Timer1
Enable Interrupts


'Hier ist die Programmhauptschleife
Do

If S1 = 0 Then Call Hoch
If S2 = 0 Then Call Mitte
If S3 = 0 Then Call Runter


Loop

Timer_irq:

If Kanal = 0 Then
If Servo1 = 0 Then
Timer1 = Serv1
Servo1 = 1
Else
Servo1 = 0
Incr Kanal
End If
End If
If Kanal = 1 Then
If Servo2 = 0 Then
Timer1 = Serv2
Servo2 = 1
Else
Servo2 = 0
Incr Kanal
End If
End If

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


Return

End

Sub Hoch
Serv1 = 57170
Serv2 = 57040
End Sub


Sub Mitte
Serv1 = 57340
Serv2 = 57225
End Sub

Sub Runter
Serv1 = 57750
Serv2 = 57630
End Sub

bei Anregungen oder Verbesserungsvorschlägen bitte hier antworten...

PicNick
07.11.2010, 15:31
Die Werte für Servo sollten bei 100 (1 mS) -200 (2 mS) liegen.
Du verwendest < 100, vielleicht macht ihn das nervös.

http://www.rn-wissen.de/index.php/Bascom_Inside-Code#SERVO