Hallo

Mein Ansatz für eine Servoansteuerung mit dem RP6:

Bild hier  
(Bild anklicken für 1,8MB mpg)

Hardware ist ein 5€-Miniservo von Conrad, aufgeklebt auf den RP6 mit einem Power-Strip. Aus dem Stecker(JBL) habe ich den Taktpin (orange) ausgebaut. Nun kann ich den Servo-Stecker mit +(rot) und -(braun) in den XBUS-stecken (Pin1=GND, Pin2=5V-Vcc) und das Signal z.b. in Pin8 (INT1) oder Pin10 (SCL).

Für die Ansteuerung zapfe ich den 72kHz-Interrupt an, der Timerinterrupt hat mit nur 10 kHz eine zu geringe Auflösung (=weniger mögliche Servopositionen). Das ergibt zwar "krumme" Werte für die Positionen, funktioniert aber wunderbar:

Code:
#include "RP6RobotBaseLib.h"
#define servo_min 26
#define servo_mitte 85
#define servo_max 155
volatile unsigned char servo_winkel;
uint8_t servo_pos=servo_mitte;

void servo(uint8_t winkel)
{
	uint16_t servo_stellzeit;
	if (servo_winkel != winkel)
	{
	   TIMSK |= (1 << OCIE2);
		servo_stellzeit=200*abs(servo_winkel-winkel);
		servo_winkel=winkel;
		while (servo_stellzeit--);
		TIMSK &= ~(1 << OCIE2);
	}
}
int main(void) {
uint8_t i;

	initRobotBase();
	DDRC |= 1; // SCL auf Ausgang stellen

	while (1)
	{
		servo(servo_mitte);
		mSleep(500);
		servo(servo_min);
		mSleep(200);
		for (i=servo_max; i>servo_min; i-=2)
		{
			servo(i);
			setLEDs(16);
		}
		for (i=servo_min; i<servo_max; i+=2)
		{
			servo(i);
			setLEDs(32);
		}
	}
while(1);
return 0;
}

/*
ISR (TIMER2_COMP_vect)
{
#define Servo on
#ifdef Servo
	extern unsigned char servo_winkel;
	static unsigned int servo_zyklus=0;
	if (servo_winkel)
	{
		if (servo_zyklus>servo_winkel) extIntOFF(); else extIntON();
		//if (servo_zyklus>servo_winkel) PORTC &= ~1; else PORTC |= 1;
		if (servo_zyklus<1440) servo_zyklus++; else servo_zyklus=0;
	}

	//else
	if (0)
	{
#endif
...
#ifdef Servo
	}
#endif
}

/**
*/
Der einfache Democode definiert die Lageendpunkte und die Mitte, und steuert das Servo endlos auf diese Punkte. In der Funktion servo() wird die Stellzeit berechnet und der Winkel in servo_winkel eingetragen. Dann wird der Interrupt freigegeben und die Erweiterung des Interrupts steuert dann das Servo automatisch. Nach Ablauf der Stellzeit wird der Interrupt wieder gesperrt. Um Seiteneffekte zu vermeiden, wird in der Library der restliche Code der ISR ausgeblendet. Der Code für die Änderung der ISR befindet sich am Ende des Democodes. Das Ganze ist noch in der Entwicklung.

Gruß

mic