Hallo
Hier kannst du das etwas entruckeln:
stellzeit=5;
Die 5 sind die Anzahl der Impulse die gesendet werden bevor die Position weitergerechnet wird. Je kleiner der Wert, umso schneller wird die Position geändert. Wenn die Zeit zu klein ist erreicht das Servo aber eventuell nicht die Zielposition!
Etwas schneller und flüssiger wird es, wenn du die Schrittweite der Einzelschritte erhöhst:
pos_temp++; bzw. pos_temp--;
Dann wird es aber etwas komplizierter, weil die Bewegung nur als beendet gemeldet wird, wenn pos_temp genau pos entspricht.
Einfacher Ansatz wäre hier, nur bestimmte Positionen zu verwenden, bzw. wenn die Ziele immer ein vielfaches der Schrittweite sind. Hier ein Beispiel dazu mit 3er-Schritten:
Code:
// "Weiche" Servoansteuerung mit sleep() mic 2.9.10
#include "RP6ControlLib.h"
char servo1(int pos)
{
static char pos_temp=0; // static = Werte zwischen den Aufrufen speichern
static char stellzeit=0;// dito
if (!pos_temp) // pos_temp beim ersten Aufruf initialisieren
{
pos_temp=pos; // Schnell zur gewünschten Position fahren
stellzeit=50; // innerhalb einer Sekunde
}
PORTC |= IO_PC4; // Impuls für aktuelle Position senden
sleep(pos_temp);
PORTC &= ~IO_PC4; // Impulspause
mSleep(200-pos_temp);
if(stellzeit) // solange Stellzeit aktiv werden gleichlange Impulse gesendet
{
stellzeit--;
}
else // Position weiterschalten
{
stellzeit=5; // Stellzeit für den nächsten Teilschritt 0,1 Sek.
if(pos_temp<pos) pos_temp+=3; // Position noch zu klein
else if(pos_temp>pos) pos_temp-=3; // Position noch zu groß
else return(0); // 0 bedeutet: "Ziel erreicht"
}
return(1); // 1 bedeutet: "Ziel noch nicht erreicht"
}
int main(void)
{
initRP6Control();
DDRC |= IO_PC4;
PORTC &= ~IO_PC4;
while(true)
{
while(servo1(9)); // Solange auf Position 9 fahren bis 0 zurückkommt
while(servo1(21)); // dito mit Position 21
}
return(0);
}
(ungetestet)
8-20 oder 10-19 würde auch funktionieren. Von den paar Codezeilen darf man natürlich keine Wunder erwarten. Wirklich gut geht es nur mit höherer Auflösung der Positionen. Das macht man dann aber normalerweise nicht mehr blockierend.
Wenn man sleep(position) durch eine Zählschleife ersetzt, kann man mehr unterschiedliche Positionen anfahren:
Code:
// "Weiche" Servoansteuerung mit Zählschleife mic 2.9.10
#include "RP6ControlLib.h"
char servo1(int pos)
{
static int pos_temp=0; // static = Werte zwischen den Aufrufen speichern
static int stellzeit=0;// dito
int pos_dummy, dummy; // Hilfsvariable für die Zählschleife
if (!pos_temp) // pos_temp beim ersten Aufruf initialisieren
{
pos_temp=pos; // Schnell zur gewünschten Position fahren
stellzeit=50; // innerhalb einer Sekunde
}
PORTC |= IO_PC4; // Impuls für aktuelle Position senden
//sleep(pos_temp);
pos_dummy=pos_temp; // Schleifenzähler laden
while(pos_dummy--) dummy^=pos_dummy; // Zeit verbummeln
PORTC &= ~IO_PC4; // Impulspause
mSleep(190);
if(stellzeit) // solange Stellzeit aktiv werden gleichlange Impulse gesendet
{
stellzeit--;
}
else // Position weiterschalten
{
stellzeit=5; // Stellzeit für den nächsten Teilschritt 0,1 Sek.
if(pos_temp<pos) pos_temp+=100; // Position noch zu klein
else if(pos_temp>pos) pos_temp-=100; // Position noch zu groß
else return(0); // 0 bedeutet: "Ziel erreicht"
}
return(1); // 1 bedeutet: "Ziel noch nicht erreicht"
}
int main(void)
{
initRP6Control();
DDRC |= IO_PC4;
PORTC &= ~IO_PC4;
while(true)
{
while(servo1(2000)); // Solange auf Position 2000 fahren bis 0 zurückkommt
while(servo1(4000)); // dito mit Position 4000
}
return(0);
}
(ebenfalls ungetestet)
Ob 2000 und 4000 passen kann ich grad nicht sagen, das sind nur "gefühlte" Werte ;)
Aber ehrlich, das wird irgendwann eine Sackgasse.
Gruß
mic
Lesezeichen