... 1-3
Servos bewegen ... ein Tip geben oder vielleicht ein Beispielcode ...
Hi Jobo,
ich bin nicht sicher, dass Dir der Servoabschnitt aus dem RNWi ssen doll helfen wird. Interessant wäre es noch zu wissen, welchen Controller Du benutzt und wie schnell der getaktet ist.
Für diese Aufgabe - mehrere Servos auf unterschiedliche Werte setzen - gibt es aber eine Menge von Beispielen.
Eine ziemlich simple Möglichkeit wäre diese Soft-PWM (dieses Beispiel ist eine modifizierte, leider auf die Schnelle nicht getestete Variante) deren Orignal auf meinem WALL R zur Steuerung des Lenkservos läuft. Umgebung ist ein mega168/328 - 20 MHz. Meine Lösung basiert auf einem 50 µs-Timer-Interrupt, der bei mir für alle möglichen zeitgesteuerten Aufgaben und zum Messen der Bordzeit verwendet wird. Mit diesem Beispiel kannst Du einen Servo auf 10 verschiedene Positionen fahren - die aber nicht beliebig wählbar sind. Vielleicht hilfts.
Code:
// Definiere ein paar Variablen:
// . . . . . .
//
volatile int16_t Iservo; // Counter für 20 ms-Periode
//
volatile int16_t Isvs1, Isvs2, ... // Stellwert (Pulslänge) für Servo1, ~2 ...
//
// ---- und danach Timerinitialisierung
// ============================================================================== =
// === Initialisierung fuer Timer2 mega168
void TC2TMR_init(void) // Init Tmr/Cntr 2, 8-Bit auf 20 kHz = 50 µs
{ //
TCCR2A |= (1<<WGM21); // Timer im CTC-Mode, Top=OCR2A doc S 157
TCCR2B |= (1<<CS21); // Prescaler 1/8 / Clock <- CPU doc S 158
OCR2A = 124; // Preset 125 für 50µs bei 20Mhz
TIMSK2 |= (1<<OCIE2A); // Tmr/Cntr2 CompareA interrupt enabled
} //
// ============================================================================== =
// Vor dem Aufruf der Timerinitialisierung sollten die Variablen
// Iservo, Isvs1 etc. auf Null gesetzt werden.
//
// ---- und ISR zur Servosteuerung
// ============================================================================== =
// === Nicht unterbrechbare ISR für timer2 ===================================== =
// Routine zählt hoch im Takt 20 kHz = 50 µs.
ISR(TIMER2_COMPA_vect) // Vektor 7
{ //
// - - - - - - - - - - - - - - -
// Es folgt die Servoroutine. Servo wird mit der/den Variablen Isvs1... gesteuert:
if (Iservo < 400) //Servo-Timer läuft von 1 .. 400
{ // 400 * 0,050 ms => 20 ms.
Iservo ++; //
if (Iservo == Isvs1) // Wenn Servozeitcounter Iservo gleich Isvs1
PORTB &= ~(1<<PB2); // Servopin1 ausschalten
if (Iservo == Isvs2) // Wenn Servozeitcounter Iservo gleich Isvs2
PORTB &= ~(1<<PB3); // Servopin2 ausschalten
} //
else // Servo-Timer hat Ende=400 erreicht, daher
{ //
Iservo = 0; // Servotimer zurückstellen auf Null und
PORTB |= (1<<PB2); // ... Servopin1 einschalten für nächste Rampe
PORTB |= (1<<PB3); // ... Servopin2 einschalten für nächste Rampe
} //
} //
// ============================================================================== =
// Die Werte Isvs1, Isvs2 ... werden im Main oder einer passenden Routine gesetzt
// ACHTUNG: beim Arbeiten mit Isvs1, Isvs2 etc. vor und hinterher cli(); /sei/();
// um Pannen beim zweibittigen Zugriff zu vermeiden.
Viel Erfolg und schreib auch, obs so läuft oder ob Du inzwischen etwas Anderes gefunden hast.
Nachtrag (hatte es irrtümlich gelöscht): in diesem Beitrag findest Du ein Lösungsbeispiel für mehrere Servos - aber in Bas com.
Lesezeichen