Servo-Impulslängenmessung    

Elektronik-Labor  Projekte   Holtek

   

Der HT46F47 tut schon in der Modellbahnanlage seinen Dienst, warum dann nicht auch im Modellflieger? Die Platine zur universellen Modellbahn-Beleuchtung kann ohne großen Umbau in einem Flieger mitreisen und z.B. direkt an 4,8 V aus den NC-Akkus betrieben werden. Alle möglichen Lichteffekte sehen sicherlich auch in der Luft gut aus.

Eine besondere Klasse von Aufgaben hat mit den Servo-Signalen zu tun. Wenn es gelingt, die Servo-Signale auszuwerten, stehen viele Türen offen. Die Steuerung muss dann nicht mehr völlig autonom arbeiten sondern kann auf Fernsteuerkommandos reagieren.

Ein Blick ins Datenblatt zeigt eine erfreuliche Eigenschaft des Timers: Er kann Impulslängen messen. Servosignale sind ja einfach nur Impulsfolgen mit Impulslängen zwischen 1 ms und 2 ms. Sie müssen hier am Pin PA4/TMR angeschlossen werden. Der Timer wird in der Betriebsart 3 (Impulslängenmessung) gestartet. Man setzt das TON-Bit auf 1 und wartet auf einen Impuls. Mit dem Impulsende wird TON automatisch auf Null gesetzt, woran man das Ende der Messung erkennt. Nun kann das Ergebnis aus dem Timer-Register ausgelesen werden. Eine neue Messung startet nicht ungefragt, sondern erst, wenn man das TON-Bit wieder hochsetzt. Wichtig ist auch das TE-Bit, das die Polarität der gesuchten Impulse angibt und hier auf 1 gesetzt werden muss. Und dann ist da auch noch der Vorteiler, der passend eingestellt werden muss, damit das Messergebnis bis 2 ms in den 8-Bit-Timer passt. Mit dem Vorteiler 64 ergibt sich bei ca. 4,5 MHz Taktfrequenz: die folgende maximal messbare Impulslänge  1 / 4500 kHz * 64 * 255 = 3,6 ms. 


#include "HT46F47E.h"
//RC-Osz mit 47 k, ca. 4,5 MHz, Servo-Eingag = PA4/TMR

#pragma vector isr_4 @ 0x4
#pragma vector isr_8 @ 0x8
#pragma vector isr_c @ 0xc

//ISR for safequard
void isr_4(){} // external ISR
void isr_c(){} // timer/event 0
void isr_8(){} // timer


void main(){
unsigned char i;
_intc = 5; //enable timer _intc = 0;
_tmr = 0;
_tmrc = 0xCE; //timer mode 3: Pulslaenge, TE=1, Vorteiler 64
_pbc = 0xff;
_pac = 0x10; //set port A to output port, PA4 I Impuls-Eingang
_pa = 0; //zero port A (all light on)
_pdc0 = 0; //PC0 Ausgang
_pd0 = 1; //PWM einschalten
_pwm = 100; //PWM-Ausgabe 0...255
_eadi = 0; //Kein Interupt
_acsr = 1; //AD-Clock = 1/8
_adcr = 8; //nur B0 als ADC0, AdC0 gewaehlt


while (1){
_tmr = 0; //Timerregister loeschen
_ton = 1; //Timer starten
while (_ton ==1); //Messung abwarten
_pwm = _tmr; //Ausgabe
}
}

Für den ersten Test wurde das Messergebnis einfach über die PWM ausgegeben. Am Oszilloskop kann dann beobachtet werden, dass die Servor-Signale den Messbereich etwa zwischen 30% (1 ms) und 60% (2 ms) ausschöpfen.



Servoimpuls mit 1,5 ms




Das PWM-Ausgangssignal

Wenn die eigentliche Messung funktioniert, kann man ganz unterschiedliche Dinge mit dem Ergebnis anfangen. Die folgende Programmschleife rechnet das Ergebnis für eine volle Aussteuerung der PWM von 0% bis 100% um. Außerdem werden auch die digitalen Ausgänge angesteuert, sodass man eine Binarzahl ausgeben kann. So können über die Fernsteuerung unterschiedliche Verbraucher an den Port PA5 bis PA7 geschaltet werden.

	while (1){
_tmr = 0; //Timerregister loeschen
_ton = 1; //Timer starten
while (_ton == 1); //Messung abwarten
i=_tmr;
if (i > 40) { //gueltiger Bereich ca. 75...150, 1 ms...2 ms
if (i > 80)
i = i - 80;
else
i=0;
if (i > 63) i=63;
i= i << 2;
_pwm = i;
_pa = i;
}
}

Eine andere Variante, die ebenfalls im Projekt enthalten ist, schaltet jeweils nur eine der Ausgangsleitungen ein und hat inaktive Bereiche der Aussteuerung, sodass ein Flackern der Ausgänge sicher vermieden werden kann.

	while (1){
_tmr = 0; //Timerregister loeschen
_ton = 1; //Timer starten
while (_ton == 1); //Messung abwarten
i=_tmr;
if (i > 40) { //gueltiger Bereich ca. 75...150, 1 ms...2 ms
if (i > 80)
i = i - 80;
else
i=0;
if (i > 63) i=63;
if (i < 15) _pa = 0;
if ((i>20) & (i<28)) _pa = 0x20;
if ((i>36) & (i<50)) _pa = 0x40;
if (i>52) _pa = 0x80;
i= i << 2;
_pwm = i;
}
}

Download: C_test3.zip


Servo-Testgenerator mit Bascom


Zum Testen wurde ein ES-M32 verwendet und mit der Servo-Funktion in Bascom programmiert. Das auf dem Board vorhandene Poti am Eingang ADC0 kann nun verwendet werden, um Servoimpulse zwischen 1 ms und 2 ms einzustellen. Eine alternative Programmschleife schaltet automatische zwischen 1 ms und 2 ms um.


'ATmega32, Servo

$regfile = "m32def.dat"
$crystal = 11059200
$hwstack = 16
$swstack = 32
$framesize = 32
Baud = 9600

Dim D As Integer


Config Servos = 1 , Servo1 = Portd.5 , Reload = 6
Config Portd = Output
Enable Interrupts

Do
D = Getadc(0)
D = D / 10
D = D + 100
Servo(1) = D
Waitms 200
Loop

Do
Servo(1) = 100 'links
Waitms 1000
Servo(1) = 200 'rechts
Waitms 1000
Loop

End



Elektronik-Labor  Projekte   Holtek