-         

Ergebnis 1 bis 4 von 4

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

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

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

    Anzeige

    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/

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    13.07.2004
    Ort
    bei Stuttgart
    Alter
    35
    Beiträge
    760
    hi,
    also eine servo ansteuerung mit 100hz macht meiner meinung nach keinen sinn, weil ein servo signal 20ms dauert, also kannst du auch nur alle 20 ms eine neue position vorgen, sprich du schaffst maximal 50 hz.
    mfg jeffrey

  3. #3
    Erfahrener Benutzer Roboter Genie Avatar von Willa
    Registriert seit
    26.10.2006
    Ort
    Bremen
    Alter
    37
    Beiträge
    1.269
    Hi!
    Das ist die allgemein anerkannte Meinung, allerdings stimmt das anscheinend nicht. Wenigstens akzeptieren meine Servos (3 unterschiedliche Hersteller) und meine Fahrtregler alle Signale mit 333 Hz Wiederholrate. Und die Servos machen keinen Unterschied daraus ob bspw. das 1.5ms High-Signal mit 200 Hz oder mit 20 Hz kommt. Ob die Servos dann tatsächlich so schnell stellen lässt sich wohl schwer feststellen, aber ausschließen würde ich es nicht.
    Viele Grüße, William
    -> http://william.thielicke.org/

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.791
    Wenigstens akzeptieren meine Servos (3 unterschiedliche Hersteller) und meine Fahrtregler alle Signale mit 333 Hz Wiederholrate.
    Das "schaffen" meine Servos auch, es bringt aber keinen Vorteil. Selbst wenn man (nach Spezifikation) alle 20ms einen Impuls sendet, können die Servos mit der Positionierung des Stellhebels (mechanisch) nicht nachkommen. Ein Impuls von 1ms, nach 20ms direkt gefolgt von einem 2ms Impuls würde den Servohebel von ganz links nach ganz rechts drehen. Je nach Servo würde diese Stellzeit bis zu 2 Sekunden (!) dauern, obwohl nur 20ms zwischen den Impulsen liegen.

    Also: Eine wesentlich höhere Wiederholrate macht keinen Sinn, manche Servos haben aber angeblich "mehr Kraft", wenn man die Wiederholrate etwas anhebt.

    Gruß Dirk

Berechtigungen

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