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:
(ungetestet)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); }
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:
(ebenfalls ungetestet)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); }
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







Zitieren

Lesezeichen