- 12V Akku mit 280 Ah bauen         
Seite 3 von 4 ErsteErste 1234 LetzteLetzte
Ergebnis 21 bis 30 von 35

Thema: Servoansteurungsproblem!! Helft mir!!

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

    Praxistest und DIY Projekte
    Hi,
    inzwischen hab ich es hingebekommen mit den 0.1ms!
    Um den Servo(den von Robotikhardware) ganz nach links zu bewegen brauch ich 6 Takte = 0.6ms undnach rechts die 20 Takte = 20ms!
    ist das normal??
    Gruß Michi

  2. #22
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Das ist auch etwa das, was ich brauche. Man müßte natürlich die Zeitdifferenzen durch die Maschinenbefehle berücksichtigen, die vom Timer --> Pulseoff noch verstreichen. Aber was soll's. irgendeine Zahl ist links und eine andere ist rechts. Von der objektiven Zeit hab ich ja nix.
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  3. #23
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    30.09.2004
    Ort
    In der Nähe von Esslingen am Neckar
    Beiträge
    706
    Hi Picnick,
    mit den Takten mein ich die Interrupts also nach 6 Interrupts 6ms usw.!
    Ja die Befehle verbrauchen sxchon ein paar Takte aber die will ich jetzt mal hinterrücklings lassen!
    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 Prescaler 64
       //1600000Mhz hat der µC 
       //0.0000000625s zischen den Takten 
       //mit Prescaler: 0.000004s zischen den Takten 
       //0.0001s/0.000004s = 25  
       //Preloadwert: 231 <= 256-25
       //Zeit zwischen Interrupt 0.1ms
       //1ms = 10 Takte
       //1.5ms = 15 Takte
       //2ms = 20 Takte
       //20ms = 200Takte
       //da erster Takt = 0
       //nach 9 Takten low
       //nach 199 Takten high!
       TCCR0 = (1<<CS01)|(1<<CS00); 
       TCNT0 = 231; 
       TIMSK |= (1 << TOIE0); 
       for(;;) 
       { 
       } 
    } 
        
    SIGNAL(SIG_OVERFLOW0) 
    { 
       switch(zaehler) 
       { 
            case 0:          
            case 1:       
    		case 2: 
    		case 3:
    		case 4:
    		case 5: //Links
    		case 6:
    		case 7:
    		case 8:
    		case 9: //1ms
    		case 10:          
            case 11: //Mitte       
    		case 12: 
    		case 13:
    		case 14:
    		case 15://1.5ms
    		case 16:
    		case 17:
    		case 18:
    		case 19: //2ms //rechts
    		
    			PORTB |= (1<<PB0); 
                           zaehler++; 
    			break; 
            case 199:        
    			zaehler = 0;          
    			break; 
    		default: 
    			PORTB &= ~(1<<PB0);      
                zaehler++; 
    			break;    
             } 
        TCNT0 = 231; 
    }
    ich kann jetzt zwar wenn ich jetzt den Servo nach links stellen will einfach vor dem alles was nach case 5: kommt ein // setzen damit er nach linkns fährt, aber will jetzt dass ich einfach sag z.B. Servo 90 und er fährt zur Mittelstellung!! da muss ich wohl noch ein paar Funktionen einsetzen!!
    Gruß Michi

  4. #24
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    21.05.2004
    Beiträge
    275
    Hi Leute!

    Ich bin auch gerade dabei eine Servoansteuerung zu proggen.
    Komme bei einer Ansteurung von 1-2ms allerdings bei weitem nicht an die Endanschläge.
    Habe kein Oszi kann also nicht die exakten Zeiten messen.
    Wie sind eure Erfahrungen so?
    (Ich nutze billig Servos)

    Von der Hardware her nutze ich:
    Atmega8 mit 16Mhz.
    Prescaler 64 -> TCNT0 mit 6 initialisiert = 1ms

    Um den rechten Rand zu erreichen muss ich TCNT0 mit 255-160 initialisieren.
    Um den linken Rand zu erreichen müsste ich TCNT0 mit 255 - 580 inititalisieren, was ich durch mehrfaches aufrufen erreiche.


    Ist bei meiner Rechnung etwas falsch, oder ist das normal?

    mfG
    Batti

    Allen noch einen frohen Feiertag!

  5. #25
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    30.09.2004
    Ort
    In der Nähe von Esslingen am Neckar
    Beiträge
    706
    Hi,
    als bei mir variieren die Zeiten auch! bei dem Servo von www.robotikhardware.de bentötige ich um den Servo nach ganz links zu drehen 0,6ms und nach rechts 20ms!
    Ich denk mal sowas ist normal wegen den Fertigungstoleranzen!
    Gruß Michi

  6. #26
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    21.05.2004
    Beiträge
    275
    Danke Michi!
    Hab mir schon sowas gedacht...

    Trotzdem wundert es micht, da ja auch die Fernsteuerungsanlagen mit den billig Dingern zurecht kommen müssen...

    mfg
    Batti

  7. #27
    Benutzer Stammmitglied
    Registriert seit
    24.11.2005
    Ort
    Hannover
    Beiträge
    45
    Hallo leute,

    ich habe diesen Thread genau gelesen und versucht auch alles so zu machen wie du (michaelb)! Aber leider passiert bei mir gar nix!

    Vielleicht noch was zu meinem Aufbau: ich hab meinem Servo an einem Mega32 und nicht am PortB sonder am PORTD.7 (Pin21)! Ich hab euch auch mal meinen Code mitgepostet, wo ich alles geändert habe wovon ich denke, dass ich es ändern muss! Ich hoffe ihr habt eine Idee warum es bei mir nicht geht!

    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(); 
       DDRD = (1<<PD7); 
       PORTD = (1<<PD7); 
       //Timer0 übernimmt die Highphase 
       //muss 1ms sein also 25 Takte bei einem Prescaler von 64 
       puls = 6; 
       TCCR0 = (1<<CS21) | (1<<CS20); 
       TCNT2 = (255-puls); 
       TIMSK = (1<<TOIE2);  
       for(;;) 
       { 
       } 
       } 
        
    SIGNAL(SIG_OVERFLOW2) 
       { 
       if(zaehler == 0) 
           { 
          PORTD &= ~(0<<PD7); 
          TCNT2 = (255-puls); 
          zaehler++; 
          } 
       else if ( (zaehler > 0 ) && (zaehler < 20 ) ) 
    
          { 
          TCNT2 = (255-puls); 
          zaehler++; 
          } 
        else 
            { 
          TCNT2 = (255-puls); 
            zaehler = 0; 
          PORTD = (1<<PD7); 
            } 
       }
    Danke für eure Antworten

    Matic

  8. #28
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    30.09.2004
    Ort
    In der Nähe von Esslingen am Neckar
    Beiträge
    706
    Hi,
    ich finde in deinem Code folgende Fehler:
    >TCNT2 durch TCNT0 erstetzen da du den Timer0 benutzen tust!
    >puls = 6 wie kommt du darauf? Ersetz das mal durch puls = 25
    >warum setzt du das Bit TOIE2? Für Timer0 brauchst du doch TOIE2!
    ok wenn du den Timer2 nutzen willst dann brauchst du schon TCNT2 und TOIE0 aber dann muss du die entsprechenden Bits im TCCR2 setzen statt im register TCCR0! wenn du nämlich diese Bits nicht setzen tust dann arbeitet der Timer gar nicht!!
    Gruß Michi

  9. #29
    Benutzer Stammmitglied
    Registriert seit
    24.11.2005
    Ort
    Hannover
    Beiträge
    45
    Hi,

    so jetzt habe ich endlich zeit gehabt um deine Fehler zu korrigieren:

    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(); 
       DDRD = (1<<PD7); 
       PORTD = (1<<PD7); 
       //Timer0 übernimmt die Highphase 
       //muss 1ms sein also 25 Takte bei einem Prescaler von 64 
       puls = 25; 
       TCCR2 = (1<<CS21) | (1<<CS20); 
       TCNT2 = (255-puls); 
       TIMSK = (1<<TOIE0);  
       for(;;) 
       { 
       } 
       } 
        
    SIGNAL(SIG_OVERFLOW2) 
       { 
       if(zaehler == 0) 
           { 
          PORTD &= ~(0<<PD7); 
          TCNT2 = (255-puls); 
          zaehler++;
    	  //PORTB = (0<<PB0);  
          } 
       else if ( (zaehler > 0 ) && (zaehler < 20 ) ) 
    
          { 
          TCNT2 = (255-puls); 
          zaehler++; 
          } 
        else 
            { 
          TCNT2 = (255-puls); 
            zaehler = 0; 
          PORTD = (1<<PD7); 
            } 
       }
    Aber leider tut sich immer noch nichts! Ich weiß nicht woran es liegen kann! Naja vielleicht könnt ihr ja was im Quellcode finden! Danke für eure hilfe!

    matic

  10. #30
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    30.09.2004
    Ort
    In der Nähe von Esslingen am Neckar
    Beiträge
    706
    Hi matic,
    also ich hab folgende Fehler gefunden:
    >ändere das:
    Code:
    TCCR2 = (1<<CS21) | (1<<CS20);
    in das
    Code:
    TCCR2 = (1<<CS22);
    um damit du den Prescaler von 64 hast!!! Datenblatt lesen!
    >das
    Code:
    TIMSK = (1<<TOIE0);
    kann nicht stimmen!!
    das muss:
    Code:
    TIMSK = (1<<TOIE2);
    heißen den du verwendest ja den Timer2!
    TOIE2 = Timer Overflow Interrupt Enable für den Timer2!

    Gruß Michi

Seite 3 von 4 ErsteErste 1234 LetzteLetzte

Berechtigungen

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

LiFePO4 Speicher Test