ServoPoti

Beinahe jeder Servo benutzt zur Positionsbestimmung und Regelung ein einfaches Potentiometer, welches sich mit der Ausgangswelle mitdreht. Dies ist auch der Grund warum Servos sich normalerweise nicht 360° drehen, da dies mit einem an der Achse befestigten Potentiometer einfach nicht geht... Es soll auch Servos geben, welche die Position über Hallgeber (berührungslos) erfassen, und damit theoretisch keine Beschränkung haben, mir selber ist so ein Teil jedoch noch nicht begegnet.

Abgreifen der Servoposition

Hier möchte ich kurz beschreiben, wie ich an den für den RoCa2011 verwendeten Servos (ModelCraft, RS-2) das Signal des Potis abgegriffen habe, und an die ADC-Eingänge des uC-Boards gelegt habe.

Als erstes muss den Servo öffnen, hierzu gibt es meist 4 Schrauben auf der Rückseite. Das Gehäuse der Servos besteht meist aus DREI Teilen, einem mittleren Teil in dem der Motor und die Elektronik sitzt, dem Deckel an der Rückseite und einem vorne aufgesetzten Getriebeteil. Wenn man die Gehäuseschrauben löst, kann es passieren sich der vordere Teil mit dem Getriebe auch löst. Im schlimmsten Fall fällt das Getriebe dann raus und man muss es wieder RICHTIG zusammensetzen... Also lieber den vorderen Teil mit etwas Isolierband sichern oder vorsichtig sein...

Nach dem Öffnen sieht der Servo dann so aus:

Offener ServoDie Anschlüsse sind mit etwas Klebstoff fixiert, um das Abbrechen bei Vibrationen (für den eigentlichen Einsazt als Modellbauservo) zu verhindern. Zu erkennen sind noch die 4 Treiber für den Motor und die drei Kontakte vom Positionspotentiometer, rechts neben dem Kabelanschluss. Der mittlere Anschluß ist der "Schleifer" oder Mittenabgriff des Potis, welcher dann die Position als Spannung an die Regelelektronik ausgibt. Diesen Anschluss habe ich abgegriffen und an einen ADC-Eingang des Boards gelegt.

 

Servo mit neuen AnschlusskabelnDa ich die Servoanschlussleitungen sowieso verlängern musste, habe ich mich entschlossen auch die originalen Anschlußleitungen für Masse, Stromversorgung und Ansteuersignal direkt an der Platine neu anzuschliessen.

Die Farbgebung der Anschlussleitung ist in diesem Fall: Braun = Masse, Rot = Versorgungsspannung und Orange = Ansteuersignal.

 

So sieht das ganze dann mit den neuen Kabeln aus. Ich habe hier einfache Kabel mit 0.14mm2 benutzt, welche ich vorher verflochten habe.

Im nächsten Schritt kommt dann ein weiteres Kabel (bei mir grün) an den mittleren Kontakt des Potentiometers.

Servo mit neuen Kabeln

 

So, dann noch zuschrauben, und das ganze sieht, bis auf die vierte Leitung, wieder halbwegs normal aus.

Das ganze habe ich für alle 4 Hauptservos des Arms gemacht. Den ganz kleinen Servo (ModelCraft Y-3009) habe ich zwar auch geöffnet um die neuen Kabel anzulöten, dort jedoch keinen Abgriff für das Potentiometer gemacht. Diese vierte Leitung mit dem Spannungssignal vom Potentiometer habe ich dann am MikroControler (auf der RoCa2011 Platine ist dies ein ATMega88) jeweils auf einen ADC-Eingang gelegt. In diesem Fall sind das PC2, PC3, PC4 und PC5, welche auf dem Expansion-Stecker des Boards liegen.

Warum überhaupt?

Beim Einschalten oder nach einem Reset fährt der Lastarm mit voller Geschwindigkeit in die angeforderte Ausgangsposition. Dies kann, je nach Ausgangslage schon beeindruckend schnell, aber im Hinblick auf mögliche Beschädigungen des Arms auch ganz schön beängstigend sein. Mein Ansatz war nun das ich die Position des Arms anhand der Potentiometersignale bestimme und mir daraus Ansteuersignale errechne, mit denen ich diese aktuelle Position erreichen müsste. Hierdurch würde der Arm dann nur noch mit relativ kleinen Ausschlägen reagieren.

Die Signale habe ich wie bereits geschrieben auf die ADC PC2/3/4/5 gelegt und frage diese Signale ab, bevor ich die Ausgänge für die Ansteuersignale freigebe. Die Signale habe ich erst gar nicht auf eine Spannung zurückgerechnet, sondern arbeite direkt mit den ADC-Werten (0-1203 für den gewählten Spannungsbereich, wobei dieser Bereich entweder auf eine interne Spannungsquelle oder eine externe Spannungsquelle skaliert sein kann). Zum Bestimmen des Zusammenhangs zwischen den ADC-Werten und den Ansteuersignale verfahre ich den Arm manuell und lasse mir nach jedem Schritt die Ansteuerdauer (in us) und den ADC-Wert ausgeben. Diese Werte habe ich dann in einem Tabellenkalkulationsprogramm dargestellt und mir dort eine Ausgleichsgerade durch die gemessenen Punkte legen lassen.

Zusammenhang ADC-Wert und AnsteuerdauerDas ganze sieht dann zum Beispiel so aus wie hier rechts dargestellt.

Ich habe den Arm aus den Endpositionen in beide Richtungen verfahren, man erkennt relativ gut, daß es hier eine Hysterese gibt, d.h. je nachdem aus welcher "Richtung" man kommt, ergeben sich leicht andere Werte. Dies hat unter anderem mit dem Spiel und der Reibung in den Servos zu tun, aber auch mit einer relativ schwach ausgelegten Positionsregelung des Servos. Eine derartige Hysterese kommt übrigens auch bei wesentlich teureren Stellern im Automobilbereich vor.

Die berechnete Ausgleichsgerade nähert die Zusammenhänge zwischen den ADC-Werten und der Ansteuerdauer für den angedachten Verwendungszeck trotzdem genau genug ab.

Dies habe ich für jeden Servo getrennt gemacht, die Ergebnisse für die Gleichung ist für alle Servos (leicht) unterschiedlich und würde wieder anders ausfallen, wenn ich z.B. die anderen Armteile anders anstelle, da sich dadurch z.B. die benötigte Kraft ändert. Da die Genauigkeit für meinen Anwendungsfall hier vollkommen ausreichend ist, habe ich auf weitere Untersuchungen oder Anpassungen an den Formeln verzichtet.

set_servo_position_us(0, (uint16_t)(4.6353f * read_adc(0) + 33.75));
set_servo_position_us(1, (uint16_t)(4.0529f * read_adc(1) + 238.79));
set_servo_position_us(2, (uint16_t)(4.7208f * read_adc(2) + 56.978));
set_servo_position_us(3, (uint16_t)(4.2915f * read_adc(3) + 92.571));

Hierdurch kann ich dann recht einfach die Initiale Ansteuerungsdauer für die aktuelle Position bestimmen, in dem ich die herausgemessenen Formeln nutze. Erst nachdem die initialen Ansteuerwerte für die Servos bestimmt wurden, gebe ich die Signalerzeugung für die Servosignale frei, und fahre danach langsam und kontrolliert in meine definierte Anfangsstellung.

Pläne ohne Potentiometer

Da durch diese 4 Potentiometersignale momentan alle verfügbaren ADC-Eingänge des Boards belegt sind (es gibt noch 4 weitere, diese liegen jedoch nicht auf einem Expansionport, bzw. sind bereits anderweitig verwendet) lässt sich so erst mal keine weitere analoge Sensorik anschließen und auswerten.

Aktuell ist geplant, die Ansteuerlogik um einen Eingabetaster zu erweitern. Nach dem Start oder einem Reset sollen die Ausgänge für die Servoansteuerung inaktiv bleiben. Der Arm kann dann von Hand in eine bekannte Ausgangsposition bewegt werden, deren Ansteuerwerte im Programm abgelegt sind. Nach einem Tastendruck soll dann die Ansteuerung mit den Werten für diese Ausgangsposition initialisiert und freigegeben werden.

Ein weiterer Tastendruck soll den Arm dann in diese Ausgangsposition zurückfahren, ein dritter Tastendruck soll dann den Ausgang wieder deaktivieren und den Arm damit Kraftfrei machen.

Dies stellt sich jedoch als schwieriger heraus als es sich anhört... Zum einen gilt es hier einen Taster einzulesen, was jetzt scheinbar einfach ist, aber durch die erforderliche Entprellung des Signals dann doch schon wieder etwas trickreich wird. Das andere Problem ist, das man in der Ansteuerlogik vorsehen muss, das man über einen Taster alle anderen Befehle "ignoriert" und eine Position anfährt. Die Schwierigkeit für mich ist zur Zeit, das ich hierfür einige Aktionen innerhalb der Interruptroutinen ausführen müsste, ich jedoch auf einen Interrupt angewiesen bin. Hierzu müsste ich in einem Interrupt einen anderen Interrupt wieder freigeben. Die sich hieraus ergebenden Fehlermöglichkeiten möchte ich aber vermeiden und suche daher aktuell noch nach einer Strategie die mir diese Funktinalität erlaubt, ohne derartige Klimmzüge machen zu müssen.

2013-06-13