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