So ein analoges Servo ist genügsam. 4 bis 5V Versorgungsspannung (4 Accu-Zellen) und ein ähnlicher Pegel für den Puls am Steuereingang genügt bereits. Weder die Versorgung noch der Pegel müssen genau sein. Im Modell sinkt die Versorgungsspannung mit nachlassender Ladung der Akkus ja auch.
Die Schaltung ist ganz unkompliziert. Der Portpin kann direkt an den Steuereingang eines Servos angeschlossen werden. Die Servos benötigen jedoch ihre eigene Stromversorgung, wenn im Experiment die MCU auf dem MSP430-LaunchPad verwendet wird. (Siehe auch: Grundlegende Experimente mit einer MCU). Der Widerstand R1 = 0Ω in diesem Experiment ist nur eine Drahtbrücke.
Am Steuereingang werden Rechteckpulse im 50Hz Takt erwartet, also ca. alle 20ms. Annähernd Vollausschlag in die eine Richtung liegt vor bei einem Puls von 1ms Breite, in die andere Richtung bei 2ms. Das ließe sich mit der PWM-Funktion der MCU machen, doch dann wäre bei zwei Servos Schluß, da nur zwei Timer da sind. Für eine ganze Reihe Servos muss ein Software-Timing her. Das Timing ist ja eher gemütlich, und so geht das bequem in high level Forth.
Im Testprogramm erhalten die Servos ihren Puls einfach nacheinander. Auf diese Weise passen bis zu 9 Servo-Pulse in die 50Hz Wiederholrate, also die 20 ms Lücke die ein Servo erwartet. Das ist schnell genug für viele Modellbau Zwecke denke ich, zumal die Stellzeit so eines Servos für eine volle Fahrt vom linken zum rechten Anschlag ja im Bereich 500ms liegt .
Der Sortware-Trick besteht darin, die Warteschleife für die Lücke um die Pulszeiten, die schon abgelaufen sind, zu verkürzen. Dann kommt der erste Puls wieder rechtzeitig, und es entsteht für jeden Servo ein 50Hz Puls-Signal. Im übrigen wird einfach nur ein Portpin an und wieder ausgeschaltet. Die Pulsbreite wird ganz simpel durch eine leere Schleife generiert. Die Durchlaufzahl wurde ausprobiert, und ein Korrekturfaktor ermittelt. Damit wird dann die Angabe in µs in die Schleifenumläufe umgerechnet. So kann man die gewünschte Pulsbreite in Mikrosekunden vorgeben. Der Korrekturfaktor ist natürlich abhängig von der Taktfrequenz der MCU. Meine lief mit dem internen Taktgenerator von ca. 8MHz.
Da ich nur ein 2-Kanal-Oscilloskop hatte, mussten die Kanäle paarweise verglichen werden. Man kann trotzdem ganz gut sehen wie die PWM-Kanäle zeitlich wandern. Das Ablaufschema der Pulse zeigt wie man sich das vorstellen kann, könnte man alle gleichzeitig darstellen.
\ PWM Pulse fuer 8 analoge Servos : ? ( adr -- ) @ . ; \ hilft testen BIN \ 76543210 10000000 CONSTANT BIT7 01000000 CONSTANT BIT6 00100000 CONSTANT BIT5 00010000 CONSTANT BIT4 00001000 CONSTANT BIT3 00000100 CONSTANT BIT2 00000010 CONSTANT BIT1 00000001 CONSTANT BIT0 HEX FFFF CONSTANT TRUE 29 CONSTANT P2OUT \ alias P2 2A CONSTANT P2DIR 2E CONSTANT P2SEL BIT0 P2 2CONSTANT P2.0 BIT1 P2 2CONSTANT P2.1 BIT2 P2 2CONSTANT P2.2 BIT3 P2 2CONSTANT P2.3 BIT4 P2 2CONSTANT P2.4 BIT5 P2 2CONSTANT P2.5 BIT6 P2 2CONSTANT P2.6 BIT7 P2 2CONSTANT P2.7 DECIMAL VARIABLE RESTDAUER : REST restdauer @ 0 DO LOOP ; : P2SET true p2dir c! zero p2 c! zero p2sel c! ; : NEU 13072 restdauer ! p2set ; \ erzeuge Puls der Breite x an Pin p vom Port adr. : SUBREST ( n -- ) negate restdauer +! ; : PULS ( x p adr -- ) 2dup >r >r cset \ H-Pegel dup subrest 0 DO LOOP \ Pulsbreite warten r> r> cclr ; \ L-Pegel : us 31 / 20 * ; ( Der Korrekturfaktor muss experimentell ermittelt werden. ) : TEST2 BEGIN neu 2000 us p2.0 puls 2000 us p2.1 puls 2000 us p2.2 puls 2000 us p2.3 puls 2000 us p2.4 puls 2000 us p2.5 puls 2000 us p2.6 puls 2000 us p2.7 puls rest key? UNTIL key drop ; : TEST1 BEGIN neu 1000 us p2.0 puls 1000 us p2.1 puls 1000 us p2.2 puls 1000 us p2.3 puls 1000 us p2.4 puls 1000 us p2.5 puls 1000 us p2.6 puls 1000 us p2.7 puls rest key? UNTIL key drop ; : RUN ( -- ) 5 0 do test1 test2 loop ; \ druecke mehrmals eine Taste wenns lauft.
An einem einzelnen Servo lässt sich mit einem weiteren kleinen Programm zeigen, wie sich der Servo bei vollem Fahrweg verhält. Wird von 1 ms auf 2 ms Pulsbreite umgeschaltet, fährt der Servo einen vollen Weg. Schaltet man von 2 ms auf 1 ms zurück, fährt er zurück. Hört man mit den Pulsen zu früh auf, bleibt der Servo unterwegs einfach stehen.
\ Erste Annäherung: Beobachten bis der volle Weg offensichtlich da ist. : FAHRTEST1 100 10 DO key? IF key drop leave THEN i . i 0 DO neu 1000 us p2.0 puls rest LOOP i 0 DO neu 2000 us p2.0 puls rest LOOP LOOP ;
Dazu kann der Aufbau unverändert benutzt werden. Sobald man den Eindruck hat das der Servo den vollen Fahrweg zurück gelegt hat, drückt man eine Taste und das Experiment stoppt. Die zuletzt ausgegebene Zahl ist die Anzahl der Pulswiederholungen. Nach einigen Durchgängen bekommt man ein ganz gutes Gefühl dafür. Bei meiner Anordnung kam ich so auf geschätzte 20 bis 23 Pulse. Rund 40 Pulse ergaben einen Rhythmus von praktisch gleich langem Hin- und Herfahren und still stehen.
\ Beobachten von vollen Wegen am Oszilloskop. : FAHRTEST2 BEGIN 40 0 DO neu 1000 us p2.0 puls rest LOOP 100 ms 40 0 DO neu 2000 us p2.0 puls rest LOOP 200 ms key? UNTIL key drop ;
Regelmäßige wiederkehrende Ereignisse sind am Oszilloskop ganz gut zu triggern. Mit dem Voltcraft USB-DSO ging das mit dem automatischen Trigger auf die Servoaktion. Dazu wurde im Aufbau die Drahtbrücke R1 gegen einen kleinen Widerstand ausgetauscht. R1 = 3Ω zwischen Vss und dem Servo reichten schon aus, um einen gut erkennbaren kurzen Spannungsabfall von 5V auf 3V hinter dem Widerstand hervorzurufen bei jeder Servoaktion - grüne Kurve im Bild, Kanal2 (CH2). Die gelbe Kurve (CH1) zeigt die Pulsserien die an den Servo gingen.
Anhand der kleinen Puls-Pausen kann man identifizieren welche Pulsserie gerade abgelaufen war. Der kürzeren Pause gingen die 1 ms Pulse voraus (rechts im Bild), und der längeren die 2 ms Pulse, (links im Bild). Mit jeder Pulsserie fuhr der Motor in die andere Richtung. Man erkennt wie die Spannung einbrach, wenn der Motor startete, und sich dann einpendelte wenn er lief. Nach 20 bis 21 Pulsen bleib der Motor stehen, aber es gab auch danach noch kurze Regelpulse der Servoelektronik. Bei den 1ms Steuer-Pulsen waren es immer nur wenige nachlaufende Regelpulse, im Bild waren es 7 Stück. Bei den 2ms-Pulsen waren es immer viele, über die ganze Steuerpulsserie hinweg. Ich deute das so, dass der Motor auf dieser Seite noch nicht am mechanischen Anschlag war, sondern in einer Position davor gehalten wurde. Der Servo brummte dabei auch leise, was er in der anderen Endstellung nicht tat. So kann man abzählen das dieser Servo nach 20 Pulsen, die alle 20ms kamen, einen vollen Fahrweg machte, also 400 ms benötigte, ungefähr eine 1/2 Sekunde.
Ein anderer Ansatz, die Servos praktisch gleichzeitig anzusteuern, wurde auch ausprobiert. Die Pulsbreite wurde in einer Variablen abgelegt, zehn davon in einem Feld. Diese wurden zyklisch herunter gezählt, um beim Nulldurchgang den zugehörigen Puls zu beenden. Dieses Verfahren, Software-Zähler mit preset zu bauen und diese zu pollen, war aber in high level Forth zu langsam. Damit konnten nur ca. 3 verschiedene Positionen am Servo eingestellt werden. Es wurde also eine viel zu geringe zeitliche Auflösung erzielt. Hier kommt man also an eine Grenze des 4e4th Forth auf dieser MCU.
Im Rahmen der grundlegenden Experimente wurde darauf verzichtet hier assemblierten, interrupt-getriebenen Code auszuarbeiten, der schnell genug für diesen Ansatz wäre. Denn es ging um das Prinzip der Servoansteuerung, und durchaus auch darum solche Grenzen zu erfahren.