-
        

Ergebnis 1 bis 3 von 3

Thema: Servo an ADC0 gesteuert von Timer0

  1. #1
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    04.03.2010
    Beiträge
    205

    Servo an ADC0 gesteuert von Timer0

    Anzeige

    Hallo,
    Ich möchte, dass mein RP6 einen Servo steuert. Den Servo habe ich an ADC0 angeschlossen und dieses Programm ausprobiert:
    Code:
    #include "RP6RobotBaseLib.h" 
    
    int main(void) 
    { 
       initRobotBase();   
       DDRA |= 1;         // ADC0 auf Ausgang 
       while(1)        // immer weiter Impuls für rechts geben
       { 
          PORTA |= 1;    
          sleep(10); 
          PORTA &= ~1;     
          sleep(200-10);  
    	  
       } 
       
       
       return(0); 
    }
    Das funktioniert auch gut aber jetzt wollte ich nicht mehr die RP6lib verwenden sondern selbst die sleep-Funktion schreiben. Das sieht dann so aus:
    Code:
    #include <avr/io.h>			
    #include <avr/interrupt.h>	
    #include <stdlib.h>		
    
    uint8_t timer=0;
    
    void timer_init(void)   // Timer einstellen
    { 
    
    TCCR0 =   (0 << WGM00) | (1 << WGM01) 
    			| (0 << COM00) | (0 << COM01) 
    			| (0 << CS02)  | (1 << CS01) | (0 << CS00);
    	OCR0  = 99;
    	
    } 
    
    ISR(TIMER0_COMP_vect)
    {	
    	timer++;	
    }
    
    
    
    void sleep(uint8_t time)
    {
    	for (timer = 0; timer < time;);
    }
    
    
    
    int main(void)
    {
       DDRA |= 1;  
       timer_init();
    
       while(1)         // Servomitte  
       { 
          PORTA |= 1;    // Ausgang auf high 
          sleep(15); // schlafe 1,5ms
          PORTA &= ~1;    // Ausgang auf low  
          sleep(200-15); // 20ms-1,5ms warten bis nächster Impuls gesendet wird 
       } 
    	return(0);
    }
    Aber leider klappt das nicht. Der Servo dreht sich garnicht.
    Kann mir jemand sagen was ich falsch gemacht habe? Bei der Initialisierung des Timers bin ich mir nicht sicher ob das richtig ist, weil ich die aus der RP6Lib habe aber selber nicht so ganz verstehe was die Befehle bedeuten.
    Nichts existiert durch sich allein!
    http://i42.tinypic.com/10pa90x.jpg

  2. #2
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.782
    Blog-Einträge
    8
    Hallo

    Ich bin grad zu faul um dein Timersetup nachzuprüfen. Es lohnt sich allerdings auch nicht wirklich in diese stümperhafte Sleep()-Ansteuerung unnötig Zeit zu investieren. Viel besser ist eine Ansteuerung direkt in der ISR. http://www.rn-wissen.de/index.php/Servo zeigt das Prinzip mit einem Servo. Die ISR wird mit 100000kHz aufgerufen und daraus werden die Impulslängen berechnet. Ich verwende das dann auch gleichzeitig als Zeitgeber für eine Pause()-Funktion:

    Code:
    	uint8_t p=0;
    
    	void Pause(uint8_t wert) // Pause in 1/50 Sek
    	{
    	   p=wert;
    	   while(p);
    	}
    	
    	und am Ende der ISR:
    	
    	if(count<2000-servopos)count++;
    		else {count=0; if(p) p--;}
    Gruß

    mic

    [Edit]
    Drei Servos an SDA, SCL und E_INT mit Timer0 ohne RP6-Library:

    http://www.roboternetz.de/phpBB2/vie...=322293#322293

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

  3. #3
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    04.03.2010
    Beiträge
    205
    Danke für die Tipps,
    Ich habe das Problem jetzt so gelöst:
    Code:
    #include <util/delay.h> 
    #include <avr/io.h> 
    #include <avr/interrupt.h> 
    #include "lib.h"
    
    
    unsigned char x, count; 
     
    
    ISR (TIMER0_COMP_vect)
    { 
       if (count>x) PORTA &= ~1; else PORTA |= 1; 
       if (count < 200) count++; else count=0; 
    } 
    
    void long_delay(uint16_t ms)
    {
        for(; ms>0; ms--) _delay_ms(1);
    }
    
    void demo(uint8_t a) // Demo: ein Durchgang besteht aus linker Anschlag bis rechter Anschlag
    {                    // Anzahl der Durchgänge kan festgelegt werden
     uint8_t q;
     uint8_t i=14;
     for(q=0; q<a; q++)
      {
     for(i=14; i<67; i++)
      {
       
         long_delay(1000);
    	
       x=i;  
      }
     for(i=67; i>14; i--)
      {
       
         long_delay(1000);
    	
       x=i;  
      } 
    }
    }
    int main(void) 
    { 
       delta_init(); 
       timer0_init();
       usart_init();
       DDRA |= 1;  
       demo(5); // Demo 5-Mal Ausführen
       
       while(1)
    {
      if(usart_byte_avail()) // Dann auf Befehle über UART warten
      {                      // links:67 , mitte:39 , rechts:14  
       x = readInteger();
      
      }
    } 
     return(0);   
      
    }
    Jetzt funktioniert alles, wie es soll.
    Nichts existiert durch sich allein!
    http://i42.tinypic.com/10pa90x.jpg

Berechtigungen

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