Hallo,
ich arbeite nach wie vor an einer Kinematik für meinen Quadruped. Ich habe das erste Bein soweit zum laufen bekommen, dass er auf dem Boden Kreise "malt". Nun wollte ich mir das nächste Bein vornehmen und musste feststellen, dass nach dem Hinzufügen des 2. Beins die Servos nichtmehr richtig positionierten (leichte Abweichung). Eine genauere Debugging-Untersuchung ergab, dass das Interrupt welches alle 10µs ausgelöst wird selber 17µs braucht (für beide Beine).
Ich habe natürlich die Möglichkeit das Interrupt in längeren Abständen auszulösen, das kostet mich dann aber die genaue Auflösung der Servo-Ansprechzeiten...
Anderseits kommen mir 17µs sehr lange für die wenigen Befehle vor - vielleicht sieht hier ein erfahrenen Programmierer eine Optimierungs-Chance?!
Code:
#define F_CPU 16000000
...
// Servo 1
#define PAD_SERVO_0 5
#define PORT_SERVO_0 PORTC
#define DDR_SERVO_0 DDRC
...
volatile unsigned char servo_pos[12] = {90, 90, 100, 200, 160, 160, 100, 100, 100, 200, 200, 200};
...
void servo_init()
{
TIMSK |= (1 << OCIE2);
TCCR2 |= (1 << WGM21) | (1 << CS20);
OCR2 = F_CPU / 100000; // <------------ INTERRUPT alle 10µS
// Servo-Ports auf Output
DDR_SERVO_0 |= (1 << PAD_SERVO_0);
...
// Interrupt global aktivieren
TIMSK |= (1<<TOIE1);
sei();
}
ISR (TIMER2_COMP_vect)
{
// --------------------------------------- ab hier (0 µs)
static int count;
// Bein 0
if (count > servo_pos[0]) PORT_SERVO_0 &= ~(1 << PAD_SERVO_0);
else PORT_SERVO_0 |= (1 << PAD_SERVO_0);
if (count > servo_pos[1]) PORT_SERVO_1 &= ~(1 << PAD_SERVO_1);
else PORT_SERVO_1 |= (1 << PAD_SERVO_1);
if (count > servo_pos[2]) PORT_SERVO_2 &= ~(1 << PAD_SERVO_2);
else PORT_SERVO_2 |= (1 << PAD_SERVO_2);
// Bein 1
if (count > servo_pos[3]) PORT_SERVO_3 &= ~(1 << PAD_SERVO_3);
else PORT_SERVO_3 |= (1 << PAD_SERVO_3);
if (count > servo_pos[4]) PORT_SERVO_4 &= ~(1 << PAD_SERVO_4);
else PORT_SERVO_4 |= (1 << PAD_SERVO_4);
if (count > servo_pos[5]) PORT_SERVO_5 &= ~(1 << PAD_SERVO_5);
else PORT_SERVO_5 |= (1 << PAD_SERVO_5);
if (count < 2000) count ++;
else count = 0;
// --------------------------------------- bis hier 17µS
}
int main()
{
servo_init();
...
Der Roboter hat 4 mal 3 Servos pro Bein!
Wenn der Debugger mir eine Teit von 17µS bei 4Mhz anzeigt - kann ich die Zeit dann bei 16Mhz vierteln?!
Mit freundlichen Grüßen Erik
Lesezeichen