Forum: Mikrocontroller und Digitale Elektronik Reedkontakt einlesen, Polling oder Interrupt oder Pinchange


von Bahri (Gast)


Lesenswert?

Guten Tag,

ich habe folgendes vor:
Mittels eines Reedkontaktes soll eine Radumdrehung eingelesen werden.
Das Rad dreht dabei mit max. 40 Hz. Dadurch ergibt sich im 
maximalbetrieb alle 25ms ein Signal. Reedschalter haben eine Prellzeit 
von ca. max. 1ms.

Zusätzlich möchte ich, solange der Kontakt geschlossen ist, eine LED 
leuchten lassen.
Mein Gedanke war es nun, den Reed gegen Masse zu schalten. Somit habe 
ich beim schließen eine fallende Flanke, dort schalte ich die LED ein. 
Beim Öffnen habe ich dann wieder eine steigende Flanke, die LED schalte 
ich aus.

Soviel zur Theorie. Jedoch in der Praxis stellen sich mir andere Fragen.
Der Reed Kontakt prellt ja. Somit ist es fraglich, ob ein Interrupt für 
die Messung in Frage kommt, da ich anschließend sowieso über einen Timer 
entprellen muss.

So wie ich das sehe, wäre ein Pinchange in dem Sinne gut, da der erste 
Wechsel die fallende Flanke ist und der nächste Wechsel die steigende 
Flanke, somit liese sich dies für die LED gut auswerten.
Zusätzlich möchte ich ja die Frequenz auswerten und müsste über einen 
Timer die Zeit von fallender zu fallender Flanke (oder analog 
steigend-steigend) auswerten.

Nur wie löse ich diese Aufgabe am besten?
Mit Polling, einer zyklischen Abfrage?
Mit externem Interrupt (INT0, INT1)?
Mit Pinchange Interrupt?

Weiterhin stellt sich für mich die Frage, wie ich das mit der 
Entprellung noch unter den Hut bekomme.
Habe die Suche bemüht, aber irgendwie nichts konkretes gefunden.

Danke für alle Antworten schonmal jetzt.

Gruß
Bahri

von Rainer U. (r-u)


Lesenswert?

Nimmste nen Interrupt und in der ISR baust Du eine Pause von 2ms ein 
(bis das Prellen vorbei ist), dann guckst Du, ob das Relais immer noch 
angezogen ist (damit Du nicht das Ausschalt-Prellen erwischt), dann 
löscht Du evtl. noch anstehende Folgeinterrupts und kehrst aus der ISR 
zurück.

von gert (Gast)


Lesenswert?

Hallo!

Hast du schon überlegt, die Reedkontakte in Hardware zu entprellen, wird 
bei 40 Hz recht gut funktionieren (Tiefpass).

1000 Ohm Widerstand 2,5 µF Kondensator, Grenzfrequenz ca. 60 Hz.

Pause in der ISR ist nicht gut, ISR immer so kurz wie möglich machen!!!

Möglich ist, den externen Interrupt für 20ms abzuschalten nachdem er 
aufgetreten ist, 50 Hz Softwarefilter.

lg

von Bahri (Gast)


Lesenswert?

Hallo Gert,

nein, daran habe ich noch nicht gedacht. Hier liest man immer, dass man 
Entprellung besser softwaremäßig erledigt.
Wie komme ich auf diese Werte? Kondensator nehme ich mal an Elko 
parallel zum Reedschalter. Wiederstand wohl vor den AVR Pin.
Ich hatte gedacht, ich lese das externe Interrupt ein, starte einen 
Timer im Compare Mode 1-2ms in diesem externen Interrupt. Nach den 
eingestellen 1-2ms läuft mein erfolgt mein Timer Interrupt, dort lese 
ich den Pin Status ein und prüfe, ob dieser immernoch auf Masse gezogen 
wird. Wenn ja, Reed Kontakt hat geschlossen, wenn nein, warten auf neue 
Flanke. Aber wenn das so einfach in der Hardware zu lösen ist, wäre das 
ja kein Problem.

Was mir noch etwas Gedanken macht, ist das leuchten lassen der LED, 
während der Kontakt geschlossen ist.
Geplant hatte ich das so:
Erkennen der fallenden Flanke (Reed fängt an zu schließen), warten bis 
entprellt ist, LED anschalten, Flankenerkennung des Interrupts auf 
steigend setzen. Erkennt nun der externe Interrupt die steigende Flanke 
(Reed öffnet sich wieder), wieder Entprellen, LED ausschalten und erneut 
Flankenwechsel auf fallend setzen.
Der Timer zum Messen der Umdrehung wird zunächst bei der ersten 
fallenden Flanke gesichert in ein Start Register und bei der zweiten 
fallenden Flanke in ein End Wert Register. Zusätzlich habe ich einen 
zweiten Timer laufen (1. für die Entprellung), der mir einfach die 
overflows zählt, um später die Frequenz aus der Vergangen Zeit von den 
beiden fallenden Flanken und dem Prozessortakt zu berechnen.
So habe ich das bis jetzt gedacht.

Würdet ihr das genauso machen?
Vielleicht könntest du noch näheres zu der Harware Entprellung sagen :-)

Danke.

Gruß
Bahri

von slowslow (Gast)


Lesenswert?

wie wäre es hiermit:

led, vorwiderstand und reed-kontakt in eine reihe schalten? bei 
geschlossenem kontakt leuchtet die led, bei offenem nicht 
(schalter-prellen wirste mit dem auge nicht sehen). oder denk ich zu 
simpel und für diese led-ansteuerung ist unbedingt ein controller 
erforderlich?

von Bahri (Gast)


Lesenswert?

Hallo slowslow,

die Idee ist prinzipiell ok, was ich nicht erwähnt habe ist, dass der 
Controller auch noch andere Aufgaben erledigen soll und diese Messung 
nur ein Teil der Aufgaben ist.
Deshalb soll die LED auch für andere Aufgaben als Status oder 
Ausgabesymbol dienen und kann daher nicht mit dem Reed in Reihe 
geschaltet werden.

von gert (Gast)


Lesenswert?

Grenzfrequenz:

f=1/(2*PI*R*C)


In Software würde ich es so machen:

Timer1 0,1ms Timer.


void GPIOInt (void)
{
  disableGPIOInt();
  frequency=10000/frequencycount;
  frequencycount=0;
}

void timer1Int (void)
{

  frequencycount++;
  filter++;
  if(filter>20)
  {
    filter=0;
    enableGPIOInt();
  }

}


lg

von octi (Gast)


Lesenswert?

Hallo,

die LED soll jedes mal aufleuchten wenn der Reedkontakt geschlossen 
wird? Dein Rad dreht sich mit 40Hz kommt also 40 mal/sek an dem 
Reedkontakt vorbei und betätigt diesen. Also bei mir sind 40Hz an einer 
LED nur ein Flimmern. Ich mach gerade so etwas ähnliches, wobei meine 
Schaltfrequenzen weit unter 1Hz liegen. Generell bin ich schon der 
Meinung was man an prellen durch ein wenig ext. Hardware beseitigen kann 
muss man sich nicht bis in den µc einschleppen. Falls du 20Hz erkennen 
kannst, dann nimm doch einen ext. oder Pinchangeinterrupt und toggel in 
der ISR den Port an welchem deine LED hängt. Die LED dürfte dann mit 
20Hz flimmern ;-)

Bye

von gert (Gast)


Lesenswert?

Für das Steuern der LED würde ich einfach den Eingang Durchschleifen, 
das Prellen ist mit dem Freien Auge vermutlich nicht erkennbar.

von gert (Gast)


Lesenswert?

octi schrieb:
> Die LED dürfte dann mit
>
> 20Hz flimmern ;-)

Wird wohl eher eine LED die nicht voll leuchtet, glaube kaum, dass da 
noch einzelne Flanken zu erkennen sind.

von hmcv (Gast)


Lesenswert?

Im Prinzip ja, aber die maximale Anzahl der Schaltspiele des 
REED-Kontaktes nicht aus den Augen lassen. 40*60*60=144.000 in der 
Stunde, d.h. in ca. 7h ist eine Million erreicht.

Wieviele werden im Datenblatt garantiert?

Gast

von Bahri (Gast)


Lesenswert?

Hallo,

die genannte Frequenz von 40Hz ist die maximal Frequenz (siehe Anfang 
max. 40Hz). Das heißt nicht, dass sich das ganze immer mit 40Hz dreht. 
Jedes erdenkliche Spektrum von 0 bzw. 1 Hz bis zu 40Hz ist möglich, 
daher macht das schon Sinn. Irgendwann wird es für das Auge in 
Dauerleuchten übergehen, das ist klar.

von octi (Gast)


Lesenswert?

hmcv schrieb:
> Wieviele werden im Datenblatt garantiert?

Da geb ich hmcv recht, sag mal Bahri was spricht eigentlich gegen eine 
Lichtschranke -> Verschleiss- und Prellfrei?

von Bahri (Gast)


Lesenswert?

Die Verschmutzung und die daraus möglicherweise resultierende 
Fehlfunktion.

von octi (Gast)


Lesenswert?

Dann aber Hallgeber, berührungslos und geschlossen.

von Sven (Gast)


Lesenswert?

und prellfrei ;-)

von oldmax (Gast)


Lesenswert?

Hi
Einlesen von Schaltern bzw. Kontakten, sollten immer im Polling 
geschenen und nicht in einer ISR. Eine ISR dafür zu verschwenden ist wie 
der Name schon sagt "Ra(e)iner Unsinn".
Ich wundere mich überhaupt, das immer wieder diese Frage auftaucht... es 
wurde schon so oft gesagt: "keine Kontakte in eine ISR"
Gruß oldmax

von gert (Gast)


Lesenswert?

oldmax schrieb:
> Eine ISR dafür zu verschwenden ist wie
>
> der Name schon sagt "Ra(e)iner Unsinn".

Welchen zweck sollten dann Externe Interrupts haben?

von Bahri (Gast)


Lesenswert?

Viele sagen, dass man das externe Interrupt nur benutzt, um den µC aus 
dem Schlaf zu holen.
Ich habe hier aber über die Suche auch viele Lösungen zum Frequenz 
einlesen gefunden mittels externem Interrupt.
Deshalb auch meine Frage, weil über die Suche diverse Lösungen verwendet 
werden.

von Sven (Gast)


Lesenswert?

>> Welchen zweck sollten dann Externe Interrupts haben?

Für schnelle Sachen wie: Encoder (an Motoren), Software-UART, 
Frequenzmessung...

Für Taster reichen Timer eigentlich meistens aus.

von oldmax (Gast)


Lesenswert?

Hi
> Welchen zweck sollten dann Externe Interrupts haben?
Stell dir vor, du hast eine Elektronik und du möchtest auf einen Impuls 
reagieren. Der µC ist auch für solche Anwendungen gebaut, also braucht 
er externe Interruptleitungen. Für Kontakte ist's aber blödsinn, kein 
Mensch ist in der Lage, Kontakte im kHz - Bereich oder höher zu 
schaltem. ( nur unerwünschtes Kontaktprellen... )Daher kann es auch 
nicht im Sinne des Erfinders sein, dafür einen Interrupt zu vergeuden. 
Natürlich kann man sagen, ich brauch ihn aber anderweitig nicht, daher 
ist's keine Vergeudung. Doch, da eine ISR der Programmschleife immer 
dazwischenfunken wird. Und schaut mal richtig hin, Taster erfassen mit 
ISR, dann aber innerhalb der ISR Zeitschleifen einbauen, um das Prellen 
abzufangen. Daher dollte man sich angewöhnen, die Eingaben am Anfang 
einer Programmschleife einzulesen und in einer internen Speicherzelle zu 
halten. Somit steht der eingelesene Wert innerhalb eines Ablaufes zur 
Verfügung. Am Ende erfolgt dann die Zuweisung der Ausgänge, wobei auch 
hier eine interne Speicherzelle "geopfert" wird. Damit stehen auch 
Ergebnisse bis zum Ende einer Programmschleife zur verfügung. Es macht 
keinen Sinn, innerhalb eines Programmes einen Ausgang mehrfach 
zuzuweisen. Wenn eine ISR benutzt wird, so ist es sinnvoll, nicht eine 
umfangreiche Bearbeitung innerhalb der ISR anzustoßen, sondern sich 
Ereignisflags zu setzen, um diese dann im Hauptprogramm abzuarbeiten. 
Wer sich mal die Mühe macht, die Zeit vom Ereignis bis zur Reaktion über 
das Hauptprogramm zu berechnen, wird feststellen, das das Ergebnis im ms 
- Bereich liegen wird. (abhängig vom Takt und von der Programmgröße )
Gruß oldmax

von Gastofatz (Gast)


Lesenswert?

>Welchen zweck sollten dann Externe Interrupts haben?

Sie haben den Zweck, damit jene Anwendungen realisieren zu können, für 
welche die besonderen Eigenschaften, die externe Interrupts auszeichnen, 
nötig sind. Externe Interrupts können den µC aus dem Power-Down 
aufwecken, und sie können maximal schnell auf Pegelwechsel an einem Pin 
reagieren. Manchmal braucht man das. Aber für von Menschen in einem 
Zeitraster von einigen 10 ms (= eine Ewigkeit für einen µC) betätigte 
Taster oder Reed-Kontakte braucht man das nicht.

von Karl H. (kbuchegg)


Lesenswert?

Gastofatz schrieb:

> Zeitraster von einigen 10 ms (= eine Ewigkeit für einen µC) betätigte
> Taster oder Reed-Kontakte braucht man das nicht.

Wobei man auch noch dazusagen muss, dass man beim Arbeiten mit 
Interrupts die Programmierweise sinnvollerweise umstellen wird. Man muss 
hin zu ereignisorientiertem Programmieren. Macht man das nicht, dann 
kommt es zu den von oldmax (zu Recht) angeprangerten delays in einer ISR 
mit all ihren Nebeneffekten, die letztenedes den 'Vorteil' einer ISR, 
nämlich maximal schnelle Reaktion, völlig zu nichte machen.

Ereignisorientiertes Programmieren ist zwar nicht schwer, wenn man den 
Dreh raus hat, aber doch ein klein wenig aufwändiger.

Und daher hat die lapidare Aussage 'man braucht das nicht' durchaus auch 
Konsequenzen, wenn man darauf antwortet "Etwas nicht brauchen bedeutet 
ja nicht dass man es nicht trotzdem so machen kann"

von Gastofatz (Gast)


Lesenswert?

>"Etwas nicht brauchen bedeutet ja nicht dass man es nicht trotzdem so
>machen kann"

Joa......... war nur'n Test, ob's jemand merkt ;-P

Was Du sagst ist natürlich völlig richtig: Man sollte es - Achtung, 
dreifache Verneinung! - nicht deshalb nicht benutzen, weil mans nicht 
braucht, sondern weil man sich Nachteile einhandeln würde.

von Bahri (Gast)


Lesenswert?

Hallo nochmal,

könnte mir jemand noch erklären, wie man den angesprochenen 
Tiefpassfilter an den µC Pin verschaltet?
Ein Schmitt Trigger ist ja in allen µC Pins vorhanden, sodass es sich 
doch durch den Tiefpassfilter einwandfrei entprellen lassen sollte.
Im Moment reagiert das Programm sauber auf die fallende Flanke, jedoch 
erkennt es manchmal die steigende Flanke nicht und bleibt dort hängen. 
Ich vermute, dass es mit dem Entprellen zusammen hängt.
Nach dem Interrupt Auslöser sperre ich die Interrupts, Lösche das Flag 
(logische 1 schreiben) und starte einen Timer, der nach 1ms überläuft. 
Im Timerinterrupt prüfe ich dann, ob am Pin immernoch HIGH Pegel anliegt 
(bei der steigenden Flanke). Leider geht dies jedoch teilweise nicht, 
und er erkennt keinen High-Pegel. Laut Datenblatt hat der Reed-Kontakt 
nur 0,5ms Schaltzeit inkl. Prellzeit, da sollten die 1ms des 
Timerinterrupts eigentlich reichen, aber irgendwie doch nicht.
Bei der fallenden Flanke gibts keine Probleme auch keine Prellprobleme.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.