-
        

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 13

Thema: Servos mit myavr Board und WinAvr ansteuern

  1. #1

    Servos mit myavr Board und WinAvr ansteuern

    Anzeige

    Hallo ich hab jetzt schon mehrfach das Forum durchsucht aber irgendwie ist mir das immer noch nicht ganz klar wie ich das PWM Signal erzeugen kann, also bzw wie ich den Servo ansteuern muss.
    Ich möchte insgesamt 3 Servos für ein hexapod bein ansteuern aber ich find weder tutorials noch sonst was zum ansteuern von Servos in C.
    Also wenn da jemand erfahrung hat und mir helfen könnte wär das super.
    greetz weasel

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    46
    Beiträge
    2.236
    Wozu brauchst Du ein Tutoral ?
    Wo liegt das Problem?
    Du mußt 50Hz takten und den high Anteil zwischen 1 und 2 ms halten, fertig.
    Je nach µC benutzt man dafür die PWM Modes von den Timern, oder man schreibt sich das per Software.

    Gruß Sebastian

  3. #3
    Also Tutorial wär halt nicht schlecht wo alles mal sauber erklärt wird.
    Hast du vielleciht ein funktionierendes Programm dass du mal posten könntest? Und evtl mit Kommentaren?

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    46
    Beiträge
    2.236
    Ich hätte da was in assembler, aber, das willst Du nicht haben, hast Du das schon gelesen?
    Könnte was für Dich sein...

    Gruß Sebastian

  5. #5
    Hab gestern zufällig ein Programm in C gefunden hier im Netz um 3 Servos gleichzeitig anzusteuern, allerdings find ichs jetzt nicht mehr....
    naja also das grundPirnzip is mir ja klar, allerdings weiß ich dann bei den registern nicht mehr weiter.
    ich bin jetzt ma soweit:
    // ATmega 8 mit nem 3,6864 MHz Quarz

    #include <avr\io.h>
    #include <avr\signal.h>
    #include <avr\interrupt.h>

    #define SYSCLK 3686400

    int main(void)
    {
    zaehler = 0;
    sei();
    DDRB = (1<<PB0);
    PORTB = (1<<PB0);
    TCCR1A = (1<<WGM11)|(1<<WGM10)|(1<<COM1A1);//10 Bit PWM nichtinvertierend
    TCCR1B = (1<<CS12) | (1<<CS10);// Takt von CLK/1024=> Timer wird mit einer Frequenz von 3600 Hz versorgt,Timer wird gestartet


    Also jetzt hab ich das soweit verstanden dass mein Timer 1 hochzählt und wenn er ganz oben ist wieder auf 0 gesetzt wird. Und das ich einen zweiten timer brauch der für 1 bis 2 ms läuft und mir so dir richtung bzw position vom servo vorgibt.
    So jetzt hab ich mir aber schon nen Haufen porgramme angschaut hier im Forum und mir is des mit de Regsiter ned ganz klar.
    Also ich denke auch u wissen dass im TCNT der momentane Zählerstand drin steht. aber wieso laden die Leutz da nen Wert rein und für was is des TIMSK gut?
    Achja und noch was. Viele programmierne immer ein Unterprogramm SIGNAL(SIGNALOVERFLOW0) aber rufens dann im main() ned auf?
    Also wär echt toll wenn mir da jemand erfahrenes zu Seite stehen könnte

    greetz Weasel

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    12.06.2005
    Ort
    Südwestdeutschland
    Beiträge
    1.076
    Blog-Einträge
    2
    Hallo FartingWeasel,
    hier mein Programm, mit dem kannst Du 10 Servos parallel steuern:

    Code:
     /************************************************************************
    
       SERVO Controller for up to 10 Servos
    
       controlled by serial line
       default: 2400 Baud 8N1
       
       Processor: ATMEGA 8
       CLOCK: 8MHZ, no prescaler set config bits of Atmega 8 correctly !
       
       Compiler: AVR-GCC
    
    
       This code is licensed under the GPL.
       You may modify, redistribute the code .. blabla, you know what I mean ...
    
       Copyright stochri (c.hab@gmx.net) Nov.2005
    
    ***************************************************************************/
    #include <stdlib.h>
    #include <inttypes.h>
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/signal.h>
    
    typedef unsigned char byte;
    
    #define SYSCLK 8000000 // timer clock 8Mhz
    #define MAXPULSFREQ 500 // 2ms => 500HZ
    
    #define TIMER_MAXPULS SYSCLK/MAXPULSFREQ // Timer1 value for a 2ms Puls
    
    #define MINPULS TIMER_MAXPULS/4  // min pulslength = 0.5ms
    #define MAXPULS TIMER_MAXPULS // max pulslength=2ms
    
    // port pin definitions
    // you may redefine the pins to suit your application
    // tale a look at the interrupt routine and enable the cases for your servo
    
    #define LOW_SERVO0 PORTD&=~(1<<6)
    #define HIGH_SERVO0 PORTD|=(1<<6)
    
    #define LOW_SERVO1 PORTB&=~(1<<0)
    #define HIGH_SERVO1 PORTB|=(1<<0)
    
    #define LOW_SERVO2 PORTB&=~(1<<1)
    #define HIGH_SERVO2 PORTB|=(1<<1)
    
    #define LOW_SERVO3
    #define HIGH_SERVO3
    
    #define LOW_SERVO4
    #define HIGH_SERVO4
    
    #define LOW_SERVO5
    #define HIGH_SERVO5
    
    #define LOW_SERVO6
    #define HIGH_SERVO6
    
    #define LOW_SERVO7
    #define HIGH_SERVO7
    
    #define LOW_SERVO8
    #define HIGH_SERVO8
    
    #define LOW_SERVO9
    #define HIGH_SERVO9
    
    
    uint16_t Pulslength[20]; // array for all delays
    
    /************************************************************************
    
       SIGNAL(SIG_OVERFLOW1)
       timer1 interrupt, generates the high and low pulses for each servo
    
    ***************************************************************************/
    SIGNAL(SIG_OVERFLOW1)
    {
       static byte servoindex_half=0;
    
       switch (servoindex_half)
       {
          case 0: HIGH_SERVO0; break;
          case 1: LOW_SERVO0; break;
          case 2: HIGH_SERVO1; break;
          case 3: LOW_SERVO1; break;
          case 4: HIGH_SERVO2; break;
          case 5: LOW_SERVO2; break;
    //      case 6: HIGH_SERVO3; break;
    //      case 7: LOW_SERVO3; break;
    //      case 8: HIGH_SERVO4; break;
    //      case 9: LOW_SERVO4; break;
    //      case 10: HIGH_SERVO5; break;
    //      case 11: LOW_SERVO5; break;
    //      case 12: HIGH_SERVO6; break;
    //      case 13: LOW_SERVO6; break;
    //      case 14: HIGH_SERVO7; break;
    //      case 15: LOW_SERVO7; break;
    //      case 16: HIGH_SERVO8; break;
    //      case 17: LOW_SERVO8; break;
    //      case 18: HIGH_SERVO9; break;
    //      case 19: LOW_SERVO9; break;
       }
    
       
       TCNT1 =Pulslength[servoindex_half]; // set time for next interrupt   
    
        servoindex_half++; // increment timervalue index
       if(servoindex_half==20)servoindex_half=0;   // reset index
    }
    /************************************************************************
    
       void setservo(byte index, byte value)
    
       Set servo position
       value: 0..255
    
    ***************************************************************************/
    
    void setservo(byte index, byte value)
    {
       uint16_t wert;
    
       wert=MINPULS+(MAXPULS-MINPULS)/256*value;
       
       // callculate hightime
       Pulslength[index<<1]=0-wert;
       
       // sume of low and hightime for one servo is 2ms
       Pulslength[(index<<1)+1]=0-(TIMER_MAXPULS-wert);
       
       // 10 Servos give you 10*2ms=20ms total cycle time
    }
    
    /************************************************************************
    
       void init_servos()
       
       initialize all Servos to the start position
    ***************************************************************************/
    void init_servos()
    {
       byte n;
       for(n=0;n<10;n++) setservo(n,128);
    }
    
    /************************************************************************
    
       void init(void)
       initialize the prozessor registers
    ***************************************************************************/
    
    void init(void)
    {
       // prepare RS232
       UCSRA = 0x00;
       UCSRB = 0x00;   
       UCSRC = 0x86; // No Parity | 1 Stop Bit | 8 Data Bit
       UBRRL = 0xCF; // 2400bps @ 8.00MHz
    //   UBRRL = 51; // 9600bps @ 8.00MHz
    //   UBRRL = 25; // 19200bps @ 8.00MHz
    
        /* initialize ports */
        DDRB = 0xFF;
        DDRC = 0xFF;
        DDRD = 0xFF;
        PORTB = 0x00;
        PORTC = 0x00;
        PORTD = 0x00;
    
        // init timer1
       TCNT1 = 0-16000;
       TCCR1A=0;
       TCCR1B=0x01;
        TIMSK |= _BV(TOIE2) | _BV(TOIE1);
    
        /* allow interrupts */
        sei();
    }
    
    /************************************************************************
    
       serial communication
    
    ***************************************************************************/
    
    byte chgetchar()
    {
       UCSRB = 0x10; // enable receiver
       while(!(UCSRA & 0x80)); // wait for received byte
       return UDR;
    }
    void chputchar(byte zeichen)
    {
       UCSRB = 0x08; // enable transmitter
       UCSRA|=0x40; // clear transmitter flag
       while (!(UCSRA & 0x20)); // wait for empty transmit buffer
       UDR = zeichen;
       while (!(UCSRA & 0x40)); // Wait for transmit complete flac (TXC)
    }
    void chSerPrint(unsigned char *data)
    {
       unsigned char i = 0;
       while(data[i]!=0x00) chputchar(data[i++]);
    }
    
    /************************************************************************
    
       main programm
    
       servo controll by RS232 interface
    
    ***************************************************************************/
    
    int main(void)
    {
       char c;
       byte n;
       byte servos[10];
    
       init();
       init_servos();
       
       chSerPrint("\n\r-- Atmega8 servo controller V1.0 --\n\r");
       chSerPrint("Connection OK\n\r");
    
       while(1)
       {
       
          // get key from terminal
          c=chgetchar();
    
          if(c=='q') servos[0] += 10;
          if(c=='w') servos[0] -= 10;
          if(c=='a') servos[1] += 10;
          if(c=='s') servos[1] -= 10;
          if(c=='y') servos[2] += 10;
          if(c=='x') servos[2] -= 10;
    
          // set to default position, if space is pressed
          if(c==' ')
          {
             servos[0] = 128;
             servos[1] = 128;
             servos[2] = 128;
          }
    
          for(n=0;n<10;n++) setservo(n,servos[n]);
       }
    }
    Gruss,
    stochri

  7. #7
    vielen dank das hab ich e schon gesehen aber ganz durchblicken tu ich da eben auch ned. Kann mir jemand das mit den registern mal erklären, am besten wärs anhand nem kleinen beispielprogramm wo ich einen servo nach links bzw nach rechts und in eine beliebig gewollte stellung bewegen kann. Also so mit kommentaren im programm des wär ned schlecht.
    Ich hab eben mit RS232 schnittstelle auch noch nix gemacht deshalb sagt mir das im Prog auch nicht viel... Aber trotzdem danke!!!
    Vielleicht kann ich mich ja bei Mechanikfragen revanchieren...

  8. #8
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    46
    Beiträge
    2.236
    aber ganz durchblicken tu ich da eben auch ned.
    Ja das ist eben das Problem, wenn Du als Anfänger solche Programme verstehen willst...
    Fang Doch mal klein an...
    Was verstehst Du nicht?
    Register TIMSK?
    Dann besorg Dir ein Dattenblatt zu Deinem µC tippe timsk unter suchen, und da kommt es irgendwann:
    Timer/Counter Interrupt Mask Register – TIMSK
    Und wenn Du weiter ließt Kannst Du erfahren welcher Bit was bewirkt.

    Ein Tip von mir, versuch nicht fremde Programme zu verstehen, sondern versuch eigene zu schreiben, guter einstieg ist eine LED in Sekundentakt
    blinken zu lassen, wenn Du das hast dann verstehst Du wozu es den TIMSK,TCNT.. SIGNAL und andere gibt.
    Wenn Du sowas machen willst sag mal bescheid, dann kann ich Dir etwas helfen.

    Gruß Sebastian

  9. #9
    Hallo es ist schon klar dass mans bei den eigenen Programmen am besten versteht darum hab ich ja auch angefangen selber eins zu schreiben , allerdings hab ich das mit dem Blink Led schon hinter mir das hat funktioniert und dazu brauchte ich die register auch nicht....
    und ich hab mir das im datenblatt auch schon angeschaut es ist ja nicht so dass ich nichts machen würde...
    hat denn keiner ein einfaches beispielprogramm?

  10. #10
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    46
    Beiträge
    2.236
    Na, gut Du das Blinklicht hast Du aber mit hilfe von delay geschrieben, und nicht Timer overflow interrupt, oder?

    Gruß Sebastian

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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