-         
Ergebnis 1 bis 3 von 3

Thema: Servo zuckelt bei timer1_irq aber nicht bei waitms ...

  1. #1
    Erfahrener Benutzer Roboter Genie Avatar von Willa
    Registriert seit
    26.10.2006
    Ort
    Bremen
    Alter
    38
    Beiträge
    1.269

    Servo zuckelt bei timer1_irq aber nicht bei waitms ...

    Anzeige

    Hi!
    Ich bin ganz neu in der Materie und habe ein Problem: Ein Servo soll per Sinus angesteuert werden. Es ist ein Futaba s9253 (mit das schnellste was es gibt) angeschlossen am RN-Control v1.4.
    Das ganze soll später eine Art Schlagflugroboter ansteuern, dessen Aerodynamik dann vermessen wird. Deswegen ist präzision hier einigermaßen wichtig.
    Hier erstmal der Quellcode der nicht richtig funktioniert:
    Code:
    $regfile = "m32def.dat"
    $framesize = 32
    $swstack = 32
    $hwstack = 32
    
     $crystal = 16000000
     $baud = 9600
    
    
    
    Config Servos = 1 , Servo1 = Portb.3 , Reload = 10
    Config Portb = Output
    
    
    Config Timer1 = Timer , Prescale = 8
    On Timer1 Timer_irq
    Enable Interrupts
    Enable Timer1
    
    Dim I As Integer
    Dim J As Single
    Dim X As Single
    Dim Sinx As Single
    Dim Erst As Single
    Dim Zweit As Single
    Dim Dritt As Integer
    Dim Vorerst As Single
    Const Pi = 3.14159265358979
    Const 2pi = 6.28318530717958
    
    
    For I = 500 To 300 Step -10                                 'sound PORTD.7 , Länge , Frequenz
    Sound Portd.7 , 10 , I
    Next I
    Waitms 180
    For I = 500 To 300 Step -10
    Sound Portd.7 , 10 , I
    Next I
    For I = 300 To 500 Step 5
    Sound Portd.7 , 12 , I
    Next I
    
    
    J = 0.02 * Pi
    
    Do
       Sinx = Sin(x)                                            'X wird im Timer_irq immer um "J" erhöht
       Vorerst = Sinx + 1                                       'die variable "Vorerst" schwankt sinusförmig zwischen o und 2
       Erst = Vorerst * 50                                      'Hochskalieren der Werte, so dass sie zw. 60 und 160 sinusförmig schwanken
       Zweit = Erst + 60
       Dritt = Round(zweit)                                     'und nochmal runden, man weiss ja nie...
       Servo(1) = Dritt                                         'servo 1 und servo 2 stellen
      'Print Servo(1)
       'Delay                                                    'ins terminal schreiben welche werte die Servos haben
    Loop
    
    Timer_irq:                                                  'hat eine Frequenz von 31Hz
       Timer1 = 1020
       If X < 2pi Then                                          'x wird um J erhöht solange x kleiner als 2 Pi, ansonsten x = 0
             X = X + J
          Else
             X = 0
       End If
    Return
    Der timer_irq schlägt mit 31 Hz zu und erhöht eine Variable X immer ein bischen, dann wird sinus X ausgerechnet und an das Servo gesendet. Dabei passiert aber folgendes (Video):

    http://www.youtube.com/watch?v=yEjPdcdpZC4

    DSas servo folgt zwar prinzipiell dem Sinus, zuckelt aber öfters mal auf irgendwelche undefinierten positionen und macht dann wieder weiter. Das sieht man auch im Terminal wenn man Servo(1) printed. Zwischendurch stehen da mal ganz wilde Zeichenkombinationen oder falsche zahlen.

    Folgender Code funktioniert. dort wird die Variable X einfach im Main-Loop erhöht, danach gibts immer 2ms pause damit das ganze nicht zu schnell läuft.

    Im Schlagflugroboter muss das servo aber am ende mit einer bestimmten frequenz laufen. Außerdem bewegt es sich dann nicht mehr per einfacher sinusfunktion sondern bewegt sich etwas komplizierter. Und wenn ich das ohne Timer1 mache, dann habe ich doch keine garantie mehr dafür dass das servo mit der richtigen geschwindigkeit läuft? Bzw. wann das Servo wie schnell läuft hängt dann davon ab wie schnell der AtMega32 die funktionen berechnen kann, oder?

    Also hier der funktionierende Code ohne timer1_irq
    Code:
    $regfile = "m32def.dat"
    $framesize = 32
    $swstack = 32
    $hwstack = 32
    
     $crystal = 16000000
     $baud = 9600
    
    
    
    Config Servos = 1 , Servo1 = Portb.3 , Reload = 10
    Config Portb = Output
    
    
    'Config Timer1 = Timer , Prescale = 8
    'On Timer1 Timer_irq
    Enable Interrupts
    'Enable Timer1
    
    Dim I As Integer
    Dim J As Single
    Dim X As Single
    Dim Sinx As Single
    Dim Erst As Single
    Dim Zweit As Single
    Dim Dritt As Integer
    Dim Vorerst As Single
    Const Pi = 3.14159265358979
    Const 2pi = 6.28318530717958
    
    
    For I = 500 To 300 Step -10                                 'sound PORTD.7 , Länge , Frequenz
    Sound Portd.7 , 10 , I
    Next I
    Waitms 180
    For I = 500 To 300 Step -10
    Sound Portd.7 , 10 , I
    Next I
    For I = 300 To 500 Step 5
    Sound Portd.7 , 12 , I
    Next I
    
    
    J = 0.002 * Pi
    
    Do
       Sinx = Sin(x)                                            'X wird im Timer_irq immer um "J" erhöht
       Vorerst = Sinx + 1                                       'die variable "Vorerst" schwankt sinusförmig zwischen o und 2
       Erst = Vorerst * 50                                      'Hochskalieren der Werte, so dass sie zw. 60 und 160 sinusförmig schwanken
       Zweit = Erst + 60
       Dritt = Round(zweit)                                     'und nochmal runden, man weiss ja nie...
       Servo(1) = Dritt                                         'servo 1 und servo 2 stellen
      'Print Servo(1)
       'Delay                                                    'ins terminal schreiben welche werte die Servos haben
    
    
    If X < 2pi Then                                             'x wird um J erhöht solange x kleiner als 2 Pi, ansonsten x = 0
             X = X + J
          Else
             X = 0
       End If
    
    Waitms 2
    
    Loop
    Und hier das Video, das Servo läuft schön regelmässig:

    http://www.youtube.com/watch?v=Wcj16WOxGcg

    Meine Frage daher: Was kann ich machen damit im timer_irq quasi die "Zeitvariable" hochzählt und im Hauptprogramm mit dieser Variablen eine Funktion ausgerechnet wird? Und diese Funktion sollte ein Servo ansteuern OHNE dass das so komisch durch die Gegend zuckelt.... Für eure Hilfe wäre ich sehr dankbar!
    Viele Grüße,
    William

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    26.03.2006
    Ort
    WOB
    Beiträge
    630
    Ich vermute mal spontan, das durch irgendwas ein Interrupt ausgelöst wird und du deswegen sporadische Fehlwerte hast. Überprüf das mal
    Gruß Thomas \/

    Alles über AVR, PIC und CAN
    blog.cc-robotics.de

  3. #3
    Erfahrener Benutzer Roboter Genie Avatar von Willa
    Registriert seit
    26.10.2006
    Ort
    Bremen
    Alter
    38
    Beiträge
    1.269
    ich habe das Problem gelöst indem ich $hwstack = 64 statt 32 groß gemacht habe.
    Außerdem muss der timer_irq jetzt nur noch rechnen:
    x=x+1
    und x ist als byte deklariert. anscheinend kommt der at32 besser mit solchen zahlen zurecht. Im Forum "Vorstellungen+Bilder von fertigen Projekten/Bots" werde ich gleich ein Thread mit Video zum fertigen "Roboter" erstellen...
    Viele Grüße,
    William

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •