Benutzer-Werkzeuge

Webseiten-Werkzeuge


projects:4e4th:4e4th:start:msp430g2553_experimente:servotester

Servotester für analoge Servos im Modellbau

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.

Aufbau

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.

Anschluß der ServosTestaufbau }

Testprogramm für 8 Servos

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.

2 Servos, 1ms Puls gefolgt von 2ms Puls, 50Hz Wiederholung; Kanal 0 und 1 2 Servos, 1ms Puls gefolgt von 2ms Puls, 50Hz Wiederholung; Kanal 0 und 22 Servos, 1ms Puls gefolgt von 2ms Puls, 50Hz Wiederholung; Kanal 0 und 7 Ablaufschema der Pulse, Kanäle 0...7

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.

Quellcode in Forth

\ 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.

Experiment zum Fahrweg

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.

Wieviele Pulse sind für einen vollen Weg des Servos nötig?

\ 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.

Wie lange dauert das dann?

\ 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 ; 

Servofahrtest 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.

Anmerkung

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.

projects/4e4th/4e4th/start/msp430g2553_experimente/servotester.txt · Zuletzt geändert: 2018-05-02 17:58 von mka