PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : PWM Eingangssiganl von Sensor verarbeiten



benhure
01.02.2006, 16:37
Hi,

mein Sensor liefert mir direkt ein 10Khz oder 100khz PWM signal.
Wie kann ich das elegant verarbeiten ?
(Kenn nur den umgekehrten weg 8-[ )

SprinterSB
01.02.2006, 16:40
Es ändert sich also nur die Frequenz bei gleichem Tastverhältnis?

ogni42
01.02.2006, 16:43
1. Weg: Mit PinChange Interrupt und free running timer: Hierüber lassen sich PWM Frequenz und Tastverhältnis ermitteln
2. Weg: RC Glied laden und per ADC auswerten. Hier bekommt man nur das Tastverhältnis raus (muss aber kalibriert werden, um wirklich genau zu sein, da Kondensatoren meist eine hohe Toleranz von 5%-20% haben).

benhure
01.02.2006, 16:47
Hi,

@ SprinterSB Jap, es ändert sich nur der Duty Cycle

@ogni42 dein 2.Weg ist mir zu ungenau
wenn kommt nur 1. weg in Frage

ogni42
01.02.2006, 16:55
Gut, den Duty Cycle kannst Du, bei bekannter Frequenz feststellen indem Du einen Timer laufen lässt, der mit einer entsprechend hohen Frequenz tickt.

Wenn dann ein PinChange Interrupt auftaucht (low-high), setzt Du das Timer Register auf 0, beim nächsten Interrupt (high-low) liest Du den timer aus und kannst dann den duty cycle bestimmen. Die Timerfrequenz bestimmt dabei die erreichbare Genauigkeit, muss aber so niedrig sein, dass der Timer bei maximalem DC nicht überläuft.

benhure
01.02.2006, 17:03
Hm, das verstehe ich soweit, auch wenn mir ein "PinChange Interrupt" neu ist. Werde mir diesbezüglich mal die Datenblätter anschauen.
Danke

Ich hab auch was von einen "Capture input" bei Timern gelesen.
Alles im Moment neu für mich. ( Hab bisher nur PWM ausgegeben )
Sagt dir da was und würde das hier auch vielleicht passen

ogni42
01.02.2006, 17:08
Schau mal nach dem INT0 bzw. INT1 Pin.

Hier ist ein kurzes Code-Schnipsel, wie man damit arbeiten kann:


#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <inttypes.h>

// key press down
SIGNAL( SIG_INTERRUPT0 )
{
// do stuff
}

// key pres up
SIGNAL( SIG_INTERRUPT1 )
{
// do other stuff
}



void interruptInit( void )
{
// react on falling edges
EICRA = (1<<ISC11)|(1<<ISC01);

// enable INTO and INT1
EIMSK = (1<<INT1)|(1<<INT0);

sei();
}

SprinterSB
01.02.2006, 17:11
Mit Input Capture gehen die genauesten Zeitmessungen.
Das Signal kommt an den ICP-Pin und auf einstellbare Flanke wird der Timerwert ins ICR gesichert, auf Wunsch ein IRQ getriggert.

Damit lassen sich aber maximal 2 Kanäle (im Zeitmultiplex) auswerten, als zweiten Zugang zum InCapt nimmt man den AC (AnalogComparator).

Die Werte aus dem ICR müssen schnell genug ausgelesen werden!, weil du ja low- und high-Zeit brauchst, also ist nicht nur die Frequenz ein kritischer Faktor, sondern auch das Tastverhältnis, denn es bestimmt die Pegel-Zeiten.

ogni42
01.02.2006, 17:17
Stimmt, habe ich gerade nicht dran gedacht :oops: Das ist die viel elegantere Lösung!

benhure
01.02.2006, 17:17
Danke, für die hilfreichen "Inputs"
Die muß ich jetzt erstmal verarbeiten :)

schönen Abend noch
benhure

SprinterSB
01.02.2006, 17:21
Schau mal nach dem INT0 bzw. INT1 Pin.

Hier ist ein kurzes Code-Schnipsel, wie man damit arbeiten kann:


#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <inttypes.h>

// key press down
SIGNAL( SIG_INTERRUPT0 )
{
// do stuff
}

// key pres up
SIGNAL( SIG_INTERRUPT1 )
{
// do other stuff
}



void interruptInit( void )
{
// react on falling edges
EICRA = (1<<ISC11)|(1<<ISC01);

// enable INTO and INT1
EIMSK = (1<<INT1)|(1<<INT0);

sei();
}



Ok, das ist zwar kein Bascom, aber wenn wir schon dabei sind: es muss heissen

SIGNAL (SIG_INTERRUPT1)

und NICHT

SIGNAL( SIG_INTERRUPT1 )

mit letzterem macht man nen bösen Bauchplatscher und sucht sich nen Wolf nach dem Fehler...

ogni42
01.02.2006, 17:30
Also bei mir funktioniert der Code so, wie er da steht. Warum auch nicht? Da ersetzt der Präprozessor doch nur das Makro.

SprinterSB
01.02.2006, 17:46
Das ist ein ziemlicher Stolperstein in manchen avr-gcc Versionen, wo das Leerzeichen still zu falschem Code führt, oder erinner ich da was falsch...)

Bei meinem avr-gcc wird's auch richtig gemacht, aber nix für ungut...

ogni42
01.02.2006, 17:48
Aha, das wusste ich nicht. Die neueren Versionen des gcc sollten da aber sauber sein.