Hallo!
Ich möchte das Signal zweier Laserlichtschranken A & B auswerten und
genau ermitteln wie lange die Zeit zwischen den Flanken ist.
Mir fallen da gerade zwei Möglichkeiten ein:
1. Möglichkeit: Verwendung INT0/INT1
Der erste Interrupt startet den Timer, der zweite Stoppt ihn wieder.
Es ist eine kleine Statemachine notwendig da entweder INT0 oder INT1
zuerst kommen kann.
Vorteil: Ich kann wahlweise steigende und fallende Flanke auswerten.
Steigende Flanke = Objekt bewegt sich in die Schranke, Fallende Flanke =
Objekt bewegt sich aus der Schranke
Nachteil: Ist die Zeit zwischen beiden Flanken sehr kurz (im Extremfall
kommen beide gleichzeitig) könnte es zu Fehlern bei der Erfassung
kommen.
2. Möglickeit: Verwendung Capture-Modul
Das Signal beider Lichtschranken wird per Hardware XOR verknüpft. Dieses
Signal geht auf den Capture-Eingang. Eine steigende Flanke setzt den
Timer zurück, eine fallende Flanke Captured den Timerwert ins Register.
Vorteil: Genaue Messung
Nachteile: Ist die Zeit zwischen beiden Flanken sehr kurz (im Extremfall
kommen beide gleichzeitig) könnte es zu Fehlern bei der Erfassung
kommen.
Außerdem kann man nicht feststellen ob das Objekt sich aus oder in die
Schranke bewegt. Wie könnte man das erweitern?
Vielleicht habe ich eine andere Möglichkeit noch gar nicht in Betracht
gezogen. Über einen Tipp oder einen Verbesserungsvorschlag wäre ich sehr
dankbar!
Beste Grüße,
Guizmo
Geschätzt: 5µS +-0.5µS, maximal 1mS
Kurz gesagt, so genau wie mit einem ATmega8 möglich, eventuell mit
kleiner externer Beschaltung.
In der Programmierung/Beschaltung müsste man auf möglichst geringen
Jitter achten.
Grüße,
Guizmo
>Geschätzt: 5µS +-0.5µS, maximal 1mS
Was denn nun? Deine zu erwartende (zu messende) Zeit ist etwa 5µs? Oder
etwa eine Millisekunde?
Und diese Zeit soll mit +/-0,5µs Genauigkeit ermittelt werden???
=> ICP.
Je nachdem wie schnell sich das Objekt durch die Lichtschranke bewegt
ist die zu messende Zeit zwischen ca. 5µS und 1mS. Die Zeiten sollten so
genau wie möglich gemessen werden.
Denkbar wäre das der Vorteiler vom Timer automatisch eingestellt wird
damit fortlaufende Messungen so genau wie möglich vonstatten gehen
(eventuell auch einstellbar).
Wenn man nun das Capture-Modul verwendet, macht die Idee mit der
XOR-Verknüpfung überhaupt Sinn?
Wie kann man feststellen ob nun die steigenden oder fallenden Flanken
der beiden Eingangssignale ausgewertet werden?
Ich möchte jetzt nicht zu sehr ins Detail gehen, mich interessiert eher
die eleganteste technische Lösung die Zeitmessung zu realisieren.
Einfach wäre ein Mega128 Controller mit 2 ICP Eingängen.
Man kann auch einen Interrupteingang und den ICP Eingang kombinieren.
Wenn der Controller vor dem Interrupt im Idel Mode ist, sollte das auch
auf einen Zyklus genau gehen. Also einen externen Interrupt als Start
und ICP als Stop. Das sollte bei 20 Mhz Takt bis 50 ns Auflösung gehen.
> Man kann auch einen Interrupteingang und den ICP Eingang kombinieren.
Dann hat man das Problem, dass beim Ext-Int die Interrupt-Response-Time
greift, während beim ICP der Zeitstempel exakt bei der Flanke genommen
wird. Dann schon lieber zweimal ext-Int, dann heben sich die
Latenzzeiten auf.
Ich halte immernoch ein externes RS-Flipflop (LS1 setzt, LS2 löscht) und
ICP für die günstigere Lösung.
...
Das mit der Interrupt Response Zeit stimmt, aber die ist konstant und
läßt sich berechnen.
Die Lösung mit dem externen Flipflop geht genausogut, braucht aber
externe Hardware. Die minimale Zeit sollte das gleiche sein:
Mit Flipflop die Zeit um die Flanke umzustellen. Mit Interupt die Zeit
um den Timer zu starten.
In beiden Fällen sollte man ab etwa 6 Zyklen (300 ns) messen können,
wenn man es unbedingt will.
2 mal mit externem Interrupt sollte etwas längere minimale Zeit geben,
denn da muss man erst noch die Interruptquelle umschalten, und man muß
mit dem Jump am Anfang der ISR arbeiten. Mit dem Idel Mode
zwischendurch, kann man da aber auch auf einen Zyklus genau werden. Bei
mehr als 65500 Zyklen wird es aber schwierig.
Die Kombination mit ICP und ext. Interrupt hatte ich auch schon
angedacht und scheint mir die beste Lösung zu sein.
Mit einem RS-FF kann ich leider nicht arbeiten da ich von vornherein
nicht weiss ob erst die Schranke A und dann B oder B und A unterbrochen
werden oder habe ich das vielleicht falsch verstanden?
Daher die Idee mit dem Hardware XOR womit man quasi beide Ereignisse
(Objekt bewegt sich in Schranke und Objekt bewegt sich aus Schranke)
erfassen kann.
Ich weiss nur noch nicht genau wie ich die Unterscheidung mache ob A/B
oder B/A.
Hat hier vielleicht jmd noch eine Idee?
Generell würde ich zusätzlich zum Capture-Interrupt auch einen
Overflow-Interrupt einbauen der die Fehlerbehandlung macht und die
internen State-Machines zurücksetzt.
Da die Geschwindigkeit des Objekts relativ konstant ist, kann ich den
Vorteiler des Timers optimal einstellen.
Ich poste heute noch einen Eagle-Plan wo die grundsätzliche Idee nochmal
aufgezeigt ist.
Danke und beste Grüße an alle!
> Das mit der Interrupt Response Zeit stimmt, aber die ist konstant und> läßt sich berechnen.
Sooo konstant ist die (beim AVR) gar nicht, es kommt immer darauf an,
was der Controller zum Zeitpunkt der Interruptanforderung gerade macht.
Denn die (Maschinen-)Befehle haben unterschiedliche Ausführungszeit, der
angefangene Befehl wird immer erst fertig abgearbeitet. Um die
Latenzzeit konstant zu halten, muss man schon dafür sorgen, dass der
Controller immer aus dem Sleep (Idle-Mode) geweckt wird. Das bedeutet
nun wieder, dass die restlichen Arbeiten auf die Zeit nach einer Messung
konzentriert werden. Oder man muss die Differenzen (bis zu 3 Takte)
akzeptieren. Software ICP (also ext.-Int und Timer in der ISR auslesen)
sollte also nicht die erste Wahl sein, wenn es genau werden soll.
> Die minimale Zeit sollte das gleiche sein:> Mit Flipflop die Zeit um die Flanke umzustellen.
Klar wird die minimale Zeit durch die Rechenzeit der ISR (incl. Aufruf
und Rücksprung) bestimmt. Das Umstellen der Flanke kostet bei Verwendung
zweier (unterer) Exklusiv-Register mit den beiden vordefinierten
Bitmustern gerade mal einen Takt (OUT). Der sollte zur Verfügung
stehen... ;-)
> Mit Interupt die Zeit um den Timer zu starten.
Für ICP wird kein Timer gestartet, das wäre kontraproduktiv, denn der
ICP-Int nimmt den Zeitstempel (des laufenden Timers) nicht erst in der
ISR, sondern bereits beim Auftreten der Flanke. Für Impulsmessung
entscheidet man in der ISR anhand eines Merkers, ob es Anfang oder Ende
ist, beim Anfang merkt man sich den Zeitstempel, beim Ende ermittelt man
die Differenz zum gemerkten Anfang. Selbst bei Software-ICP sollte man
den Timer nicht ohne Not anhalten. (Habe ich zwar auch schon gemacht,
würde ich heute aber möglichst vermeiden...) Wohlüberlegtes Verwenden
von Exklusivregistern erspart langsame RAM-Zugriffe.
...
A und B wird XOR verküpft und kommt am ICP dran. Parallel dazu A
und/oder B an zwei/ein Pins. Der ICP triggert immer nur auf L/H Flanke.
Angenommen deine A/B Ausgänge sind L-aktiv, dh. L-Pegel signalisiert
unterbrochene Lichtschranke. Durch das XOR ergibt sich also immer die
Sequenz LLLL-HLH-LLLLLL unabhängig der Richtung in der die Lichtschranke
durchlaufen wird. In der ICP-ISR, die ja immer durch eine L/H Flanke
getriggert wird liest du die beiden Pins für A/B ein. Anhand deren
Kombination kannst du nun ermitteln ob eine Messung beginnt (relativ zur
letzten Messung) und ob eine Messung beendet wurde und in diesem Falle
weist du auch durch diese Pins in welcher Richtung die Lichtschranke
durchlaufen wurde.
Also
1. ICP-ISR, A=L B=H, ICP=L/H Flanke, Messung=not Messung, Messung
beginnt
2. ICP-ISR, A=H B=L, ICP=L/H Flanke, Messung=not Messung, Messung ist
beendet, von A nach B durchlaufen
1. ICP-ISR, A=H B=L, ICP=L/H Flanke, Messung=not Messung, Messung
beginnt
2. ICP-ISR, A=L B=H, ICP=L/H Flanke, Messung=not Messung, Messung ist
beendet, von B nach A durchlaufen
Dies zeigt auch warum ich meine das es ausreicht A xor B an ICP Pin und
A oder B an einem Pin. Du misst ja nur die Zeitspanne zwischen der
Unterbrechung jeweils einer Lichschranke bis zur Unterbrechungen jeweils
nur der anderen Lichtschranke, also Ein- und Austrittspunkt des Objektes
in die Lichtschrankenkonstruktion. Und dieser Ein-/Austrittspunkt ist
klar im Signal definiert, nämlich nur die L/H Flanke des XOR Signales
wenn deine Lichtschranken L-aktiv sind.
Wenn du nur zb. das Signal A auswertest dann siehst du an obiger Tabelle
der möglichen ICP-ISRs das man mit dessen Signal auch die Richtung
bestimmen kann.
Gruß Hagen
Möchtest du das nun störunanfälliger machen dann schliest du A und B and
zwei Pins im level triggered INT Pins an. Spätestens wenn in deren ISRs
an beiden Pins L-Pegel anliegt ist eine Messung zu Ende. Also selbst
wenn dein AVR mit dem ICP zu langsam wäre kannst du so erkennen das die
Variable Messung=False gesetzt werden muß.
Also nochmal
ICP Pin = A xor B und auf L/H Flanke getriggert
INT0 = A, auf L-Pegel getriggert
INT1 = B, auf L-Pegel getriggert
INT0-ISR: wenn A und B = L-Pegel dann Messung = False, wenn Messung =
true war dann Zeitstempel auswerten
INT1-ISR: wenn A und B = L-Pegel dann Messung = False, wenn Messung =
true war dann Zeitstempel auswerten
ICP-ISR:
Messung = not Messung, wenn Messung False war dann beginnt eine neue
Messung, A oder B auswerten für Richtung, Timestamp berechnen
Gruß Hagen
Übrigens ist es dabei egal wie weit die Lichtschranken relativ zur
detektierbaren Objektgröße zueinander angebracht werden. Dein XOR
liefert im minimalen Fall eine Sequenz von LLLLLL-HLH-LLLLLL bei großen
Objekten und engem Abstand der Lichtschranken und bei kleinen Objekten
mit größerem Abstand eine Sequenz wie LLLL-HL-LLLLL-HL-LLLLL. Du
triggerst den ICP aber immer nur auf L-H bzw. H-L Flanke.
Theoretisch kannst du sogar ermitteln ob mehr als ein Objekt in deine
Konstruktion reingelaufen ist oder sogar ob das Objekt innerhalb der
Konstruktion seine Richtung geändert hat ;)
Gruß Hagen
@Hagen Re: Wow, danke für diese ausführliche Beschreibung. Damit sollte
ich das aus alle Fälle hinkriegen.
Die Schranken haben entweder einen H oder L Ausgang sobald sie
unterbrochen werden. Unterschied sollte das keinen machen, A xor B gibt
immer das selbe Ergebnis und INT0/INT1 kann man ja einstellen ob H oder
L-Level aktiv.
Grüße, Guizmo
>Unterschied sollte das keinen machen, A xor B gibt>immer das selbe Ergebnis und INT0/INT1 kann man ja einstellen ob H oder>L-Level aktiv.
Nur in der Software macht es einen Unterschied, aber mariginal, bei der
Auswertung der Zustände A/B an den Pins.
Ich empfehle dir mal praktisch deine Lichtschrankenkonstruktion auf dem
Papier aufzumalen und alle Zustände wenn sich ein Objekt von Links und
Rechts durchbewegt zu simulieren. Das Objekt einmal mit kleinerem
Durchmesser als der Abstand der Lichtschranken und einmal mit größeren.
Unter der Bedingung A xor B am ICP und A und B zusätzlich an INTx Pins.
Du wirst sehen das sowas oft bei der Problemlösung hilft und in deinem
Falle eigentlich zeigt wie trivial es ist. Um auf alle Eventualitäten
vorbereitet zu sein simulierst du noch das das Objekt innerhalb der
Lichtschranken verschwindet oder Richtung wechselt und schwups weist du
wie du in deiner FSM getriggert durch ICP und INTx und Timer reagieren
musst um Fehlmessungen auszuwerten.
Gruß Hagen