-         

Seite 1 von 4 123 ... LetzteLetzte
Ergebnis 1 bis 10 von 35

Thema: Servoansteurungsproblem!! Helft mir!!

  1. #1
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    30.09.2004
    Ort
    In der Nähe von Esslingen am Neckar
    Beiträge
    706

    Servoansteurungsproblem!! Helft mir!!

    Anzeige

    Hi Leutz,
    ich da ein Problem mit der Servoansteuerung!
    Folgenden Quelltext verwende ich:
    Code:
    #include <avr/io.h> 
    #include <avr/signal.h> 
    #include <avr/interrupt.h> 
    #include <inttypes.h> 
    #include <math.h> 
    
    volatile unsigned char servowert;
    volatile unsigned char puls;
    volatile unsigned char zaehler;
    
    int set_servo(volatile uint8_t pos)
    	{
    	servowert = (pos/180) + 1;
    	}
    	
    int main(void)
    	{
    	zaehler = 0;
    	sei();
    	DDRB = (1<<PB0);
    	PORTB = (1<<PB0);
    	//Timer0 übernimmt die Highphase
    	//muss 1ms sein also 25 Takte bei einem Prescaler von 64
    	puls = 25;
    	TCCR0 = (1<<CS01)|(1<<CS00);
    	TCNT0 = (255-puls);
    	for(;;)
    	{
    	}
    	}
    	
    SIGNAL(SIG_OVERFLOW0)
    	{
    	if(zaehler == 0)
    	    {
    		PORTB = (0<<PB0);
    		
    		zaehler++;
    		}
    	else if(0 < zaehler < 20)
    		{
    		zaehler++;
    		}
        else
            {
            zaehler = 0;
    		PORTB = (1<<PB0);
            }
    	}
    die Funktion set_servo hat damit noch nichts zu!
    Folgendes macht das Programm:
    -> Timer0 mit Prescaler64
    -> 25 Takte ergeben 1ms
    -> zuerst ist PortB0 an
    -> nach der 1ms wird PortB0 ausgeschaltet
    -> danach wird zaehler immer erhöht bis 20 ist dann wird PortB0 wieder eingeschaltet!
    ein Servo braucht doch erst 1ms high und dann 19ms low und dann wieder 1ms high.....usw!
    Sobald ich den µC resette fährt der Servo ein Stück weiter bleibt dort dann aber stehen!
    Könnt ihr mir da weiterhelfen? Was ist an dem Code falsch?
    Gruß Michi

  2. #2
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Also, wenn ich das übersetze und mir die .lst anschau, bleibt von dem
    if(0 < zaehler < 20) { zaehler++; } else ....
    nur der { zaehler++; } übrig

    Probier mal statt
    if(0 < zaehler < 20)

    if ( (zaehler > 0 ) && (zaehler < 20 ) )

    Zumindest mir kommt das vertrauter vor, will aber nix heissen.
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  3. #3
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    30.09.2004
    Ort
    In der Nähe von Esslingen am Neckar
    Beiträge
    706
    Hi Picnick,
    danke für die Antwort!
    aber leider ändert sich nichts!!
    kann jemand mir weiterhelfen? Oder einen funktionierenden Servocode posten?
    Gruß Michi

  4. #4
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Source hab ich jetzt auch nicht, aber viel mehr ist da ja eh nicht
    das muß auch in die ISR Routine (jedesmal)
    TCNT0 = (255-puls);
    und das ist wirkungslos
    PORTB = (0<<PB0);
    bitte:
    PORTB = (1<<PB0);

    Wenn du sagst, welchen quartz du hast, kann ich auch mitrechnen
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    30.09.2004
    Ort
    In der Nähe von Esslingen am Neckar
    Beiträge
    706
    Hi Picnick,
    mein Quartz ist 16Mhz
    Es muss doch PORTB = (0<<PB0); heißen da ich ja das Servosignal löschen will!
    mein aktueller Code:
    Code:
    #include <avr/io.h> 
    #include <avr/signal.h> 
    #include <avr/interrupt.h> 
    #include <inttypes.h> 
    #include <math.h> 
    
    volatile unsigned char servowert;
    volatile unsigned char puls;
    volatile unsigned char zaehler;
    
    int set_servo(volatile uint8_t pos)
    	{
    	servowert = (pos/180) + 1;
    	}
    	
    int main(void)
    	{
    	zaehler = 0;
    	sei();
    	DDRB = (1<<PB0);
    	PORTB = (1<<PB0);
    	//Timer0 übernimmt die Highphase
    	//muss 1ms sein also 25 Takte bei einem Prescaler von 64
    	puls = 25;
    	TCCR0 = (1<<CS01)|(1<<CS00);
    	TCNT0 = (255-puls);
    	for(;;)
    	{
    	}
    	}
    	
    SIGNAL(SIG_OVERFLOW0)
    	{
    	if(zaehler == 0)
    	    {
    		PORTB = (0<<PB0);
    		TCNT0 = (255-puls); 
    		zaehler++;
    		}
    	else if ( (zaehler > 0 ) && (zaehler < 20 ) ) 
    
    		{
    		TCNT0 = (255-puls); 
    		zaehler++;
    		}
        else
            {
    		TCNT0 = (255-puls); 
            zaehler = 0;
    		PORTB = (1<<PB0);
            }
    	}
    funktioniert immer noch net!
    Gruß Michi

  6. #6
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Löschen is anders:
    PORTB &= ~(1<<PB0);
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  7. #7
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    30.09.2004
    Ort
    In der Nähe von Esslingen am Neckar
    Beiträge
    706
    hmmmm....bringt auch nichts!!
    Gruß Michi

  8. #8
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Gut, mit dem Timing dampft es etwas.
    Für 1 mS prescale 64 Preload 6
    zähler = 0 -->Pulse on
    zähler = 20 ----> zähler reset
    else ---->pulse off
    d.h
    1. mS PULSE ON
    2. mS ---> 19. mS PULSE ON
    20 ms zähler reset
    Code:
    #include <avr/io.h> 
    #include <avr/signal.h> 
    #include <avr/interrupt.h> 
    #include <inttypes.h> 
    #include <math.h> 
    
    volatile unsigned char servowert; 
    volatile unsigned char puls; 
    volatile unsigned char zaehler; 
    
    int set_servo(volatile uint8_t pos) 
       { 
       servowert = (pos/180) + 1; 
       } 
        
    int main(void) 
       { 
       zaehler = 0; 
       sei(); 
       DDRB = (1<<PB0); 
       PORTB = (1<<PB0); 
       //Timer0 übernimmt die Highphase 
       //muss 1ms sein also 25 Takte bei einem Prescaler von 64 
       puls = 25; 
    
       TCCR0 = (1<<CS01)|(1<<CS00); 
       TCNT0 = 6; 
       for(;;) 
       { 
       } 
    } 
        
    SIGNAL(SIG_OVERFLOW0) 
    { 
    	switch(zaehler)
    	{ 
    	      case 0:         
    	 //     case 1:         das da aktivieren für 2 mS Servo 
    		PORTB |= (1<<PB0); 
        	                zaehler++; 
    		break;
    	      case 20:       
    		zähler = 0;   		
    		break;
    	      default:
    		PORTB &= ~(1<<PB0);  	
        	                zaehler++; 
    		break;	
          	} 
    	TCNT0 = 6; 
    }
    Aber viel kannst du mit dem mS Timing nicht machen, ausser ganz links und ganz rechts
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  9. #9
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Beim initialisieren fehlt noch was:

    TIMSK |= (1 << TOIE0); enablen timer

  10. #10
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    30.09.2004
    Ort
    In der Nähe von Esslingen am Neckar
    Beiträge
    706
    Hi Picnick,
    inzwischen läuft mein Servo! wenigstens in eine Richtung!!
    denn ich hab was entscheidendes vergessen:
    TIMSK = (1<<TOIE0);
    aktueller Code:
    Code:
    #include <avr/io.h> 
    #include <avr/signal.h> 
    #include <avr/interrupt.h> 
    #include <inttypes.h> 
    #include <math.h> 
    
    volatile unsigned char servowert; 
    volatile unsigned char puls; 
    volatile unsigned char zaehler; 
    
    int set_servo(volatile uint8_t pos) 
       { 
       servowert = (pos/180) + 1; 
       } 
        
    int main(void) 
       { 
       zaehler = 0; 
       sei(); 
       DDRB = (1<<PB0); 
       PORTB = (1<<PB0); 
       //Timer0 übernimmt die Highphase 
       //muss 1ms sein also 25 Takte bei einem Prescaler von 64 
       puls = 25; 
       TCCR0 = (1<<CS01)|(1<<CS00); 
       TCNT0 = (255-puls); 
       TIMSK = (1<<TOIE0);  
       for(;;) 
       { 
       } 
       } 
        
    SIGNAL(SIG_OVERFLOW0) 
       { 
       if(zaehler == 0) 
           { 
          PORTB = (0<<PB0); 
          TCNT0 = (255-puls); 
          zaehler++; 
          } 
       else if ( (zaehler > 0 ) && (zaehler < 20 ) ) 
    
          { 
          TCNT0 = (255-puls); 
          zaehler++; 
          } 
        else 
            { 
          TCNT0 = (255-puls); 
            zaehler = 0; 
          PORTB = (1<<PB0); 
            } 
       }
    warum Preload 6 ich hab doch 25 ausgerechnet?
    Wie mach ich das wenn ich in die andere Richtung will? Preload verdoppeln?
    Gruß Michi

Seite 1 von 4 123 ... LetzteLetzte

Berechtigungen

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