PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] Frequenz messen und zählen



BascomBenutzer
27.12.2016, 22:59
Hallo,

Ich stehe gerade auf dem Schlauch.
Mit der Benutzung der Timer bin ich vertraut und auch
der Interrupts.
Ich möchte wenn ein 1 kHz Signal an einem Eingang ansteht eine Variable um 1 hoch gezählt wird. Das Signal kommt von einer geputzten LED.
Wie stell ich das am einfachsten an?

wkrug
28.12.2016, 08:41
Deine Anfrage ist irgendwie unklar.
Willst Du nun eine Frequenz messen, oder beim anliegen eines periodischen Signals eine Variable hochzählen, oder eine Kombination von beiden?

Grundsätzlich gibt es für die Frequenzmessung mehrere Methoden.
1. Eine wäre eine echte Frequenzmessung mit fester Torzeit.
Du gibst die unbekannte Frequenz auf den Takteingang eines Timers und konfigurierst einen 2ten Timer so, das er nach genau einer Sekunde einen Interrupt produziert. In diesem Interrupt wird der Zählerstand des ersten Timers ausgelesen und wieder auf 0 gesetzt für die nächste Messung und ist dann ein direktes Maß für die Frequenz.
Diese Methode eignet sich eher für hohe Frequenzen und ist relativ Jitterstabil.

2. Eine weitere wäre die Messung der Periodendauer.
Ein Timer läuft frei, lediglich Overflows müssen erkannt werden.
Das unbekannte Signal wird auf den Input Capture Pin des verwendeten Timers gelegt und der zugehörige Interrupt freigegeben.
In diesem Interrupt wird dann der Zählerstand des vorherigen Interrupt vom aktuellen Wert abgezogen und bildet dann ein Maß für die Periodendauer des Signals.
Diese Periodendauer muss dann unter Berücksichtigung der Timerfrequenz in eine Frequenz umgerechnet werden.
Die Umrechnung bitte nicht in der Interruptroutine machen, sondern im Hauptprogramm.
Diese Methode ist sehr gut für niedrige Frequenzen geeignet ( jede Periode produziert einen Interrupt ) und liefert sehr schnell neue Ergebnisse.
Nachteil der Methode ist, das immer nur eine Periode des Eingangssignals gemessen wird. Unregelmässige oder verjitterte Signale machen bei dieser Methode Probleme. Also mehrere Messungen samplen und einen Mittelwert daraus bilden.

Mir ist auch nich ganz klar was Du mit der LED meinst. Hast Du die LED als Fotodiode verwendet? Nimmst Du das Signal mit einer Fotodiode oder einem Fotowiderstand vom Licht der LED ab, oder gehst due einfach auf die Anschlusspins der LED ???
Ich denke auch, das Du das LED Signal, wo immer es auch herkommt über einen Schmitt Trigger in ein sauberes Rechtecksignal umformen musst.

Dann würde ich noch ein Flag anlegen "1kHz Signal vorhanden". Wenn ein 1kHz Signal detektiert wird geht diese Variable von 0 nach 1 und dein Zähler zählt eins weiter.
Wird kein 1kHz Signal detektiert geht die Variable wieder nach 0.

monkye2000
28.12.2016, 09:01
Kann es sein dass Du die Frage schon einmal im Bascom-Forum gestellt hast?

Unregistriert
28.12.2016, 09:57
Es geht darum.
Hab hier einen CNY 70 der die Drehzahl eines Motor misst.
Die LED habe ich mit Timer0 gepulst.
Der Transitor geht dann auf einen Eingang des AVR.
Es muß nicht genau die Frequenz gemessen werden sondern
nur unterschieden werden, ob eine Frequenz anliegt (dann Variable +1) oder 0V Level.

monkye2000
28.12.2016, 10:32
OK, das habe ich verstanden: CNY70 arbeitet als Reflexlichtschranke und soll zur Unterdrückung von Störlicht mit 1kHz getaktet werden, in Deinem Fall von Timer0 per PMW. (letzteres geraten)

Da ich die mögliche Drehzahl des Motors nicht kenne (es mach schon einen Unterschied, ob Du bis 10.000 U/min oder bis zu 100.00 U/min messen willst) - könnte Deine Modulation mit 1kHz viel zu gering sein, weil schlicht und einfach zu wenig Zeit bleibt um das Ende des Impulses zu messen.

Beispiel: Deine Messung erfolgt per Reflexion an einem Rad, der Reflektor ist ca. 10mm vom Zentrum entfernt. Der Einfacheit halber ist alle 36° ein Reflektor, so dass 360°/36° = 10 Sekmente möglich wären - sondt wird es zu winzig. Wenn Du also mehr Segmente brauchst (genauer bzgl. des Drehwinkels), oder weniger - z.B. nur 1 Segment über die Hälfte des Umfangs (ca. 31,5mm weiß, 31,5mm schwarz) - dann ist die mögliche Messzeit sehr verschieden.

Bei 1kHz ist die HIGH-Phase alse 0,5ms, so dass sich in unserem Beispiel mit 1 Segment und z.B. 10.000 U/min ==> 166,6 U/sec in etwa 166,6 x 63mm = 10.495,8mm/s bzw. 10,4958 mm/ms zurückgelegt werden. Das heißt: Das halbe Segment ist ja nur 31,5mm lang und so passen gerade noch 3 Impulse (!!) auf den weißen Reflektor.

Die Wahrscheinlichkeit, dass Störungen mit 1kHz durch die Luft flimmern ist relativ groß - und damit ist die erwünschte Wirkung nicht gut genug. Empfehlung: Frequenz hochsetzen. Normale TV-Fernbedienungen arbeiten oft im Bereich 35...45kHz.

Unregistriert
28.12.2016, 13:56
habe es mal so versucht.
geht relativ gut.

'Auwertung einer Drezahl mit einem CNY70
'Die LED des CNY70 wird an Protb.5 mit Timer2 gepulst
'am Transitor des CNY wird das Singnal mit einem RC Hochpaß aufbereitet und
'auf den INT0 (Portd.2) gegeben.
'Die Signale an Portd.2 werden während einer Torzeit(Timer0/Merker1) gezählt
'Liegt eine Frequenz an gab es während der Torzeit ca.6 Impulse
'Liegt eine Frequenz an wird hochgezählt und gewartet bis die Frequenz wieder weg ist.
'Liegt erneut eine Frequenz an wird wieder hochgezählt

$regfile = "m8adef.dat"
$crystal = 1000000
$hwstack = 40
$swstack = 16
$framesize = 32

Dim Wert As Word 'Erkannte Impulse
Dim Zaehler As Word 'Impulse Frequenz zählen
Dim Merker As Bit 'Merker Torzeit abgelaufen
Dim Merker2 As Bit 'Frequenz Ja/Nein

Config Portb.5 = Output 'Ausgang LED CNY 70
Config Portd.2 = Input 'Impulseingang
Config Portb.1 = Output 'Anzeige-LED Frequenz erkannt

Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portb.0
Config Lcd = 20 * 4
Cursor Off
Cls

Config Timer0 = Timer , Prescale = 256 'Torzeit Impulse
On Timer0 Torzeit
Enable Timer0

Config Timer2 = Timer , Prescale = 8 'LED Pulsen CNY70
On Timer2 Ledpulsen
Enable Timer2

Config Int0 = Rising 'Interrupt zum Frquenz zählen
On Int0 Eingangsimpuls
Enable Int0
Enable Interrupts

Do
If Merker = 1 Then Gosub Auswerten 'Auswert nach Torzeit Frequenz Ja/Nein '

Locate 1 , 1
Lcd Wert ; " " 'Anzeige der erkannten Impulse


Loop

End

Auswerten:
Merker = 0 'Torzeitmerker auf 0
If Zaehler > 3 And Merker2 = 0 Then 'Prüfung neuer Frequenzimpuls Ja/Nein bei dieser Torzeit ca.6 Impulse
Incr Wert 'Erkannte Impulse hochzälen
Portb.1 = 1 'Frequenz erkannt
Else
Portb.1 = 0 'Frequenz nicht erkannt
End If

If Zaehler > 3 Then
Merker2 = 1 'Frequenz erkannt
Else
Merker2 = 0 'keine Frequenz erkannt
End If
Zaehler = 0 'Zähler auf 0 für nächsten Durchgang
Return

Ledpulsen:
Timer2 = 130
Toggle Portb.5 'LED CNY70 pulsen
Return

Eingangsimpuls:
Incr Zaehler
Return

Torzeit:
Timer0 = 100 'Timer0 auf Startwert 100
Merker = 1 'Torzeit abgelaufen
Return

021aet04
28.12.2016, 14:01
Ich würde das etwas anders machen. Ich würde die Frequenz mit einem AMV erzeugen. Mit dem Empfänger des CNY gehst du auf einen Monoflop und somit musst du nur das Signal vom Monoflop auswerten. Frequenz würde ich ebenfalls auf ca. 30kHz (oder mehr) hochgehen.

MfG Hannes

Unregistriert
28.12.2016, 15:10
Klar Frequenz kann ich erhöhen.
Wie im Titel vom Programm steht nehm ich das Signal vom Transistor des CNY 70 und filter die Gleichspannung mit einem RC Hochpass weg und mach mit einem OP LM358 TTL Pegel drauß.
Hat noch jemand andere Programmieransätze oder Vereinfachungen?

wkrug
29.12.2016, 07:50
Der TTL Pegel ist ja wieder ein 30kHz Signal.
Das kannst Du nun mit dem Controller auswerten, oder Du schaltest noch ein Monoflop nach, wie Hannes schon vorschlug, und kannst dann die Impulse direkt mit dem AVR zählen.
Die Triggerschwelle des LM 358 würde ich einstellbar machen um die Impulse auch sicher zu detektieren.

Unregistriert
29.12.2016, 10:58
Ja richtig...Hab ein Poti an den - Eingang des LM358 dran gebaut um
die Empfindlichkeit und Abstand zur reflecktierenden Markierung
ein zu stellen. Wollte die Außenbeschaltung weitestgehend gering
halten und in der Software erledigen. Aber welches retriggerbares Monopflop würdet ihr vorschlagen.

wkrug
29.12.2016, 12:07
Im einfachsten Fall eine Diode ein Kondensator und ein Widerstand.
Die Eingänge des AVR reagieren wie ein Schmitt Trigger.
Die Diode lädt den Kondensator auf. Der Widerstand entlädt den Kondensator wieder.
Bleibt dann das Signal aus wird der Eingang des AVR LOW.

021aet04
30.12.2016, 08:04
Ich würde einen NE(LM,...)556 nehmen, das sind 2 555-Timer in einem Gehäuse. Mit einer Hälfte würde ich einen AMV aufbauen und damit die LED ansteuern, mit der 2ten Hälfte baust du den MMV auf.

So würde ich es zumindest machen. Wenn etwas nicht funktioniert kann man dann auch etwas messen.

MfG Hannes

wkrug
30.12.2016, 08:30
Ein symetrisches Rechtecksignal mit einem AVR zu produzieren ist ja nun kein Problem und verbraucht auch keine Prozessorressourcen ( Prozessorzeit ).
Eine Treiberstufe für die LED wird man wohl auch brauchen - Ein BS 170 FET kann diese Aufgabe übernehmen.
Der 555 hat schon eine kräftige Treiberstufe, die bis zu 300mA liefern kann.
MMV gibts schon seit C-Mos Zeiten als IC z.B. 4047 - NE 555 ist natürlich auch ne Möglichkeit.
Wenn 555, dann würde ich die C-MOS Variante 7555 verwenden - Braucht weniger Strom.
Du brauchst natürlich ein retriggerbares Monoflop ( MMV ).
Es führen halt viele Wege zum Ziel.

monkye2000
30.12.2016, 09:02
OK, mit zusätzlicher Hardware gehts auch... Aber genau das kann man sich sparen, wenn man die verfügbaren Ressourcen eines MC sinnvoll nutzt - da sparst Du nicht nur Bauteile, sondern auch Platz auf dem PCB. Und Änderungen an der Software sind einfach möglich, bei der Hardware wird es dann komplizierter...

Ach ja, mit einem 555 kann ein MMV gebaut werden :-).