Go Down

Topic: Interrupt Frage CHANGE FALLING Pinstate (Read 717 times) previous topic - next topic

mde110

Ich verwende attachInterrupt und die ISR um damit Impulse zu Messen.

Das Problem ist jetzt, dass ich gerne beide Flanken messen würde. Die Pinabfrage ist aber zu langsam, da ich Impulse mit 600µs erfassen möchte.
Gibt es oder kennt jemand eine Alternative, um in der ISR den Event (FALLING,RISING, HIGH oder LOW) zu bekommen?

uwefed

CHANGE
attachInterrupt(0, intFunktion, CHANGE);

siehe http://arduino.cc/en/Reference/AttachInterrupt

Grüße Uwe

mde110

#2
Feb 09, 2013, 01:41 am Last Edit: Feb 09, 2013, 01:54 am by mde110 Reason: 1
In dem Beispiel wird aber nicht der Zustand des Interrupts verarbeitet.
Ich weiß in der ISR, dass der Signalzustand sich gewechselt hat, aber nicht wie der aktuelle Zustand ist.
Gibt es kein Register in dem die Ursache für den IRQ steht?

jurs


In dem Beispiel wird aber nicht der Zustand des Interrupts verarbeitet.
Ich weiß in der ISR, dass der Signalzustand sich gewechselt hat, aber nicht wie der aktuelle Zustand ist.
Gibt es kein Register in dem die Ursache für den IRQ steht?


Also ich kenne nur die Methode, dass ich den aktuellen Zustand in der allerersten Programmzeile der ISR abfrage, z.B.:
int State = digitalRead(DATAPIN);
und dann steht der Pinstatus innerhalb der ISR in einer Variablen.

Und das funktioniert auch dann bestens, wenn ich z.B. bei einem 433MHz Empfänger beim Funkempfang Impulse mit 600 µs Dauer von solchen mit 1200 µs Dauer unterscheiden möchte.

uwefed


In dem Beispiel wird aber nicht der Zustand des Interrupts verarbeitet.
Ich weiß in der ISR, dass der Signalzustand sich gewechselt hat, aber nicht wie der aktuelle Zustand ist.
Gibt es kein Register in dem die Ursache für den IRQ steht?

Die zweite metode ist ähnlich: direkt das datenregister der Eingänge auslesen und das entsprechende Bit kontrollieren:
http://playground.arduino.cc/Learning/PortManipulation
Das gesagte gilt auch für den Atmega328.

Grüße Uwe

mde110


... bei einem 433MHz Empfänger beim Funkempfang Impulse mit 600 µs Dauer von solchen mit 1200 µs Dauer unterscheiden möchte.

Genau da brauche ich es 8)

Da ich aber mit digitalRead große Schwankungen in der Erkennung hatte muss ich das verwerfen. Wie hast nur du das geschafft???
Bis jetzt läufts mit
Code: [Select]
const bool RXPIN = (PINE&B100000)>>5;

jurs


Genau da brauche ich es 8)

Da ich aber mit digitalRead große Schwankungen in der Erkennung hatte muss ich das verwerfen. Wie hast nur du das geschafft???


Timing natürlich mit micros().
Und ISR Routinen laufen dann stabil im System, wenn sie KURZ laufen.

Das erreichst Du dadurch, dass sämtliche langlaufenden Aktionen NUR in der loop laufen, z.B. Auswertung von Funkprotokollen, aber nicht in der ISR!

Die ISR ermittelt die Länge der Impulse, dampft ggf. die Datenmenge ein, und speichert die Werte in einem Ringpuffer weg. Hinweis: Die Variablen des Ringpuffers müssen "volatile" deklariert werden, damit ein problemloser Zugriff auf korrekte Variablenbereiche sowohl von der ISR als auch von der loop aus möglich ist.

Beispielhafter Code für eine Interrupt-Behandlungsroutine zum Ermitteln von sowohl Low- als auch High-Impulsen, die Ringpuffer-Logik zum Wegspeichern der Daten muss dort eingefügt werden, wo die Kommentarzeilen stehen.

Code: [Select]

void rx433Handler()
{
 static long rx433LineUp, rx433LineDown;
 long LowVal, HighVal;
 int rx433State = digitalRead(RX433DATAPIN); // current pin state
 if (rx433State) // pin is now HIGH
 {
   rx433LineUp=micros(); // line went HIGH after being LOW at this time
   LowVal=rx433LineUp - rx433LineDown; // calculate the LOW pulse time
   // Hier ggf. viel zu kurze und viel zu lange Impulse verwerfen,
   // sowie ggf. den LowVal ggf. auf int eindampfen (Speicherplatz!),
   // oder ggf. auch direkt per Vergleich ermitteln, ob ein 1-Bit, 0-Bit oder Startbit empfangen wurde
   // und den Wert zur Verarbeitung in der loop in einem Ringpuffer (volatile!) wegspeichern
 }
 else
 {
   rx433LineDown=micros(); // line went LOW after being HIGH
   HighVal=rx433LineDown - rx433LineUp; // calculate the HIGH pulse time
   // Hier ggf. viel zu kurze und viel zu lange Impulse verwerfen,
   // sowie ggf. den HighVal ggf. auf int eindampfen (Speicherplatz!),
   // oder ggf. auch direkt per Vergleich ermitteln, ob ein 1-Bit, 0-Bit oder Startbit empfangen wurde
   // und den Wert zur Verarbeitung in der loop in einem Ringpuffer (volatile!) wegspeichern
 }
}

Go Up