====== Servomotor ======
//Notwendiges Wissen: [HW] [[en:hardware:homelab:motor]], [HW] [[en:hardware:homelab:sensor]], [AVR] [[en:avr:io]], [LIB] [[en:software:homelab:library:module:motor]], [LIB] [[en:software:homelab:library:adc]]//
===== Theorie =====
[{{ :examples:motor:servo:motor_servomotor.jpg?220|RC Servomotor}}]
[{{ :examples:motor:servo:motor_servo_signal_position.png?220|Das Verhältnis von Signalweite und Position der PWM des Servomotors.}}]
Servomotoren werden oft in funkgesteuerten (RC) Modellen benutzt und sind sehr nützlich für kleine robotischen Anwendungen, da sie sehr kompakt und günstig sind.
Ein RC-Servomotor verfügt über einen eingebauten Gleichstrommotor, ein Getriebe, einen Positionsfeedbacksensor (meistens ein Potentiometer, und eine Steuerelektronik. RC-Servomotren können mit einem externen PWM-Signal gesteuert werden. Wenn das Signal den RC Servotiming-Vorraussetzungen entspricht, "beschreibt" es normalerweise ein Positionsinput für die Servo-Steuer-Elektronik. Die Servomotor Elektronik vergleicht die Achsenstellung mit der eingegebenen Position und versucht eine übereinstimmende Position zu erreichen. Das Positionskontrollsignal ist eine durchgehende Rechteckschwingung, wie in dem Bild dargestellt.
RC (//radio-controlled//) Servomotoren sind in der Robotik und im Modellbau sehr verbreitete Antriebe. Sie bestehen aus einem kleinen Gleichstrommotor, einer Übersetzung und der logischen Kontrolleinheit. Normalerweise versucht der Rotor des Servomotors sich in eine bestimmte Position zu bringen und diese zu halten. Die Position des Rotors hängt von dem Kontrollsignal ab, dass der Servomotor empfangen hat. Je nach Typ des Motors kann der maximale Drehwinkel des Motors variieren. Servomotoren, die sich konstant drehen, sind selten. In diesem Fall gibt das Kontrollsignal nicht den Rotationswinkel, sondern die Rotationsgeschwindigkeit an. Servomotor-Hacks sind auch sehr verbreitet. Hierdurch wird ein positionsbestimmender Servomotor zu einem konstant drehenden. In diesem Fall wird das Feedback Potentiometer durch zwei Widerstände ersetzt, und der mechanische Widerstand, welcher verhindert, dass eine vollständige Rotation stattfinden kann, wird entfernt.
Eine wichtige Eigenschaft des Servomotors ist das Kraft-Gewicht-Verhältnis.
Das Kontrollsignal des Servomotors ist ein speziell pulsweitenmoduliertes Signal (PWM), bei dem die Pulsweite die Position des Rotors angibt. Die Periode des Signals liegt bei 20 ms (50 Hz) und die Weite der hohen Periode ist 1 ms - 2 ms. 1 ms markiert die eine äußerste Position 2 ms die Andere. 1,5 ms markieren die Mittelposition des Servomotorrotors.
Traditionelle RC-Servomotoren sind auch bekannt als analoge Servomotoren. Dies liegt daran, dass in dem letzten Jahrzehnt so genannte digitale Servomotoren auf den Markt kamen. Der Unterschied zwischen beiden besteht darin, dass analoge RC-Servomotoren mit einem 50 Hz PWM Signal gesteuert werden, digitale RC-Servomotoren durch einen Mikrocontroller mit einem höherfrequenten Signal. Das Inputsignal ist das Gleiche, jedoch ist durch die höhere Modulationsfrequenz wird eine schnellere und präzisere Positionsbestimmung ermöglicht.
~~CL~~
===== Übung =====
Auf dem Platine des HomeLab Motormoduls sind 2 Anschlüsse für RC-Servomotoren vorhanden.
Die PWM-Enden der Stecker sind an den Pins PB5 und PB6 am Mikrocontroller angeschlossen, dessen sekundäre Funktion das Vergleichen der Einheiten A und B von Timer 1 ist. Timer 1 kann ein PWM Signal erzeugen, und daher ist das Steuern eines Motors sehr einfach zu programmieren. Die einzige Schwierigkeit besteht im Einstellen des Timers.
Timer 1 muss in den PWM-Produktionsmodus eingestellt werden, wobei der maximale Wert des Timers mit dem ICR Register bestimmt wird. Durch Änderung des maximales Wertes im Programm und im Taktgeber des Timers, kann die präzise PWM Frequenz zur Steuerung des Servomotors bestimmt werden. Mit dem Vergleichs-Register des Timers werden die Längen für beiden hohen Semi-Perioden des Signals bestimmt. Der Timer hat eine spezielle Vergleichseinheit, welche den Wert des Zählwerks beobachtet und für den Fall, dass es gleich dem Wert des Vergleichs-Registers ist, den Output-Wert der Vergleichseinheit ändert. Es folgt ein Programm-Code der Servomotor-Steuerbibliothek des HomeLab. Für die Ausführung nutzt es Parameter für Timer welche durch Makrofunktionen bestimmt werden. Zum Beispiel, wird die Periode durch die F-CPU Konstante angegeben, welche die Taktrate des Mikrocontrollers angibt. Wenn man Makros nutzt, müssen die Parameter des Timers für verschiedene Taktzyklen nicht berechnet werden und der Compiler konvertiert die Operationen mit Makros zu Konstanten. Dadurch erhöht sich der Programmspeicher nicht, und es wird auch nicht mehr Rechenzeit benötigt.
//
// Der WErt des Timers (20 ms) zum ERreichen der vollen PWM-Periode.
// F_CPU ist die Taktrate des Mikrocontrollers, welche durch 50 Hz und 8 dividiert wird.
//
//
#define PWM_PERIOD (F_CPU / 8 / 50)
//
// Mittlere Position der PWM des Servomotors (5 ms / 20 ms)
// Mittlere Position liegt bei 15/200 der vollen Periode.
//
#define PWM_MIDDLE_POS (PWM_PERIOD * 15 / 200)
//
// Faktor zur Konvertierung von Prozenten in Perioden(-100% to 100%).
// +1 wird addiert um sicherzustellen, dass die Halbperioden die Grenzen von 1 ms und 2 ms erreichen oder // etwas höher liegen.
//
#define PWM_RATIO (PWM_PERIOD / 20 / 2 / 100 + 1)
//
// Einrichtung der Pins.
//
static pin servo_pins[2] =
{
PIN(B, 5), PIN(B, 6)
};
//
// Servomotor vorbereiten.
//
void servomotor_init(unsigned char index)
{
// Pin des PWM Signals als Output.
pin_setup_output(servo_pins[index]);
// Einrichtung von Timer 1.
// Vorzähler = 8
// Schneller PWM Modus, wobei TOP = ICR
// OUTA und OUTB auf low im Vergleich.
timer1_init_fast_pwm(
TIMER1_PRESCALE_8,
TIMER1_FAST_PWM_TOP_ICR,
TIMER1_FAST_PWM_OUTPUT_CLEAR_ON_MATCH,
TIMER1_FAST_PWM_OUTPUT_CLEAR_ON_MATCH,
TIMER1_FAST_PWM_OUTPUT_DISABLE);
// Festlegung der Periode durch maximalen Wert.
timer1_set_input_capture_value(PWM_PERIOD);
}
//
// Festlegung der Postition des Servomotors.
// Parameter der Position liegen zwischen -100% und +100%.
//
void servomotor_position(unsigned char index, signed short position)
{
switch (index)
{
case 0:
timer1_set_compare_match_unitA_value(
PWM_MIDDLE_POS + position * PWM_RATIO);
break;
case 1:
timer1_set_compare_match_unitB_value(
PWM_MIDDLE_POS + position * PWM_RATIO);
break;
}
}
Das Beispielprogramm nutzt beschriebene Funktionen der HomeLab Bibliothek. Am Anfang des Programms wird der erste PWM-Signal Generator des Servomotors mit der //servomotor_init// Funktion gestartet. Der Wert der Position des Servomotors wird durch die Kanalnummer 3 des Analog-Digital-Konverters (ADC) empfangen, an dem ein Potentiometer an der Sensorplatine angeschlossen ist. Um die Reichweite von -100 % bis +100 %, die für die Steuerung des Servomotors notwendig, ist zu erhalten wird die Hälfte des Maximums (512) vom ADC Wert abgezogen und das Ergebnis durch fünf dividiert. Das Ergebnis ist +/- 102, kleine Ungenauigkeiten können unbeachtet bleiben, da Servomotoren sich auch in der Relation des PWM-Signals und des Drehwinkels unterscheiden. Die finale PWM Halbperiodenweite in Anwendungen muss über das "Try-and-Error"-Verfahren gefunden werden. Auch wenn die Funksteuerungen von RC-Modellen Möglichkeiten für ein präzises Setup besitzen. Wenn das Programm läuft, wird die Rotorposition des Servomotors je nach Position des Potentiometers verändert.
//
// Testprogramm des Motormoduls des HomeLab kit.
//
#include
#include
//
// Hauptprogramm.
//
int main(void)
{
short position;
// Einrichtung des ADC.
adc_init(ADC_REF_AVCC, ADC_PRESCALE_8);
// Einrichtung des Motors.
servomotor_init(0);
// Endlosschleife.
while (true)
{
// Auslesen der Position aus dem Potentiometer und Konvertiereung der Reichweite
// des Servomotors.
position = ((short)adc_get_value(3) - (short)512) / (short)5;
// Festlegung der Position des Servomotors.
servomotor_position(0, position);
}
}