- 12V Akku mit 280 Ah bauen         
Seite 4 von 5 ErsteErste ... 2345 LetzteLetzte
Ergebnis 31 bis 40 von 41

Thema: Atmega N fach Servo Controller ?

  1. #31
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Anzeige

    LiFePo4 Akku selber bauen - Video
    aber ich bekomm den Port C nicht zum laufen
    JTAGEN Fuse kontrollieren (muss aus sein).
    MfG
    Stefan

  2. #32
    Moderator Robotik Einstein Avatar von HannoHupmann
    Registriert seit
    19.11.2005
    Ort
    München
    Alter
    42
    Beiträge
    4.534
    Blog-Einträge
    1
    @Sternst danke das wars, ich hatte nämlich letzte woche nen neuen Mega32 eingebaut und der hatte noch die alten Fuses und nicht wie der vorgänger die neuen. Nur an sowas hab ich mich nimmer erinnert.

    Bleibt die Frage wie ich den Code auf 11 Servos erweitern kann

  3. #33
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    06.02.2005
    Ort
    Hamburg
    Alter
    38
    Beiträge
    4.255
    Die Beschränkung auf 10 Servos kommt daher, dass die Steuerinmpulse 1 bis 2ms lang sind, und im 20ms-Rhythmus wiederholt werden. Es werden daher die einzelnen Impulse nacheinander ausgegeben, und nach zehn Impulsen mit Maximallänge + Pause ist man automatisch bei dem 20ms.

    Die meisten Servos sehen das mit den 20ms aber nicht allzu eng. Du könntest also erst mal versuchen, alle Arrays und Variablen von 10 auf 11 anzupassen. Die Neutrallage der übrigen Servos könnte sich minimal verschieben, aber ansonsten stehen die Chancen gut, dass es klappt.

    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
       
       Warnungen beiseitigt von uwegw
    
    ***************************************************************************/
    #include <stdlib.h>
    #include <inttypes.h>
    #include <avr/io.h>
    #include <avr/interrupt.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[22]; // !!! // 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;
    //		case 20: HIGH_SERVO10; break; // !!!
    //      case 21: LOW_SERVO10; break; // !!!
       }
    
       
       TCNT1 =Pulslength[servoindex_half]; // set time for next interrupt   
    
        servoindex_half++; // increment timervalue index
       if(servoindex_half==22)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);
       
       // 1 Servos give you 1*2ms=22ms total cycle time /!!!
    }
    
    /************************************************************************
    
       void init_servos()
       
       initialize all Servos to the start position
    ***************************************************************************/
    void init_servos(void)
    {
       byte n;
       for(n=0;n<11;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(void)
    {
       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(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<11;n++) setservo(n,servos[n]); //!!!
       }
    }
    Kompilert einwandfrei, habs allerdings nicht testen können. Die Änderungen habe ich mit //!!! markiert. Könnte sein, dass ich noch was übersehen habe...

  4. #34
    Moderator Robotik Einstein Avatar von HannoHupmann
    Registriert seit
    19.11.2005
    Ort
    München
    Alter
    42
    Beiträge
    4.534
    Blog-Einträge
    1
    Gibt es eigentlich noch eine einfache Möglichkeit, den Code so zu erweitern, dass sich die Geschwindigkeit der Servos regeln lässt? Ich möchte meine Servos nicht immer mit maximaler Geschwindigkeit laufen lasen, sondern auch mal langsam anfahren und stoppen (Massenträgheit und sowas).

  5. #35
    Habe den Code jetzt selber auf meinem Atmega8 getestet, kompilieren lässt er sich ohne Probleme, der gewünschte Effekt wurde jedoch nicht erzielt.

    Möchte einfach nur zu Testzwecken 2 Servos ansteuern, egal welche Position.
    Der Servo bewegt sich jedoch immer nur in eine Richtung bis zum Anschlag. Bei meinen Messungen habe ich gemerkt das ich ein durchgehendes Signal bekomme und keine 1-2ms Signale.

    Wenn ich im AVR Studio debugge wird immer nur "SIGNAL(SIG_OVERFLOW1)" durchlaufen, "setservo(X,X)" eigentlich nie...

    In der Makefile habe ich die 8Mhz angegeben, sprich "-DF_CPU=8000000UL" und bei den Fuses muss ich ja glaube ich keine großen Änderungen vornehmen, verwenden den "Int. RC Osc. 8 MHz; Start-up time: 6 CK + 0 ms".

    Hier der Code, freue mich über jede Hilfe.

    Code:
    /************************************************************************
    
       SERVO Controller for up to 10 Servos
       
       Processor: ATMEGA 8
    
    ***************************************************************************/
    #define F_CPU 8000000UL
    
    #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 
    #define MAXPULSFREQ 500 // 2ms 4Mhz => 1024HZ
    
    #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
    
    #define LOW_SERVO0 PORTD&=~(1<<2)
    #define HIGH_SERVO0 PORTD|=(1<<2)
    
    #define LOW_SERVO1 PORTB&=~(1<<1)
    #define HIGH_SERVO1 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(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
    {
       setservo(0,128);
       setservo(1,128);
    }
    
    /************************************************************************
    
       void init(void)
       initialize the prozessor registers
    
    ***************************************************************************/
    
    void init(void)
    {
    
        // init timer1
       TCNT1 = 0-16000;
       TCCR1A=0;
       TCCR1B=0x01;
        TIMSK |= _BV(TOIE2) | _BV(TOIE1);
    
        /* allow interrupts */
        sei();
    }
    
    /************************************************************************
    
       main programm
    
    ***************************************************************************/
    
    int main(void)
    {
       byte servos[2];
    
       init();
       init_servos();
       
       while(1)
       {
       
             servos[0] = 20;
             servos[1] = 130;
    
        setservo(0,servos[0]);
        setservo(1,servos[1]);
       }
    }

  6. #36
    Neuer Benutzer Öfters hier
    Registriert seit
    03.07.2006
    Ort
    Gründau
    Alter
    37
    Beiträge
    19
    Vielen Dank erstmal für den Code

    Habe ihn mal auf meine bedürfnisse gekürzt

    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 PORTA&=~(1<<4)
    #define HIGH_SERVO0 PORTA|=(1<<4)
    
    #define LOW_SERVO1 PORTA&=~(1<<5)
    #define HIGH_SERVO1 PORTA|=(1<<5)
    
    #define LOW_SERVO2 PORTA&=~(1<<6)
    #define HIGH_SERVO2 PORTA|=(1<<6)
    
    #define LOW_SERVO3 PORTA&=~(1<<7)
    #define HIGH_SERVO3 PORTA|=(1<<7)
    
    #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)
    {
    
    
        /* initialize ports */
        DDRA = 0xFF;
       
        PORTA = 0x00;
    
        // init timer1
       TCNT1 = 0-16000;
       TCCR1A=0;
       TCCR1B=0x01;
        TIMSK |= _BV(TOIE2) | _BV(TOIE1);
    
        /* allow interrupts */
        sei();
    }
    
    
    
    /************************************************************************
    
       main programm
    
       servo controll by RS232 interface
    
    ***************************************************************************/
    
    int main(void)
    {
       char c;
       byte n;
       byte servos[10];
    
       init();
       init_servos();
       
    
    
       while(1)
       {
       
     
    
     
    
         
             servos[0] = 128;
             servos[1] = 100;
             servos[2] = 128;
             servos[3] = 128;
    
          for(n=0;n<10;n++) setservo(n,servos[n]);
       }
    }

    jetzt funktionieren die Servos allerdings nur sollange ich den befehl servos[0..3] in der while(1) schleife lasse.

    wie schaffe ich es mit hilfe dieses codes aus meinem eigentlich hauptprogramm herraus die Servos zu steuern.. sodass er nicht immer in der while schleife hängen muss !? oder ist das mit diesem code nicht ohne weiteres möglch ?

    also das ich in meinem hauptprogramm nur einen befehl wie servo[5]=255 oder ähnlich ausgeben muss der rest von allein passiert ich es also nicht in eine endlosschleife packen muss...

    das wäre das erste problem.
    Es läuft im Moment auf meinem Atmega32 mit 8 Mhz.
    Würde es gerne auf 16Mhz portieren.. schaffe es aber leider nicht
    habe schon mit den werten experimentiert. aber es läuft leider nicht.. vielleicht habt ihr ja einen tipp für einen anfänger.

    danke

  7. #37
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    07.02.2005
    Beiträge
    102
    Hallo Leute,

    ich muss diesen Beitrag noch mal hoch holen, denn ich kämpfe grade mit den gleichen Problemen wie Somebuddy.

    Auch ich habe einen Mega32 mit 16MHz der einen Servocontroller ergeben soll und bekomme den Code nicht richtig ans fliegen.

    Weiterhin soll das Board Daten vom UART entgegennehmen mit den Befehlen für die Servos und dann soll er noch die Schritte der Servos berechnen, und zwar so, dass alle Servos zum gleicne Zeitpunkt am Ziel ankommen, egal wie viele Impulse sie dafür benötigen.

    Beispiel: Servo 1 soll 200 Schritte machen, Servo 2 nur 50 Schritte also muss das so aufgeteilt werden, dass Servo 2 nur alle 4 Schritte von Servo1 einen Schritt macht.

    Wenn ich mir die Routine in der ISR so ansehe, dann bleibt für solche Dinge irgendwie gar keine Zeit mehr zumal die Daten der Seriellen Schnittstelle ja auch mit Interrupts arbeiten und ggf noch Berechnungen ausgeführt werden müssen.

    mws
    ---------------o00o----' (_)' ----o00o----------------
    Wer Rechtschreibfehler findet darf sie behalten.

  8. #38
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Irgendwie paßt das nicht zusammen: Servos und Schrittmotoren. Die normalen Modelbauservos haben keine schritte, sondern arbeiten mit einer analogen Positionsrückmeldung. Schritte gäbe es bei Servomotoren, also Motoren mit Drehgeben die so geregelt werden. Da kann es schon mal Passieren das ein µC nur 1-2 Motoren schaft.

    Wenn das Program gut gemacht ist, können viele Dinge gleichzeitig gehen. Es können also durch aus mehrere Interrupts aktiv sein. Solange die einzelenen ISRs schnell bleiben kann das recht gut gehen. Etwas Planung gehört aber dazu.

    Das Schwierigste dürfte das reagieren auf die Befehle per UART. HIer kommen die Bytes ja einzeln. Man muß erstmal die Daten nur puffern und kann dann erst reagieren wenn der Befehl vollständig übertragen sind. Dazwischen muß man die ISR immer wieder beenden.

  9. #39
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    07.02.2005
    Beiträge
    102
    OK, es sind keine wirklichen Schritte wie bei Schrittmotoren aber es gibt nur eine endliche Zahl an Positionen die mit einem Controller erzeugt werden. Diese kann man als "Schritte" bezeichnen. Elektor hate mal so ein Projekt aber in Forth geschrieben

    Wenn ich mir die ISR für die Servos so anschaue, dann sind die nicht wirklich kurz. Da muss es doch noch was anderes geben.

    Und das mit dem Puffern hatte ich mir auch so gedacht. So lange puffern bis ein "CR" gesendet wird und dann die Verarbeitung des Strings durchführen. (In Bascom wird das auch so gemacht und das gefiel mir gut.)

    mwsh
    ---------------o00o----' (_)' ----o00o----------------
    Wer Rechtschreibfehler findet darf sie behalten.

  10. #40
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Die Servos sind eher geächliche Motoren. Da sollte die Rechenzeit nicht so knapp werden. Wenn man mehr als 2 Servos hat, erzeugt man die pulse ohnehin am besten in einem Interrupt. Dann muß man schon aufpassen das keine andere ISR zu lange braucht. Das wäre hier vor allem die UART. Da sollte man in der ISR also nur das aller nötigste tun. Vermutlich also so etwas wie ein Puffer zum einlesen, mehr nicht.

    Das anpassen der sollpositionen kann man dann syncron mit den Servopulsen machen, also z.B. dann wenn man ohnehin die Pause zum auffüllen auf 10-20 ms macht. Das könnte dann sogar in der ISR passieren, denn da läuft dann ja gerade nichts wirklich Zeitkritisches, nur die UART. Fürs Haupt programm wäre dann die Befehlserkennung und das berechnen der Geschwindigkteiten übrig.
    Da sollte man nichtmal die volle Geschwindigkeit des µc brauchen. Wenn man sich wirklich anstrengt, wäre vermutlich 1 MHz ausreichend, unter 100 kHz wird aber schwierig wegend er Auflösung.

Seite 4 von 5 ErsteErste ... 2345 LetzteLetzte

Berechtigungen

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

Labornetzteil AliExpress