PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : einfacher schnellerer Timer zur Ansteuerung von Servos



WarChild
03.04.2008, 00:16
Hallo,

ich wollte mal fragen, ob es eine "Stopwatch" mit höherer auflösung als die vorhandene gibt?
Selbst die sleep() Funktion ermöglicht nur eine Pulsgeneration auf 10° genau. Gibt es da vielleicht eine kleine Erweitrung für die Lib???

Hier mal mein Code. Mein Testservo hängt am ADC3 des M32 Boards.


// Includes:

#include "RP6ControlLib.h" // The RP6 Control Library.
// Always needs to be included!
#define CLOCKWISE 4 //minimal value = 4
#define COUNTERCLOCKWISE 22 //maximal value = 22
#define SPEED 0 //set impulse increasement/decreasement Speed in ms (0 bis <40 ist Ruckelfrei)
#define ADJUSTTIME 200 //Set the servo's time needed to rotate 180° in ms (ausbauen und Pausenzeit auf ein minimum reudzieren)



// Main function - The program starts here:

int main(void)
{
initRP6Control(); // Always call this first! The Processor will not work
// correctly otherwise.

setStopwatch1(0);
startStopwatch1();
DDRA |= (ADC3);

uint8_t pulse = CLOCKWISE;
uint8_t countup = true;

while(true)
{
PORTA |= ADC3;
sleep(pulse);
PORTA &= ~ADC3;
mSleep(20); //könnte man noch durch eine Stopwatch ersetzen

if(getStopwatch1() >= SPEED) // nach ablauf der Zeit wird die nächste Position angefahren
{
if (pulse>=COUNTERCLOCKWISE) // wechsel der drehrichtung
{
countup = false;
mSleep(ADJUSTTIME); // muss noch optimiert werden, damit es pausenlos läuft
}
else if (pulse<=CLOCKWISE)
{
countup = true;
mSleep(ADJUSTTIME);
}

if (countup == true) // ändrung der Richtung
pulse++;
else
pulse--;

setStopwatch1(0);
}
}
return 0;
}

Das ist schon recht Simpel gehalten, aber dennoch mit einem besseren Timer ausbaufähig.

mfg WarChild

Pr0gm4n
03.04.2008, 14:05
Hi,

warum machst du das nicht mit einer Software-PWM?

ich kann dir zwar noch nicht sehr viel darüber sagen, aber eins weis ich: Mit einer Software-PWM kann man Servos auf bis zu (1/255)*180° oder (1/1024)*180° verschiedene Stellwinkel bringen, je nachdem, ob man einen 16 Mhz Timer oder einen 8 Mhz Timer einsetzt

Dazu kannst du dir vielleicht überlegen, einen M32 für 3,00€ bei Reichelt zu kaufen, der hat ein paar Timer, den lässt du dann per I²C die Servostellungen empfangen und kannst ihm dann mit ner Software-PWM die Servos ansteuern lassen

ich sag deshalb Software-PWM, weil es auch µCs gibt, die eine eingebaute Hardware-PWM haben, wie man die dann ansteuert weis ich leider nich...

ansonsten kannst du das natürlich auch direkt an der M32 machen, die hat ja auch ein paar freie Timer

Ich weis jetzt auch nicht, was er kostet aber dieser Servochip für 20 Servos soll ja sehr empfehlenswert sein...

MfG Pr0gm4n

WarChild
03.04.2008, 14:29
Mit welchen Befehlen spricht man die internen Timer des AtMega32 an?

Vielen Dank im vorraus.

Was mir etwas fehlt ist der simple 10 us Takt, den den ich von der Siemens Step 7 kenne. Damit lassen sich beliebig viele "Stopwatches" erstellen, indem man einfach die takte zählt...

Ceos
03.04.2008, 14:38
naja mit "befehlen" geht das nicht, du musst die steuerregister der timer entsprechend einstellen und evetuell die Timer-ISR schreiben ... ich verweise hier mal aud das datenblatt des mega32, ich würds dir ja gern erklären iss aber vll. n bisschen viel ohne das datenblatt zu rate zu ziehen

WarChild
03.04.2008, 14:42
:cry: Ich hasse das Datenblatt :cry:

Warum gibt es für die Atmega32 funktionen nur kein ähnliches Listing wie für die Standardbibliotheken...

Aber trotzdem danke!

mfg WarChild

Ceos
03.04.2008, 14:48
mh das datenblatt ist doch sehr übersichtlich ... nimm zum beispiel timer0 und liess dir die beschreibung zu den registern durch(im letztenabschnitt zu timer0), da sind die ganzen flags, register und ihre bedeutung wunderschön erklärt ... das datenblatt kann man nicht hassen man kann nur zu faul sein es zu lesen ... ich kanns ja wenigstens mal verscuhen zu erklären aber erst wenn ich zu hause bin :p


EDIT wenn du schonmal mit den megas gearbeitet hast, müsste dir doch klar seni das es keine "funktionen" gibt, sondern ausschliesslich mit registern gearbeitet wird ?!

SlyD
03.04.2008, 19:33
Hallo WarChild,

schau Dir doch nochmal den RP6Lib Header an: timer.
Das ist eine Variable die alle 100us erhöht wird.

MfG,
SlyD

Edit:
die Variable heisst natürlich nicht system_timer sondern nur "timer".
Sorry hatte ich grad irgendwie falsch im Kopf.

Dirk
03.04.2008, 21:54
Hallo WarChild,

schon 'mal in diesem Thread gestöbert?
Da gibt's (am 8.10.07) von mir z.B. eine fertige Hardware-PWM Servoansteuerung mit der M32:
https://www.roboternetz.de/phpBB2/viewtopic.php?t=34407

Gruß Dirk

WarChild
05.04.2008, 14:03
Ich habe bei durchlesen der Lib eine ganz simple funktion gefunden mit der ich wohl weiter kommen werde...

delayCycles();

Das ist zwar ne blockende funktion, aber ich denke mal dass der Chip in den 2,5 ms der pulsgeneration ruhig einmal aussetzen kann, da der Chip dann knapp 18ms bis zum nächsten Puls Zeit hat, um alles andere zu erledigen, finde ich sind 12,5% Auslastung kein problem.

Ich plane in einer funktion alle 18 Servos, meines Hexpods anzusteuern. (folgede Werte sind auf meine Servos bezogen)
400us Pulsdauer sind Minimum und Rechtsanschlag. 10us Pulsdauer mehr entsprechen ungefähr einem Grad. Also Lasse ich zunächst alle Ports High setzen, dann wird nach 400us im 10us Abstand, =160 delay Cycles später, überprüft welche Pulse hier enden und werden abgeschaltet bis er bei 2200us angelangt ist und eigentlich alle Ports low sein müssten. Also werden Nahezu beliebig viele Servos simultan mit verschiedenen pulsen versorgt. Allerdings müsste man die Bearbeitungsdauer, um die Ports abzuschalten noch von den delay cycles abziehen, damit das signal später nicht verfälscht ist. Wie lange mad das dauern, eine if-Bedingung zu prüfen und einen Pin auf low zu schalten? 1-2 cyclen???

Allerding komme ich in Portbedrängnis, denn ich habe nur 6 freie ADCs und 8 freie I/Os also fehlen 4. Ich bin am überlegen welche Pins ich umfunktionieren kann. ich würde ungerne auf I²C und Display verzichten. Die LEDs sind anscheinend mit den LCD Pins doppelt belegt, sonst wäre es ja auch zu einfach, weils genau 4 sind...
Da gibt es also noch Int0, Int1 und Int2. Die sind doch eigentlich überhaupt nicht belegt, die sind nur im XBus system überall verfügbar nicht wahr?(Ich habe sie auch bei der Base nicht belegt)
Fehlt noch einer... im Zweifelsfall baue ich das Mic aus uns nutze den Ausgang.


mfg WarChild

Pr0gm4n
05.04.2008, 17:34
Oder du baust den Pieper weg und schaust dann, ob du deine Servos nich quasi mit beep(); steuern kannst :)

Ich fänds witzig mal zu nem Motor zu sagen:

"Hey du, gib mir mal ein a³ bitte...."

und der Motor Stellt sich dann auf ne bestimmte Position^^


MfG Pr0gm4n

Pr0gm4n
05.04.2008, 21:24
Ach ja, ich wollte noch ne kleine Frage dazu stellen:

Warum holst du dir für deine ganzen Servos dann nich nen Mega32 extra, das kostet dich mit Grundschaltung bei Reichel 5-7€ und du kannst mit diesem delayCycles(); (sofern es das da auch gibt) die Servos alle zusammen ansteuern, also halt eine Funktion schreiben, bei der das mit einer blockierenden Delayfunktion auch geht(etwas viel schreibarbeit, aber doch machbar)

etwas komfortabler geht es natürlich mit nicht-blockierenden Delayfunktionen, danach suche ich aber selber grade...

Wenn ich nix finde oder mal lust zum proggen hab mach ich dir nen entwurf zu o.g. funktion für delayCycles();


man muss dabei vermutlich aber die Werte von Servo1 bis ServoX per Parameter übergeben denke ich, das ist zwar auch wieder ein bisschen was zum schreiben, aber wenns nicht gleich 100 sind geht das schon

Wenn ihr so eine nicht-blockierende Delayfunktion in der Standard AVR-Lib findet, dann bitte unbedingt mitteilen, damit geht das alles viel einfacher, man liest einfach Variablen Servo1 bis ServoX aus und stellt in eine while-Schleife lauter if-Bedingungen mit if(delayvar==Servo1){<Servoleitung auf low>}
und am Anfang jedes mal die delayvar einlesen...


Kurze Zusatzfrage: Kann man bestimmen, wie lange eine Schleife in ms braucht, 1x durchzulaufen?
das wäre dann am einfachsten, wenn das geht

man kalibriert einmal am Anfang im Programm nach der Zeit, die die Schleife braucht und dann in der endlosschleife gibt es eine Variable, die sich bei jedem Durchlauf um 1 erhöht

Mit bestimmen meine ich in diesem Fall, ob das eine Rolle spielt, ob eine if-Bedingung mit Port-auf-low-setzen ausgeführt wird oder nur abgefragt und die Bedingung false ist



void task_Servos()
{
<Delay> //hier genau 1 Sekunde Delay für unteren Anschlag
task_0Grad();
task_1Grad();
task_2Grad();
task_3Grad();
task_4Grad();
task_5Grad();
task_6Grad();
:
:
:
:
task_180Grad();
}

void task_0Grad()
if(Servo1==0)
{//Servoleitung auf Low
}
if(Servo2==0)
{//Servoleitung auf Low
}
:
:
:
if(ServoX==0)
{//Servoleitung auf Low
}

}

void task_1Grad()
{
<Delay> //hier lange genug für ein weiteres Grad warten
if(Servo1==1)
{//Servoleitung auf Low
}
if(Servo2==1)
{//Servoleitung auf Low
}
:
:
:
if(ServoX==1)
{//Servoleitung auf Low
}

}

void task_2Grad()
{
<Delay> //hier lange genug für ein weiteres Grad warten
if(Servo1==2)
{//Servoleitung auf Low
}
if(Servo2==2)
{//Servoleitung auf Low
}
:
:
:
if(ServoX==2)
{//Servoleitung auf Low
}

}





usw.


Naja, da könnte man dann unabhängig von der Anzahl der Timer belibig viele Servos ansteuern, vorausgesetzt man hat genug Pins und aber auch Servos:)


MfG Pr0gm4n

EDIT: Wenn ich mich jetz nicht recht irre, dann muss man glaube ich aufpassen, dass man am Anfang alle task-Funktionen als Prototypen anführt, damit das keinen Fehler ausgibt (Prototyp der Funktion printf(Parameter) ist: printf(Parameter); das man einfach ganz oben unter dem "Include" aufruft)

WarChild
08.04.2008, 00:58
Hallo Alle zusammen...

Ich denke ich habe hier eine Narrensichere die Lösung:



// Includes:

#include "RP6ControlLib.h" // The RP6 Control Library.
// Always needs to be included!
#define MIN 4 //Servo's pulse length limits 1 = 0,1ms
#define MAX 22
#define CLOCKWISE 45 //Rotation angles in Degree (actually the pulse leght = MIN*0.1ms + CLOCKWISE*0.001ms [in my case its one degree])
#define COUNTERCLOCKWISE 135
#define SPEED 10 //set impulse increasement/decreasement Speed in ms (0 = fastest)
#define ADJUSTTIME 1000 //if the servo's movement is very fast then set at least the servo's time needed to rotate the required angle in ms else use it as a break between changing movedirection
#define CYCLES 15 //set the individual ammount of Cycles made in 1us (15-16 @16MHz / 7-8 @8MHz) (Use this to adjust on a test angle)

// Main function - The program starts here:

int main(void)
{
initRP6Control(); // Always call this first! The Processor will not work
// correctly otherwise.

initLCD(); // Initialize the LC-Display (LCD)
// Always call this before using the LCD!

// Write some text messages to the UART - just like on RP6Base:
writeString_P("\n\n _______________________\n");
writeString_P(" \\| RP6 ROBOT SYSTEM |/\n");
writeString_P(" \\_-_-_-_-_-_-_-_-_-_/\n\n");

// Set the four Status LEDs:
setLEDs(0b1111);
mSleep(500);
setLEDs(0b0000);

// Play two sounds with the Piezo Beeper on the RP6Control:
sound(180,80,25);
sound(220,80,0);

showScreenLCD("<<RP6 Control>>", "<<LC - DISPLAY>>");
mSleep(1000);
showScreenLCD(" Servo Control ", " Test Program ");
mSleep(1000);


setStopwatch1(0);
startStopwatch1();
setStopwatch2(0);
startStopwatch2();

DDRA |= (ADC3);

uint8_t pulse = CLOCKWISE;
uint8_t countup = true;

uint8_t counter = 0;

while(true)
{
if (getStopwatch2() >= 18) // hier geschiet die eigentliche Pulserzeugung alle 20ms
{
PORTA |= ADC3; // alle anzusteuernden Ports werden auf high gesetzt
sleep(MIN);
for (counter=0;counter<(MAX-MIN)*10;counter++) // jeder schleifendurchlauf bedeutet 1° Winkeländerung
{
delayCycles(CYCLES);
if (pulse == counter) // sobald der gewünschte Winkel erreicht wird, Wird der entsprechende Port auf low gesetzt
PORTA &= ~ADC3;
}
setStopwatch2(0);
}

if(getStopwatch1() >= (ADJUSTTIME + SPEED)) // nach Ablauf der Zeit wird die nächste Position angefahren
{
setStopwatch1(ADJUSTTIME);
if (pulse>=COUNTERCLOCKWISE) // wechsel der drehrichtung
{
countup = false;
setStopwatch1(0);
}
else if (pulse<=CLOCKWISE)
{
countup = true;
setStopwatch1(0);
}

if (countup == true) // änderung der Richtung
pulse++;
else
pulse--;
}
}
return 0;
}


Das meiste ist der standard Quellcode
In der Endlosschleife sind zwei If()-Bedingungen, die eine erzeugt das Servo-Signal und die andere erzeugt eine Pendelbewegung. Eigentlich war das nicht Ziel dieses Threads, aber sonst ist das so langweilig... ein still stehender Servo... =D>
Die Pulsvariable könnte man auch durch beliebige eigene Funktionen generieren lassen.
Da mein uC bei 16MHz maximal eine genauigkeit von 0,06us schafft (= 1 Takt), finde ich dass mein bis auf 1us genaues Signal keine schlechte alternative zu den aus meiner Sicht eher komplizierten timern ist.
Der Servo hat eine Auflösung von 180 Stellungen, (360 sind auch leicht möglich, aber da der Servo ehh im 20ms takt ruckelt, fand ich es nicht deutlich flüssiger mit 360er Auflösung).
Ich konnte das prgramm jetzt noch nicht mit mehreren Servos testen, da ich z.Zt nur einen Servo am M32 angeschlossen habe.(Ich muss erst noch die Servokabel auseinanderpulen, um sie anzuschließen)
Prinzipiell, sollte man jedoch beliebig viele Servos gleichzeitig parallel ansteuern können. Vielleicht muss man dann jedoch wegen des steigenden rechenaufwandes die CYCLES der "delayCycles()" reduzeren.

mfg WarChild

Pr0gm4n
08.04.2008, 13:11
Ok, habs jetzt mal gelesen und ist so weit ok!!

Wie du schon sagtest haste es ja auch schon getestet...


Mal die Frage: isses nich mit meiner Funktion dann einfacher, mehrere Servos anzusteuern?

Ich überlege grad, ob man denn bei mir mit einbeziehen muss, dass er recht viel Code zu durchlaufen hat und somit die Rechenzeit die Servostellung beeinträchtigt

Ich hoffe jetz mal nicht...


Kann mir jemand sagen, wo ich mir die ganzen Befehle die ich bei anderen AVRs (halt nicht am RP6) habe, damit ich da mal nach einer Taktzähl-Funkt. gucken kann, die nicht blockiert, denn damit wär das ganze echt einfacher

reicht es dann das mit Interrupts zu machen oder soll man das dann lieber mit if-Bedingungen abfragen?



MfG Pr0gm4n


PS: ansonsten werd ich jetz dann meine Version mal ausprogrammieren, da fehlte ja noch einiges
Ich denke die ist dann einfacher zu verstehen und man muss nur die Funktion aufrufen, die Servostellungen in Grad angeben und den Rest erledigt der Code

Wenn man jetzt nicht immer 20 Servos braucht könnte man auch genausogut eine zusätzliche Funktion schreiben, in der das alles nur mit 5 Servos gemacht ist, nur um dem Anwender Schreibarbeit zu ersparen

Edit: Ich würde gerne am Anfang kalibrieren, sodass ich dann einmal feststelle, wie lange die delayCycles(); bei dem Wert 1 braucht und danach dann mein Programm richten, denn es soll möglichst auf alle AVRs protabel sein

Kann ich dafür möglicherweise die eingebauten Timer hernehmen oder zeigen die mir solche kleinen Werte nicht an?

Wenn nicht muss ich es halt mit 1 Mio. delayCycles machen, dann gehts aber, oder?

Pr0gm4n
08.04.2008, 16:34
Hallo!!

Hier nun mein überarbeiteter Vorschlag-Code für eine Ansteuerung von 5 Servos:



#include <avr/io.h> /* Servoansteuerung AVR --- 8.4.2008 Pr0gm4n*/

//Defines:


#define SERVOMAX 180 //Anzahl der Schritte, die möglich sein sollen.


//alle defines hier kann man irgendwo in seinem Programm machen,
//doch sie sind nötig um Servos mit der Funktion task_Servos anzusteuern

//z.B. #define SERVOREGISTER DDRA
//#define SERVOREGISTER1
//#define SERVOREGISTER2
//#define SERVOREGISTER3
//#define SERVOREGISTER4
//#define SERVOREGISTER5
//z.B. #define SERVOPORT PORTA
//#define SERVOPORT1
//#define SERVOPORT2
//#define SERVOPORT3
//#define SERVOPORT4
//#define SERVOPORT5
//z.B. #define SERVOBIT 0
//#define SERVOBIT1
//#define SERVOBIT2
//#define SERVOBIT3
//#define SERVOBIT4
//#define SERVOBIT5




//Prototypen:
void task_Servos(uint Servo1, uint Servo2, uint Servo3, uint Servo4, uint Servo5);
void task_Grad(uint Servo1, uint Servo2, uint Servo3, uint Servo4, uint Servo5, uint Grad);


/************************************************** *******************************************/
/****************** Prototypen ende, jetzt: Funktionen *************************************/
/************************************************** *******************************************/


//Funktionen:


void task_Servos(uint Servo1, uint Servo2, uint Servo3, uint Servo4, uint Servo5)
{



SERVOREGISTER |=(1<<SERVOBIT1);
SERVOREGISTER |=(1<<SERVOBIT2);
SERVOREGISTER |=(1<<SERVOBIT3);
SERVOREGISTER |=(1<<SERVOBIT4);
SERVOREGISTER |=(1<<SERVOBIT5);
SERVOPORT1 |= (1<<SERVOBIT1);
SERVOPORT2 |= (1<<SERVOBIT2);
SERVOPORT3 |= (1<<SERVOBIT3);
SERVOPORT4 |= (1<<SERVOBIT4);
SERVOPORT5 |= (1<<SERVOBIT5);
<Delay> //hier genau 1 ms Sekunde Delay für ersten Anschlag

for(int i=0;i<(SERVOMAX+1);i++)
{
task_Grad(uint Servo1, uint Servo2, uint Servo3, uint Servo4, uint Servo5, i);
<Delay> //hier genau 1/180 ms Sekunde Delay und auch zwischen allen anderen
//auch sehr leicht auf mehr als 180 Schritte ausweitbar durch höhere Zahlen für Grad und und Servo1-5

}//for-Schleife schliessen (nur zur besseren Übersicht)

}


void task_Grad(uint Servo1, uint Servo2, uint Servo3, uint Servo4, uint Servo5, uint Grad)
{
if(Grad >(SERVOMAX-1)) Grad = SERVOMAX; //Grad und die Servowerte auf das Maximum beschränken
if(Grad <1) Grad=1; //Wenn man dies nicht macht kann es passieren, dass es
if(Servo1 >(SERVOMAX-1)) Servo1 = SERVOMAX; //keinen übereinstimmenden Wert für ServoX und Grad gibt
if(Servo1 <1) Servo1 = 1;
if(Servo2 >(SERVOMAX-1)) Servo2 = SERVOMAX;
if(Servo2 <1) Servo2 = 1;
if(Servo3 >(SERVOMAX-1)) Servo3 = SERVOMAX;
if(Servo3 <1) Servo3 = 1;
if(Servo4 >(SERVOMAX-1)) Servo4 = 180;
if(Servo4 <1) Servo4 = 1;
if(Servo5 >(SERVOMAX-1)) Servo5 = SERVOMAX;
if(Servo5 <1) Servo5 = 1;
if(Servo1==Grad)SERVOPORT1 &= ~(1<<SERVOBIT1); //Servo 1 Signal beenden
if(Servo2==Grad)SERVOPORT2 &= ~(1<<SERVOBIT2); //Servo 2 Signal beenden
if(Servo3==Grad)SERVOPORT3 &= ~(1<<SERVOBIT3); //Servo 3 Signal beenden
if(Servo4==Grad)SERVOPORT4 &= ~(1<<SERVOBIT4); //Servo 4 Signal beenden
if(Servo5==Grad)SERVOPORT5 &= ~(1<<SERVOBIT5); //Servo 5 Signal beenden
}




Im Moment versuche ich, der Funktion task_Servos noch einen Parameter servos_count hinzuzufügen. Dabei soll festgelegt werden, wie viele Servos angesteuert werden sollen.
bisherige Ideen:




if(servos_count=1) task_1_Servo(Parameter);
if((servos_count>1)&&(servos_count<6)) task_5_Servos(Parameter);
if((servos_count>5)&&(servos_count<11)) task_10_Servos(Parameter);
if(servos_count>10)task_max_Servos(Parameter);



Ich bin mir nicht sicher, ob es stört, dass man für Servo7-10 keinen Wert hat, andernfalls muss man sie als 0 definieren und dann mit den richtigen Werten überschreiben


eine weitere Möglichkeit wäre es, die Servo-Stellungen in einem Array zu übergeben und dann die Elemente von 0-(servos_count-1) abzufragen

diese Möglichkeit halte ich für sinnvoller


MfG Pr0gm4n

EDIT: An meinen Code muss noch ein Delay von 18ms angefügt werden, da man Servos nur alle 20 ms neu mit Signalen versorgt und maximale 2ms Signal nötig sind, um einen Servo auf Anschlag zu stellen

Pr0gm4n
09.04.2008, 20:29
Hi nochmal,

ich hab da mal eine Frage: Ich möchte die Servofunktion auch auf alle anderen ATMegas portabel haben und brauche nun eine Delayfunktion, die in etwa einfach den Takt des µCs hat und ich dann kalibrieren kann

Es reicht auch ein Takt von 10us, aber am liebsten würde ich einfach gerne einen Link zur AVR/io.h, die man ja überall includen kann

wenn ich die Servofunktion dann fertig habe, denke ich sie wird auch auf dem RP6 funktionieren, oder muss man dann noch extra die AVR/io.h includen?

Ich werde mir auf jeden Fall eine Art Servolibrary schreiben, die man bei include reinschreibt, im makefile angibt

danach einfach nur noch die Funktion aufrufen zu müssen wäre doch super, oder?


MfG Pr0gm4n

WarChild
11.04.2008, 16:44
Ich dachte mir das so ähnlich... ich wollte einfach ne funktion in der Control library hinzufügen... ist ja nicht soo viel an Quellcode, dass ich dafür eine ganze Lib anlegen würde..
Das mit der Portabilität ist so eine sache, letztendlich muss man die funktion ehh auf die individuelle Anzahl von servos aufbauen und die sind außerdem bei jedem an anderen Ports also soll meine lösung auch nur bei mir funzen.

ich habe jetzt die ersten erfolgreichen versuche mit meiner auf drei sevos erweiteren version des von mir oben geposteten codes ausgeführt.

mfg WarChild

PS: eigentlich war meine frage bereits mit der delayCycles(); funktion geklärt.

Pr0gm4n
11.04.2008, 17:49
Hi,

das mit den servos an verschiedenen Pins hab ich ja gelöst, indem man die Angaben (oben in meinem Code) irgendwo im Programm definiert und somit dann die eigenen Pins reinschreiben kann. das mit der individuellen Zahl an Servos kann man auch umgehen, du kannst ja bei ner Funktion mit 20 Servos dann das aufrufen:

task_Servos(90, 90, 90, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 180); //das letzte ist die Anzahl der zählschritte


damit musst du nur die Register der servos 4-20 auf unbenutzte Pins legen



MfG Pr0gm4n

PS: ich werde als Zusatz noch eine Funktion eibauen, bei der man als Parameter die Stellung des Servos und den Pin angiebt und dann kann man auch einzelne Servos ändern

Was ich aber in dem Code noch unbedingt beachten muss, ist dass man ja alle 20 ms senden muss und ich so nur die Servos einmal ausrichten würde. Ich werde das aber vermutlich so lassen, denn der µC hat eigentlich nix anderes zu tun und das kann ich dann auch mit in meiner while(1) - Schleife berücksichtigen