Hallo
Irgendwie habe ich den Eindruck, wir reden aneinander vorbei. Anhand eines Democodes möchte ich versuchen zu zeigen, wie die Geschwindigkeitssteuerung eines gehackten Servos mit Verwendung der orginalen Servoelektronik (Plan C) umgesetzt werden kann. Das Demo ist für die drei Omniwheels geschrieben, deshalb werden gleichzeitig drei identische Impulse an PB1, PB2 und PB4 erzeugt:
Code:
#include "asuro-probot.h"
#include "asuro-probot.c"
int main(void)
{
int i, j;
Init();
PORTC |= 3; // Odo-PullUps simulieren für PollSwitch()
PORTB &= ~(1<<PB5 | 1<<PB4 | 1<<PB2 | 1<<PB1);
while(!PollSwitch());
while(PollSwitch());
StatusLED(RED);
while(!PollSwitch()) // kalibrieren
{
PORTB |= (1<<PB1);
PORTB |= (1<<PB2);
PORTB |= (1<<PB4);
Sleep(36);
PORTB &= ~(1<<PB1);
PORTB &= ~(1<<PB2);
PORTB &= ~(1<<PB4);
for(i=19; i--; Sleep(36));
}
while(PollSwitch()); //fertig
StatusLED(YELLOW);
Msleep(2000);
while(1) // Demo
{
for(j=0; j<500; j++)
{
PORTB |= (1<<PB1);
PORTB |= (1<<PB2);
PORTB |= (1<<PB4);
Sleep(31);
PORTB &= ~(1<<PB1);
PORTB &= ~(1<<PB2);
PORTB &= ~(1<<PB4);
for(i=19; i--; Sleep(36));
}
for(j=0; j<500; j++)
{
PORTB |= (1<<PB1);
PORTB |= (1<<PB2);
PORTB |= (1<<PB4);
Sleep(41);
PORTB &= ~(1<<PB1);
PORTB &= ~(1<<PB2);
PORTB &= ~(1<<PB4);
for(i=19; i--; Sleep(36));
}
for(j=0; j<500; j++)
{
PORTB |= (1<<PB1);
PORTB |= (1<<PB2);
PORTB |= (1<<PB4);
Sleep(26);
PORTB &= ~(1<<PB1);
PORTB &= ~(1<<PB2);
PORTB &= ~(1<<PB4);
for(i=19; i--; Sleep(36));
}
for(j=0; j<500; j++)
{
PORTB |= (1<<PB1);
PORTB |= (1<<PB2);
PORTB |= (1<<PB4);
Sleep(46);
PORTB &= ~(1<<PB1);
PORTB &= ~(1<<PB2);
PORTB &= ~(1<<PB4);
for(i=19; i--; Sleep(36));
}
}
}
Die Impulslängen werden im Demo recht einfach über interrupterzeugte Sleep()-Funktionen erzeugt. Zeitbasis ist eine 36kHz-ISR, deshalb dauert eine Pause von Sleep(36) ziemlich genau 1ms. Im folgenden Programmabschnitt werden nun bis zu einem Tastendruck 1ms-Impulse gesendet. Dies dient der Kalibierung der Potis (Plan C):
Code:
while(!PollSwitch()) // kalibrieren
{
PORTB |= (1<<PB1);
PORTB |= (1<<PB2);
PORTB |= (1<<PB4);
Sleep(36);
PORTB &= ~(1<<PB1);
PORTB &= ~(1<<PB2);
PORTB &= ~(1<<PB4);
for(i=19; i--; Sleep(36));
}
Nach Abschluss der Kalibrierung steht das Servo, wenn ein 1ms-Impuls gesendet wird!
Im folgenden Abschnitt werden Impulse mit Sleep(31) bzw. Sleep(41) erzeugt. Dies entspricht Impulslängen von 0,86ms (1/36*31) bzw. 1,14ms (1/36*41), also ca. 0,14ms von der Mittelstellung von 1ms entfernt.
Code:
for(j=0; j<500; j++)
{
PORTB |= (1<<PB1);
PORTB |= (1<<PB2);
PORTB |= (1<<PB4);
Sleep(31);
PORTB &= ~(1<<PB1);
PORTB &= ~(1<<PB2);
PORTB &= ~(1<<PB4);
for(i=19; i--; Sleep(36));
}
for(j=0; j<500; j++)
{
PORTB |= (1<<PB1);
PORTB |= (1<<PB2);
PORTB |= (1<<PB4);
Sleep(41);
PORTB &= ~(1<<PB1);
PORTB &= ~(1<<PB2);
PORTB &= ~(1<<PB4);
for(i=19; i--; Sleep(36));
}
Im dritten Abschnitt sind die Impulslängen dann Sleep(26) bzw. Sleep(46) (oder 0,72ms bzw. 1,28ms):
Code:
for(j=0; j<500; j++)
{
PORTB |= (1<<PB1);
PORTB |= (1<<PB2);
PORTB |= (1<<PB4);
Sleep(26);
PORTB &= ~(1<<PB1);
PORTB &= ~(1<<PB2);
PORTB &= ~(1<<PB4);
for(i=19; i--; Sleep(36));
}
for(j=0; j<500; j++)
{
PORTB |= (1<<PB1);
PORTB |= (1<<PB2);
PORTB |= (1<<PB4);
Sleep(46);
PORTB &= ~(1<<PB1);
PORTB &= ~(1<<PB2);
PORTB &= ~(1<<PB4);
for(i=19; i--; Sleep(36));
}
Die Servoelektronik errechnet nun jedesmal die erforderliche/mögliche Drehgeschwindigkeit aus dem Unterschied zwischen dem 1ms-Impuls, auf dem es ja durch den (nach dem Kalibrieren) fixen Spannungsteiler des Potis zu stehen glaubt, und der Sollposition des gesendeten Impulses. Dadurch ergibt sich im zweiten Abschnitt (31/41) eine geringere Drehgeschwindigkeit des Servos als bei (26/46). Die Maximaldrehzahl und die einzelnen Drehzahlstufen sind natürlich vom verwendeten Servo abhängig und können deshalb als "extrem ungenau" bezeichnet werden. Entscheidend für die Brauchbarkeit dieser Technik ist aber letztlich die geplante Anwendung.
Erwähnen möcht ich hier noch, dass die 1ms für die Mittelstellung in der Literatur und auch in der Praxis auch 1,5ms sein können ;) Und es gibt natürlich noch viele andere Möglichkeiten die Servoimpulse zu erzeugen. Das Prinzip der hier beschriebenen Drehzahlsteuerung ändert sich dadurch aber nicht.
Beachten muss man zusätzlich noch, dass die Servos einen "Totpunkt" haben. Das bedeutet, erst wenn der Sollimpuls einen bestimmten Abstand zur Istposition hat, regelt das Servo seine Position nach. Das begrenzt die minimale Drehzahl.
https://www.roboternetz.de/phpBB2/ze...rag.php?t=8139
http://www.electronicsplanet.ch
Gruß
mic
Lesezeichen