- fchao-Sinus-Wechselrichter AliExpress         
Seite 2 von 3 ErsteErste 123 LetzteLetzte
Ergebnis 11 bis 20 von 23

Thema: Servo machen nicht das, was sie sollen!

  1. #11
    Erfahrener Benutzer Robotik Einstein Avatar von vohopri
    Registriert seit
    11.09.2004
    Ort
    südlich der Alpen
    Beiträge
    1.708
    Anzeige

    Praxistest und DIY Projekte
    OK,

    dann solltest du auch so intelligent sein, und dir die Handhabung von Timern und Interrupts ansehen.

    grüsse,
    vohopri

  2. #12
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    ...oder mal die Suchfunktion bemühen...
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  3. #13
    Neuer Benutzer Öfters hier
    Registriert seit
    08.01.2009
    Beiträge
    14
    stimmt, ich schau mir mal des an, was in RN-Wissen steht.
    Hey Hoh, letz program

  4. #14
    Neuer Benutzer Öfters hier
    Registriert seit
    08.01.2009
    Beiträge
    14
    Ich hab jetz mal folgenden Code ausprobiert:
    Code:
    #define SERVOPIN 7
    #define SERVOPORT PORTD
    #define DDRSERVO DDRD
    
    volatile unsigned char servopos;
    
    void servo_init()
    {
    	TIMSK|=(1<<OCIE2);
    	TCCR2 |= (1<<WGM21) | (1<<CS20);	//Prescale=1, CTC mode
    	OCR2 = F_CPU/100000;			//alle 10µS ein IRQ
    	DDRSERVO|=(1<<SERVOPIN);
    };
    
    ISR(TIMER2_COMP_vect)
    {
    	static int count;
    	if(count>servopos)SERVOPORT&=~(1<<SERVOPIN);
    	else SERVOPORT|=(1<<SERVOPIN);
    	if(count<2000+servopos)count++;
    	else count=0;
    };
    der hat funktioniert, nachedm ich servopos als integer deklariert hab.

    der folgende code für zwei Servos funktioniert aber nicht so richtig:
    Code:
    #define SERVOPIN_LEFT (1<<PA1)
    #define SERVOPIN_RIGHT (1<<PA2)
    
    #define SERVOPORT PORTA
    #define DDRSERVO DDRA
    
    #define LEFT_SERVO 450
    #define RIGHT_SERVO 420
    volatile unsigned int servopos_left;
    volatile unsigned int servopos_right;
    void servo_init()
    {
    	TIMSK |= (1<<OCIE2);
    	TCCR2 |= (1<<WGM21) | (1<<CS20);	//Prescale=1, CTC mode
    	OCR2 = F_CPU/100000;			//alle 10µS ein IRQ
    };
    
    ISR(TIMER2_COMP_vect)
    {
    	static int count_left;
    	static int count_right;
    	if(count_left > servopos_left)
    		SERVOPORT &= ~SERVOPIN_LEFT;
    	else 
    		SERVOPORT |= SERVOPIN_LEFT;
    	if(count_left < 2000 + servopos_left)
    		count_left++;
    	else count_left=0;
    
    	if(count_right > servopos_right)
    		SERVOPORT &= ~SERVOPIN_RIGHT;
    	else 
    		SERVOPORT |= SERVOPIN_RIGHT;
    	if(count_right < 2000 + servopos_right)
    		count_right++;
    	else count_right=0;
    };
    wenn ich im Interrupt den Teil für den ersten Servo auskommentier läuft der erste, wenn ich den zweiten auskommentier läuft der zweite.
    Aber beide gleichzeitig laufen nicht.

    Ach ja, ich hab ne main-schleife :
    Code:
    int main(void)
    {
    	DDRA = 255;
    	servo_init();
    	servopos_left = 500;
    	servopos_right = 370;
    	sei();
    	while(1)
    	{
    
    	}		
    	while(1);
    	return 0;
    }
    Hey Hoh, letz program

  5. #15
    Neuer Benutzer Öfters hier
    Registriert seit
    08.01.2009
    Beiträge
    14
    Weiß irgendwer, wo der Fehler in meinem Programcode liegt?
    Hey Hoh, letz program

  6. #16
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    21.05.2008
    Ort
    Oststeinbek
    Alter
    34
    Beiträge
    607
    Mach die Servo-Ansteuerung lieber über hardware-PWM an den Pins OC1a und OC2.
    Lied dir dazu im Datenblatt des Controllers den Artikel "Timer/counter" (oder so ähnlich) durch, dann brauchst du nicht mal Interrupts.
    Ich würde Fast-PWM empfehlen (ich finde, das kann man am schönsten einstellen.

    Grüße, Yaro

  7. #17
    Neuer Benutzer Öfters hier
    Registriert seit
    08.01.2009
    Beiträge
    14
    ah, danke, ich werds ausprobieren
    Hey Hoh, letz program

  8. #18
    Neuer Benutzer Öfters hier
    Registriert seit
    08.01.2009
    Beiträge
    14
    Ok, ich hab jetz mal nen Code erstell:
    Code:
    DDRD |= (1<<PD4) | (1<<PD5);
    TCCR1A |= (1<<COM1A1) | (1<<COM1B1) | (1<<COM1A0) | (1<<COM1B0)| (1<<WGM12) | (1<<WGM11) | (1<<WGM10);
    TCCR1B |= (1<<CS11);
    Hey Hoh, letz program

  9. #19
    Neuer Benutzer Öfters hier
    Registriert seit
    08.01.2009
    Beiträge
    14
    Ok, ich hab jetz mal nen Code erstell:
    Code:
    DDRD |= (1<<PD4) | (1<<PD5);
    TCCR1A |= (1<<COM1A1)|(1<<COM1B1)|(1<<COM1A0)|(1<<COM1B0)|(1<<WGM12)|(1<<WGM11)|(1<<WGM10);
    TCCR1B |= (1<<CS11);
    Jetzt weiß ich bloß nicht, wie ich OCR1A und OCR1B einstellen muss.
    Hey Hoh, letz program

  10. #20
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    Deine ISR von oben sollte besser so aussehen:
    Code:
    ISR(TIMER2_COMP_vect)
    {
       static int count;
       if(count > servopos_left)
          SERVOPORT &= ~SERVOPIN_LEFT;
       else
          SERVOPORT |= SERVOPIN_LEFT;
    
       if(count > servopos_right)
          SERVOPORT &= ~SERVOPIN_RIGHT;
       else
          SERVOPORT |= SERVOPIN_RIGHT;
    
       if(count < (2000)
          count++;
       else
    		count=1;
    };
    Mit dem "count=1" kann man mit servopos=0 den Impuls ganz ausschalten.

    Trotzdem stimmt etwas mit dem Takt nicht denn die Werte für die Servopositionen sind viel zu hoch:
    servopos_left = 500;
    servopos_right = 370;
    Bei einem 10µs-Interrupt wären das 5ms oder 3,7ms! Und 2000 als count-Wert würden auch keine 20ms ergeben. Deshalb reicht dir auch das char für servopos nicht aus.

    Code:
    TCCR1A |= (1<<COM1A1) | (1<<COM1B1) | (1<<COM1A0) | (1<<COM1B0)| (1<<WGM12) | (1<<WGM11) | (1<<WGM10); 
    TCCR1B |= (1<<CS11);
    Sollen wir nun das Datenblatt wälzen um das Setup des Timers zu kontrollieren? Je nach Timer-Mode und Taktfrequenz/Prescaler werden OCR1A und OCR1B eingestellt. Bei nur zwei Servos erscheint mir die Verwendung der ISR-Lösung einfacher.

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

Seite 2 von 3 ErsteErste 123 LetzteLetzte

Berechtigungen

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

Labornetzteil AliExpress