- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 4 von 4

Thema: Schnelle Ansteuerung für 4 Servos ohne "Servo"-Bef

Baum-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Roboter Genie Avatar von Willa
    Registriert seit
    26.10.2006
    Ort
    Bremen
    Alter
    44
    Beiträge
    1.273

    Schnelle Ansteuerung für 4 Servos ohne "Servo"-Bef

    Hi!
    Ich möchte gerne 4 Servos schnell ansteuern (mit vielleicht 100 bis 200 Hz). Im Anhang findet Ihr ein Bild mit dem angedachten Aufbau. Die Framezeit scheint total unkritisch zu sein. Mein Programm funktioniert anscheinend wunderbar, allerdings frage ich mich wie effizient mein Code wohl ist...
    Hier mal mein Bascom Code:
    Code:
    $regfile = "m32def.dat"
    $framesize = 32
    $swstack = 32
    $hwstack = 64
    $crystal = 16000000
    $baud = 9600
    
    Config Timer0 = Timer , Prescale = 64             'je höher prescale desto resourcenschonender?
    On Timer0 Timer_irq
    Dim Servo1time As Byte                            'servo1 high-time
    Dim Servo2time As Byte                            'servo2 high-time
    Dim Servo3time As Byte                            'servo3 high-time
    Dim Servo4time As Byte                            'servo4 high-time
    Dim Kanal As Byte                                 'Kanal 1-4
    Dim I As Byte
    Dim Timeraufnull As Bit                           'Timer Zurücksetzer
    
    
    Enable Timer0
    Enable Interrupts
    Config Portb = 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
    
    Kanal = 1
    Timeraufnull = 0
    Servo1time = 131                                  'Preload 131 = 2000Hz = 0.5ms pulse
    Servo2time = 131
    Servo3time = 131
    Servo4time = 131
    
    
    
    Do
       '----- Das ist nur Code um Servos zu bewegen --> unwichtig
       For I = 0 To 255
          'Servo1
          Servo1time = I
          Waitms 50                                   'bisschen warten damit servo auch position erreichen kann
    
          'Servo2
          If I < 163 Then
             Servo2time = I + 20
             Else
             Servo2time = 131
          End If
    
          'Servo3
          If I < 170 Then
             Servo3time = 301 - I
             Else
             Servo3time = 150
          End If
    
          'Servo4
          If I < 140 Then
             Servo4time = I
             Else
             Servo4time = 170
          End If
       Next I
    Loop
    End
    
    
    
    Timer_irq:
    
    If Kanal = 1 Then
       If Portb.0 = 0 Then                            'wenn port low...
          Timer0 = Servo1time                         'dann timer auf gewünschte länge...
          Portb.0 = 1                                 'und port auf high
       Else                                           'portb.0 = 1
          If Timeraufnull = 1 Then                    'port erst wieder auf low wenn der timer
             Portb.0 = 0                              'servo1time gelaufen ist UND einmal zurückgesetzt wurde.
             Incr Kanal                               'das ergibt dann: 0 bis 1ms + 1ms = 1 bis 2ms high
             Timeraufnull = 0
          Else                                        'TimerAufNull=0
             Timeraufnull = 1
             Timer0 = 6                               'ergibt 1ms bis zum erneuten überlauf
          End If
       End If
    End If
    
    'und hier das gleiche für die anderen kanäle...
    If Kanal = 2 Then
       If Portb.1 = 0 Then
          Timer0 = Servo2time
          Portb.1 = 1
       Else
          If Timeraufnull = 1 Then
             Portb.1 = 0
             Incr Kanal
             Timeraufnull = 0
          Else
          Timeraufnull = 1
          Timer0 = 6
          End If
       End If
    End If
    
    If Kanal = 3 Then
       If Portb.2 = 0 Then
          Timer0 = Servo3time
          Portb.2 = 1
       Else
          If Timeraufnull = 1 Then
             Portb.2 = 0
             Incr Kanal
             Timeraufnull = 0
          Else
          Timeraufnull = 1
          Timer0 = 6
          End If
       End If
    End If
    
    If Kanal = 4 Then
       If Portb.3 = 0 Then
          Timer0 = Servo4time
          Portb.3 = 1
       Else
          If Timeraufnull = 1 Then
             Portb.3 = 0
             Incr Kanal
             Timeraufnull = 0
          Else
          Timeraufnull = 1
          Timer0 = 6
          End If
       End If
    End If
    
    
    
    
    If Kanal > 4 Then
        Kanal = 1
    End If
    Return


    Ablauf:
    Kanal = 1 und Portb.0 ist aus. Der Preload des Timers wird auf die gewünschte Länge gesetzt , z.b. 152 = 2400Hz = 0,416ms. Der Port wird angeschaltet, der Rest des Timer_irq wird nicht ausgeführt.
    Nach 0,416ms wird erneut in Timer_irq gesprungen. Nun wird die Variable "Timeraufnull" auf "1" gesetzt, und der Preload des Timers auf 6 = 1000Hz = 1ms gesetzt. Timer_irq wird wieder verlassen.
    Nach 1,416ms wird nochmal ins Timer_irq gesprungen. Jetzt wird Portb.0 ausgeschaltet, die Kanalnummer um eins erhöht und "Timeraufnull" wieder auf 0 gesetzt. Noch während dieses Interrupts wird das ganze für Servo2 eingeleitet usw....


    Meine Fragen:

    Es gibt 8 Interrupts von Timer0 um alle Servos zu stellen. Ist das gut so, oder nimmt man besser Timer1 mit Prescale=1?? Das ergäbe auch ne gute Auflösung, außerdem nur 4 Interrupts um 4 Servos zu stellen. Aber der Prescale wäre nur 1, und das ist doch ungünstig?

    Wie stelle ich Performance des Programms fest? Im Simulator steht was von Cycles und "mS", kann man das benutzen um zu errechnen wie schnell ein Programm läuft?

    In Zukunft soll das Programm auf einem ATmega644 mit 20 MHz laufen. Dann ist die maximale Pulslänge den ich mit Prescale=64 erreichen kann 0,8159ms und nicht mehr 1,019 ms. D.h. ich komme nicht mehr auf 2 ms wenn ich zwei Interrupts zusammenzähle, sondern nur noch auf ca. 1,632 ms. Das reicht nicht für den Vollausschlag eines Servos... Was tun? Evtl drei Interrupts zusammenhängen? Das wird aber ungleich komplizierter....

    Wenn mir jemand ein bisschen weiterhelfen könnte wäre das fantastisch....!
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken servoansteuerung.ai.jpg  
    Viele Grüße, William
    -> http://william.thielicke.org/

Berechtigungen

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

Solar Speicher und Akkus Tests