Na prima. 1000/5000 sind die Werte für die Impulse min/max, 40000 die 20ms-Wiederholung. So könntest du knapp deine 12 Servos ansteuern wenn du pausenlos Impulse senden würdest. Das ist zwar ein Weg der vermutlich in die Sackgasse führt, aber du brauchst erst etwas Übung mit Servos. Das Ansteuern kannst du auch mit deinen drei Servo lernen.
Zuerst solltest du den Wert für die Pause optimieren. Wenn er zu groß ist zuckeln die Servos. Die Impulspause ist nun auch der Platz im Programm zum Berechen neuer Servopositionen. Dazu verwendest du dann Variablen für die Positionen und nach der Pause, noch vor dem Start der nächsten Impulse, berechnest du die neuen Positionen und änderst die entsprechenden Variablen. Die Zeit die das Programm dafür benötigt gewinnst du durch Verkürzung der Pausenzeiten. (Wenn du dich damit beschäftigst: die Schwankungen der Pausezeiten durch unterschiedliche Impulsdauern sollte man auch berücksichtigen. Impulse+Pause sollte ca. 20ms sein)
Code:
#include <avr/io.h> // I/O Port definitions
//#include <avr/interrupt.h> // Interrupt macros (für cli)
#define servo1_port PORTB
#define servo1_ddr DDRB
#define servo1_pin PB0
#define servo2_port PORTB
#define servo2_ddr DDRB
#define servo2_pin PB1
#define servo3_port PORTB
#define servo3_ddr DDRB
#define servo3_pin PB2
#define servo1_on servo1_port |= 1<<servo1_pin
#define servo2_on servo2_port |= 1<<servo2_pin
#define servo3_on servo3_port |= 1<<servo3_pin
#define servo1_off servo1_port &= ~(1<<servo1_pin)
#define servo2_off servo2_port &= ~(1<<servo2_pin)
#define servo3_off servo3_port &= ~(1<<servo3_pin)
uint16_t i, stellzeit, dummy;
uint16_t servo1_position, servo2_position, servo3_position;
int main(void)
{
servo1_ddr |= 1<<servo1_pin; // Pins als Ausgang definieren
servo2_ddr |= 1<<servo2_pin;
servo3_ddr |= 1<<servo3_pin;
servo1_off; // und auf low schalten
servo2_off;
servo3_off;
servo1_position=1000;
//cli(); // keine Störungen erlauben
while(1) // solange Saft im Akku...
{
stellzeit=100; // 100 mal den Impuls senden
while(stellzeit--)
{
servo1_on; // Impuls für erstes Servo erzeugen
for(i=0; i<servo1_position; i++) dummy^=i;
servo1_off;
for(i=0; i<40000; i++) dummy^=i; // Impulspause
}
// neue Position berechen
if(servo1_position == 1000) servo1_position=5000; else servo1_position=1000;
}
return(0);
}
Das wird dann auch zum Ziel führen wenn man schrittweise optimiert. Servoansteuerung als Funktion gestalten und zyklisch aufrufen, dann als ISR im Hintergrund. Aber das ist eher ein Ausblick auf die nächsten Hürden.
Gruß
mic
Lesezeichen