kramann.info
© Guido Kramann

Login: Passwort:










kramann.info
© Guido Kramann

Login: Passwort:




Umbau eines handelsüblichen Modellbau-Servos als Antriebseinheit

(EN google-translate)

(PL google-translate)

Es ist möglich einen Servo als Antiebseinheit umzurüsten. Dazu wird die Stoppnase des Antriebszahnrades entfernt. Außerdem wird der Mitnehmer des Potentiometers entfernt, es exakt auf Mittelstellung gebracht (Messung beider Widerstandsanteile) und mit Sekundenkleber fixiert.

Während sonst ein Regelkreis bei einer Differenz von PWM-Breite und aktuell durch das Potentiometer angezeigtem Winkel zum Ausregeln der Differenz zwischen Soll- und Ist-Winkel genutzt wird, ist nun die Drehgeschwindigkeit des Servos PWM-abhängig, da es bei der nun konstanten Sollstellung unterschiedlich große Regelabweichungen "vorgaukelt".

Es wird ein preiswerter Standard-Typ mit Kunststoffgetriebe verwendet (Modelcraft RS-2).

Öffnen der Unterplatte eines Servos mit der Elektronik und vorsichtiges Heraushebeln dieser. Rechts unten sind die Anschlüsse des Potentiometers zu sehen.

Bild 0-1: Öffnen der Unterplatte eines Servos mit der Elektronik und vorsichtiges Heraushebeln dieser. Rechts unten sind die Anschlüsse des Potentiometers zu sehen.

Die Stoppnase des Antriebszahnrades kann mit Hilfe eines Elektronikschneiders entfernt werden. Es kostet einige Mühe alle Reste an der Oberfläche gründlich zu entfernen. Unbedingt ist darauf zu achten, niemals mit dem Schneider an die Ritzel des Zahnrades zu kommen!

Bild 0-2: Die Stoppnase des Antriebszahnrades kann mit Hilfe eines Elektronikschneiders entfernt werden. Es kostet einige Mühe alle Reste an der Oberfläche gründlich zu entfernen. Unbedingt ist darauf zu achten, niemals mit dem Schneider an die Ritzel des Zahnrades zu kommen!

Hier wird die Mittelstellung des Potentiometers gesucht. ACHTUNG: Es ist nicht nötig das Potentiometer wie hier herauszuschneiden und dann wirder anzulöten. Das Herauslösen von Platine mit Servo ist auch mit intakter Verbindung möglich!

Bild 0-3: Hier wird die Mittelstellung des Potentiometers gesucht. ACHTUNG: Es ist nicht nötig das Potentiometer wie hier herauszuschneiden und dann wirder anzulöten. Das Herauslösen von Platine mit Servo ist auch mit intakter Verbindung möglich!

Herausgelöste Platine mit intaktem Potentiometer.

Bild 0-4: Herausgelöste Platine mit intaktem Potentiometer.

Aufweiten der Bohrungen der Verbindungsscheibe auf 3mm, Durchbohren von Modellbauradfelgen. Es können 3mm Schrauben mit 20mm Länge zur Radbefestigung verwendet werden.

Bild 0-5: Aufweiten der Bohrungen der Verbindungsscheibe auf 3mm, Durchbohren von Modellbauradfelgen. Es können 3mm Schrauben mit 20mm Länge zur Radbefestigung verwendet werden.

Fertiger Testaufbau.

Bild 0-6: Fertiger Testaufbau.

#include <avr/io.h>
int main(void)
{
    uint8_t akku;
    uint16_t position = 108;


    DDRB = 0b00000000;
    DDRC = 0b11111111;

    TCCR1A = (1<<COM1A1) | (0<<COM1A0) | (1<<COM1B1) | (0<<COM1B0) | (0<<FOC1A) | (0<<FOC1B) | (1<<WGM11) | (1<<WGM10);
    TCCR1B = (0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (0<<CS12) | (1<<CS11) | (1<<CS10);
    DDRD |= (1<<PB5) | (1<<PB4); //auf Ausgang setzen.            
    OCR1A = position; //PWM-Breite setzen (entspricht für Servo auf 0 Grad).
    OCR1B = position; //PWM-Breite setzen (entspricht für Servo auf 0 Grad).
    PORTC = position;

    while(true)
    {
        akku = PINB;
        if( position<144 && (akku & 0b00000011) == 1) //Taster PB0 gedrückt
        {
            position++;
            PORTC = position;
            OCR1A=position; 
            OCR1B=position; 
            while( (akku & 0b00000011) == 1)
                akku = PINB;
        }
        else if( position>72 && (akku & 0b00000011) == 2) //Taster PB1 gedrückt
        {
            position--;
            PORTC = position;
            OCR1A=position; 
            OCR1B=position; 
            while( (akku & 0b00000011) == 2)
                akku = PINB;
        }
    }
    return 0;
}

Code 0-1: Testprogramm für den Servoantrieb.

Übung
  • Bauen Sie selber einen Servo als Antriebseinheit um.
  • Testen Sie ihn mit Hilfe Ihres Steckbretts und Ihres Programmierers.
  • Obiges Programm arbeitet mit einem Quarz von 9,216MHz.
  • Schreiben Sie das Programm um für einen Quarz von 2,4576MHz.
Timer-Mode-Tabelle für Timer 1 des ATmega32, Quelle: Datenblatt Atmel, Seite 107.

Bild 0-7: Timer-Mode-Tabelle für Timer 1 des ATmega32, Quelle: Datenblatt Atmel, Seite 107.

  • Finden Sie anhand der Tabelle auf Seite 107 des Datenblattes des ATmega32 heraus, in welchem Mode der Timer bei obigem Programm arbeitet.
  • Es soll nun nach einem Arbeitsmodus gesucht werden, der es erlaubt die Auflösung der PWM-Ansteuerung weiter zu erhöhen.
  • Schreiben Sie ein Testprogramm mit dem neuen Modus.
  • Nutzen Sie die Angaben im PWM-Kapitel der Mikrocontroller-Vorlesung zur Lösung dieser Aufgabe, insbesondere Kapitel 4.8.
Musterlösung

Modus 10 erlaubt es, die Zählobergrenze durch Belegung des Registers ICR1 festzulegen. Da dieser Modus volle 16 Bit Verwendet, gibt es hier eine grosse Bandbreite an Einstellungsmöglichkeiten. Die Festlegung der passenden Einstellungen zur Servo-Ansteuerung mit hoher Auflösung entnehmen Sie bitte den Kommentaren des folgenden Quelltextes, bzw. den Erläuterungen in der Vorlesung:

Servo hin und her schwenken lassen, wenn Taster gedrückt wird

  • Vorbereitungen am Steckbrett

Anschluß eines Servos:

  • schwarz / braun: Masse.
  • rot: +5Volt
  • gelb / orange: OC1A (Pin 19)
servo Steckbrett.

Bild 0-8: servo Steckbrett.

  • Quelltext für den Mikrocontroller
#include <avr/io.h>

//N     CS12 CS11 CS10   
//1       0    0    1    
//8       0    1    0    
//64      0    1    1    
//256     1    0    0
//1024    1    0    1

//Datenblatt S. 107:
//PWM-Modus Nr. 10:
//TOP = ICR1
//16 Bit
//Phasenkorrekt
//WGM13..10: 1010
//fpwm = fclk/(2*N*TOP)
//

//10..20ms == 100Hz .. 50Hz
//
//fpwm = 2457600/(2*1*15360) = 80Hz == T=0,0125s
//1 Schritt == 0,0125/15360 = 0,000000814
//1..2ms == 1228,5 .. 2457
// Mitte: 1842


#define POSMAX 2457
#define POSMIN 1229
#define POSMITTE 1842
               
int main(void)                    
{                                 
   DDRD  |= 0b10000000;            
   DDRB  &= 0b11111110;
   PORTB |= 0b00000001;

   int richtung = 1;
   uint16_t position = POSMITTE;

   long pause;                    

   ICR1 = 15360;

   TCCR1A = (1<<COM1A1) | (0<<COM1A0) | (1<<COM1B1) | (0<<COM1B0) 
          | (0<<FOC1A) | (0<<FOC1B) | (1<<WGM11) | (0<<WGM10);
   TCCR1B = (0<<ICNC1) | (0<<ICES1) | (1<<WGM13) | (0<<WGM12) 
          | (0<<CS12) | (0<<CS11) | (1<<CS10);

   DDRD |= (1<<PB5) | (1<<PB4); //auf Ausgang setzen.            
   OCR1A = position; //PWM-Breite setzen (entspricht für Servo auf 0 Grad).
   OCR1B = position; //PWM-Breite setzen (entspricht für Servo auf 0 Grad).


   while(1)                       
   {                              
            OCR1A=position; 
            OCR1B=position; 

            if(position > POSMAX || position<POSMIN)
                richtung = -richtung;

            if(  (PINB & 0b00000001)==0 )
                position+=richtung;
            else				 
                position=POSMITTE;

            for(pause=0;pause<500;pause++)
                DDRC = 0;
   }                              
}

Code 0-2: servo.c