-         
+ Antworten
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 13

Thema: Wie steuert man ein Servo an?

  1. #1
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    16.03.2004
    Beiträge
    259

    Wie steuert man ein Servo an?

    Ja also wie gesagt, wie steuert man ein Servo an?

    Ich weiss schon dass man alle 20ms ein Signal an das Servo senden muss und die Länge je nach Lage 1-2ms lang sein muss.

    Mein Problem is nur wie schaut so ein Program denn aus? Könntet ihr mir vielleicht ein kleines Beispielprogram posten anhand dessen ich das verstehen kann? Hab schon in vielen Tutorials geschaut aber das stand nirgends so drinnen.

    Danke schonmal

    Grind

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    17.01.2004
    Ort
    Erlangen, Bayern
    Alter
    34
    Beiträge
    253
    -Du initialisierst einen Timer mit 20ms
    -Dann einen mit dem Pulswert.
    -Der Erste stösst den Zweiten immer an, der Zweite läuft seine Dauer ab und zieht dann das Signal wieder auf low..
    -wenn der Zweite eingeschaltet wird, wird das Signal gesetzt..

    Oder mit einem Timer:
    -Setze Pulsweite (timeroverflow)
    -Beim Erreichen berechnest du die Differenz auf 20ms und initialisierst damit den Timer neu
    -beim zweiten Overflow wieder Pulsweite setzen
    usw.

    Aufpassen musst du bei beiden Möglichkeiten beim Ändern der Pulsdauer...
    Deshalb:
    Vorher Timer anhalten (!!!) und danach nicht einfach wieder loslaufen lassen sondern ZURÜCKSETZEN!!!Sonst enstehen Störsignale die ab und zu sehr blöde Folgen haben

    Oder:
    Kauf dir einen sd20 (Servocontroller)

    Gruss
    Michael

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.07.2004
    Beiträge
    270
    Hallo,
    bei Möglichkeit 2, was ist mit "Pulsweite" gemeint? Vielleicht versteh ich dann den Rest.

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    30.09.2004
    Ort
    In der Nähe von Esslingen am Neckar
    Beiträge
    706
    Hi FoCus,
    kannst du bitte mal ein Beispielcode posten! Das würde mich auch interressieren! Kannst du wenn du einen posten würdest auch bissl was dazu erklären? Wäre voll nett!
    Gruß Michi

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.07.2004
    Beiträge
    270
    Vielleicht ist mit Pulsweite ja das Steuersignal(+- 2ms, kommt auf gewünschte Pos an oder?) gemeint, d.h. nach der Zeit ein Timeroverflow, dann Timer so einstellen, dass 20ms vergehen, bis wieder ein Overflow ausgelöst wird, dann wieder Steuersignal etc. ...
    Aber wäre cool, wenn sich mal einer melden würde, der sich da genauer auskennt.
    Und mit PWM hat dass dann wohl eher nichts zu tun oder?

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    31.01.2004
    Ort
    36399
    Alter
    42
    Beiträge
    1.517
    Ich habe meine Ansteuerung per PWM gebaut weil dann muß im rest des programms nicht so auf passen und Cycle zählen.

    Ich habe den Code zusammen Kopiert das geben ich zu aber er funktioniert.

    Code:
    void init_servos(void)
    {
      /* Use Timers 1 generate the pulses for 2 R/C servos; each
       * timer can do up to 2 servos. */
        /*
       * configure OC1A for mode 0: normal, top=0xffff prescale=8 (f~=30):
       *
       * WGM33=0, WGM23=0, WGM13=0, WGM03=0, CS32=0, CS31=1, CS30=0 
       */
        
      SETBIT(DDRD,PD5); //auf ausgang
      SETBIT(DDRD,PD4);
      
      TCCR1A &= ~(BV(WGM11) | BV(WGM10) | BV(COM1A1) | BV(COM1B1));
      TCCR1A |= BV(COM1A0) | BV(COM1B0);
      TCCR1B &= ~(BV(WGM13) | BV(WGM12) | BV(CS12) | BV(CS10));
      TCCR1B |= BV(CS11);
      TCNT1   = 0;
      TIMSK  |= BV(TOIE1);
    
      /* set all Servos to their center positions */
      SERVO1 = SERVO_MID;
      SERVO2 = SERVO_MID;
     }
    Init Timer als PWM mit Mega16 bei 16 Megaherz

    Code:
    void servo1(BYTE s1)
    {
    	if(s1== 0)
    	{
    		SERVO1 = 1300;
    		SendMCData(52,0);
    	}
    	if(s1== 1)
    	{
    		SERVO1 =2250;
    		SendMCData(52,1);
    	}
    	if(s1== 2)
    	{
    		SERVO1 = 3000;
    		SendMCData(52,2);
    	}
    	if(s1== 3)
    	{
    		SERVO1 = 3750;
    		SendMCData(52,3);
    	}
    	if(s1== 4)
    	{
    		SERVO1 = 4700;
    		SendMCData(52,4);
    	}
    }
    
    void servo2(BYTE s1)
    {
      	if(s1== 0)
    	{
    		SERVO2 = 1300;
    		SendMCData(53,0);
    	}
    	if(s1== 1)
    	{
    		SERVO2 =2250;
    		SendMCData(53,1);
    	}
    	if(s1== 2)
    	{
    		SERVO2 = 3000;
    		SendMCData(53,2);
    	}
    	if(s1== 3)
    	{
    		SERVO2 = 3750;
    		SendMCData(53,3);
    	}
    	if(s1== 4)
    	{
    		SERVO2 = 4700;
    		SendMCData(53,4);
    	}
    }
    Setzen der Werte für das servo

    Code:
    // PWM Timmer
    SIGNAL(SIG_OVERFLOW1)
    {
      TCNT1 = 0;
    
      /* configure to set outputs on compare match so we can turn on the
       * pulse in the next statement */
      TCCR1A |= BV(COM1A1)|BV(COM1A0)|BV(COM1B1)|BV(COM1B0);
    
      /* force compare match to set outputs */
      TCCR1A |= BV(FOC1A)|BV(FOC1B);
    
      /* configure to clear outputs on compare match so that the output
       * compare function ends the pulse */
      TCCR1A &= ~(BV(COM1A0)|BV(COM1B0));
    }
    Code:
    #define SETBIT(ADDRESS,BIT)(ADDRESS |=(1<<BIT))
    #define CLEARBIT(ADDRESS,BIT)(ADDRESS &= ~(1<<BIT));
    
    #define SERVO_MIN 1300
    #define SERVO_MID 3000
    #define SERVO_MAX 4700
    
    #define SERVO1   OCR1A
    #define SERVO2   OCR1B
    Das sind ein teil der define's von mir ich finde das mach den Code
    lesbarer. Bitte alle "echten" c programmierer/in mich jetzt nicht er schlagen
    Ich programmier normaler weise c++ unter windows mit VC++

    Wenn der Timer überläuft hole ich mir die Neuen werte.

    Noch mal zur klar stellung das ist nicht alle mein code sondern er ist aus verschieden quelle zusammen kopiert.

    Es sei alle gedank die Teile des Quellcodes ver offentlichen.

    Ich betreibe mit diesem Code Zwei Modelbau Motortreiber.

    Mfg
    Home
    P: Meine Tochter (06.11.07) und Link
    M: Träumen hat nix mit Dummheit zu tun es ist die Möglichkeit neues zu erdenken

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.07.2004
    Beiträge
    270
    Hm, mag ja sein dass das funktioniert, aber ich verstehe nicht, wie man mit PWM einen Servo ansteuern kann, der in bestimmten Zeitabständen Impulse bestimmter Länge verlangt...

  8. #8
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.07.2004
    Beiträge
    270
    Hallo,
    hab mcih jetzt mal drangemacht und versucht, einen Servo anzusteuern:
    Code:
    #include <avr/io.h>
    #include <avr/signal.h>
    #include <avr/interrupt.h>
    #include <inttypes.h>
    #include <math.h>
    
    int16_t sollwert=(0.001/0.000004); 
    int16_t wert_alt;
    int8_t pos;
    
    int main(void)
    {
     
     sei();
     DDRB = (1<<DDB0);
     PORTB = (0<<PB0);
     wert_alt = 5000;
     TCCR0 = (0<<CS02) | (1<<CS01) | (1<<CS00); //Vorteiler 64
     TCNT0 = (255-5000);   //Timer vorladen
     TIMSK = (1<<TOIE0);  //Interrupt enablen
     
    }
    
    SIGNAL (SIG_OVERFLOW0)
    {
     PORTB ^= (1<<PB0);   //Pin tooglen
     if (wert_alt = 5000)  
      {
       TCNT0 = sollwert;
       wert_alt = sollwert;         
      }
     else
      { 
       TCNT0 = 5000;
       wert_alt = 5000;
      }
    }
    Das Problem ist, das er bei Werten zwischen 0.002 und 0.001 eigentlich immer nur in eine Richtung will, gleiches wenn ich die Werte noch größer oder kleiner mache. D.h. es ist keine genaue Positionierung möglich.

    Meine Berechung ist folgendermaßen:
    16000000/64 = 2500000
    1/250000 =4*10^-6=0.000004 Zeit, die ein Takt braucht
    20ms = 0.02s -> 0.02/0.000004 = 5000
    1ms = 0.001s -> 0.001/0.000004 = 250

    Weiss jemand, wo mein Fehler ist?

  9. #9
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    09.12.2004
    Beiträge
    485
    Hallo Spurius

    Wo der Denkfehler liegt kann ich Dir leider nicht sagen, aber:

    Ich habe gerade einen Code geschrieben der die HW pwm verwendet.
    Mittels diesem kann man mittels 100 Schritten (max. wären 500 möglich)
    ein servo von Mitte zu Vollausschlag bringen.
    Die bisherigen Programme die ich dazu gesehen habe, waren alle bis auf das vom Kijon viel zu ungenau, es waren max. 10 Schritte möglich
    Werde es Heute Abend testen, wenn es funktioniert kann ich ihn ja hier posten wenn Du willst.

    LG
    Rubi

  10. #10
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    17.01.2004
    Ort
    Erlangen, Bayern
    Alter
    34
    Beiträge
    253
    Zitat Zitat von Spurius
    Hm, mag ja sein dass das funktioniert, aber ich verstehe nicht, wie man mit PWM einen Servo ansteuern kann, der in bestimmten Zeitabständen Impulse bestimmter Länge verlangt...
    Kleiner Tip:
    Es gibt zwei unterschiedliche Arten PWM zu betreiben
    Du benötigst den Fast PWM Mode....
    Oder du machst es so, wie oben beschrieben....

    Anbei noch ein kleines Beispiel in ASM, bzw das Steuertool unter Win unter C++, das ich vor einem halben Jahr mal geschrieben hab...

    Gruss
    Michael
    Angehängte Dateien Angehängte Dateien

+ Antworten
Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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