Frage zu Interrupt kann man die laenge eines Impuls Festsetellen

Hallo zusammen

Ich brauche mal wieder Eure Hilfe

Kann man die laenge eines Interrupt(Impuls) Festsetellen damit man Stoerimpulse rausfiltern kann

Will Impulse von S0-Zaehler zaehlen

void setup()
{
  Serial.begin(9600);
  attachInterrupt(1, showTemperatures, FALLING);
}

void loop()
{

}

void showTemperatures()
{
  buttonState = !buttonState;

  Serial.println("Hallo");
}

bye juergen

Da kannste besser einfach nur mit der Bounce Lib arbeiten. Dein Sketch ist nicht optimal. Eine Serielle Ausgabe hat nichts in einem Interrupt zu tun.

Hallo Zusammen

Hallo sschultewolter

Der Code sollte nur ein Beispiel sein

Ich wollte nur wissen ob man Laenge in Millis eines Interrupt(Impuls) Messen kann bei meiner S0-Zäehlung fehlen mir CA. 2% bei 1 Impuls je Sekunde gerechnet ueber 5 Min

bye juergen

Das geht, aber du musst jede Flanke für sich triggern (oder mit CHANGE arbeiten). millis() wird innerhalb von Interrupts nicht aktualisiert, da es selbst in einem Timer Interrupt läuft und sich Interrupts nicht gegenseitig unterbrechen können. Man kann aber am Anfang der ISR einmal millis() machen und die Zeit speichern.

z.B. So:

volatile unsigned long TS1, TS2;
volatile boolean ISR, Flanke;

void ISRpulslang(){
  if (ISR){  // Prüfen, ob letztes Ergebnis schon abgeholt
    if (Flanke){  // steigende Flanke speichern
      TS1 = micros();
      attachInterrupt(0, ISRpulslang, FALLING); // Interrupt an Pin2
      Flanke = !Flanke;
    } else {    // fallende Flanke speichern.
      TS2 = micros();
      attachInterrupt(0, ISRpulslang, RISING); // Interrupt an Pin2
      Flanke = !Flanke;
      ISR = false;  // Flag setzen, dass Ergebnis verfügbar.
    }
  }
}

unsigned long Pulslang(){
  if (!ISR){  // prüfen, ob Ergebnis verfügbar
    noInterrupts();
    unsigned long pulse = Flanke2-Flanke1;
    interrupts();
    ISR = true;  // ISR wieder freischalten
    return (pulse);
  }
  return(0);
} // end Pulslang

In der interrupt Service Routine ISRpulslang() werden die Zeiten der Flanken gespeichert, die dann mit der Funktion Pulslang() in der Loop() ausgewertet werden. Bei mir messe ich damit die Länge von Servo-Steuerpulsen

sschultewolter: Da kannste besser einfach nur mit der Bounce Lib arbeiten. Dein Sketch ist nicht optimal. Eine Serielle Ausgabe hat nichts in einem Interrupt zu tun.

Um klarzustellen. Ein debounce oder die Bounce Lib in der Interruptfunktion hat nichts zu suchen. Mit Interrupt, falls Du ein Entprelen brauchst dann mußt Du es Hartwareseitig machen.

Auch hat Serial.print in der Interruptfunktion nichts zu suchen. Die interruptfunktion muß so kurz wie möglich sein um weitere interrupts nicht zu verlieren.

Grüße Uwe

Hallo Zusammen

Hallo guntherb

Bekomme es nicht hin

Kannst Du es mir in den kurzen sketch einbinden bei ansteigender Flanke sodas Ich im void loop die micros in der Variablen Pulse abfragen kann

bye juergen

Da war sogar noch ein kleiner Fehler drin bei den Variablen.

Das kommt davon, wenn man Teile aus verschiedenen Sketches zusammen kopiert und dann nicht testet. :blush:

Im Anhang der getestete Sketch.

PulseLaenge_messen2.ino (869 Bytes)

Hallo Zusammen

Hallo guntherb

Es laeuft nur wenn Ich PULLUP entferne
mit oder ohne Spannungsteiler !

PinMode(2,INPUT_PULLUP);

Ich Danke dir guntherb

bye juergen

Hallo Zusammen

Hallo guntherb

Ich habe noch mal eine Frage

Was muss man machen wenn man die Laenge der Impulse von 2 Interrupt Messen will.

Das mit dem einen geht sehr gut man kann sogar Stoerimpulse von 10 Miros sehen

Habe einen Arduino Mega 2560

bye juergen

Naja, am einfachsten, in dem man die Funktionen und Variablen mit anderem namen nochmal anlegt.

Also zu

volatile unsigned long TS1, TS2;
volatile boolean ISR, Flanke;

void ISRpulslang(){
usw...

kommt dazu:

volatile unsigned long TS1_b, TS2_b;
volatile boolean ISR_b, Flanke_b;

void ISRpulslang_b(){
usw...

Es gibt elegantere Methoden, aber für 2 Interrupts geht das. Und welcher Pin auf welchen Interrupt geht, kannst du bei ../Reference/AttachInterrupt nachlesen.

Hallo Zusammen

Hallo guntherb

Die belegung der Interrupt kenne Ich Mit dem Umbenen der Funktionen und Variablen war Mir schon klar

nur Ich wusste nicht was volatile ist und ob die Variablen Scluesselworte sind

bye juergen

juergen01: nur Ich wusste nicht was volatile ist und ob die Variablen Scluesselworte sind

Die Variablennamen sind frei gewählt. Die Bedeutung von volatile hättest du in der Referenz nachlesen können.arduino.cc/en/Reference/Volatile

Volatile bedeutet nur, dass die Variable immer im RAM gehalten wird, und nicht als Kopie in einem Register gehalten werden darf. Damit ist sichergestellt, dass sie immer aktuell sind.

Es bedeutet auch dass der Compiler nicht versucht die Variable wegzuoptimieren. Der Compiler kann nicht erkennen wie ISRs aufgerufen werden. Er denkt dann eventuell die Funktion wird nie aufgerufen und "optimiert" an der Variable rum.

Hallo Zusammen

Hallo guntherb

Habe es probiert Interrupt an Pin3 zählt leider nicht kannst Du mir noch mal Helfen

volatile unsigned long TS1, TS2;
volatile boolean ISR, Flanke;

volatile unsigned long TS1_b, TS2_b;
volatile boolean ISR_b, Flanke_b;

void ISRpulslang_b(){
  if (TS1_b){
    if (Flanke_b){
      TS1_b = micros();
      attachInterrupt(1, ISRpulslang_b, FALLING); // Interrupt an Pin3
      Flanke_b = !Flanke_b;
    } else {
      TS2_b = micros();
      attachInterrupt(1, ISRpulslang_b, RISING); // Interrupt an Pin3
      Flanke_b = !Flanke_b;
      ISR_b = false;
    }
  }
}
unsigned long Pulslang_b(){
  if (!ISR_b){
    noInterrupts();
    unsigned long pulse_b = TS2_b-TS1_b;
    interrupts();
    ISR_b = true;
    return (pulse_b);
  }
  return(0);
} // end Pulslang_b



void ISRpulslang(){
  if (ISR){
    if (Flanke){
      TS1 = micros();
      attachInterrupt(0, ISRpulslang, FALLING); // Interrupt an Pin2
      Flanke = !Flanke;
    } else {
      TS2 = micros();
      attachInterrupt(0, ISRpulslang, RISING); // Interrupt an Pin2
      Flanke = !Flanke;
      ISR = false;
    }
  }
}

unsigned long Pulslang(){
  if (!ISR){
    noInterrupts();
    unsigned long pulse = TS2-TS1;
    interrupts();
    ISR = true;
    return (pulse);
  }
  return(0);
} // end Pulslang
  

void setup(){
  Serial.begin(9600);
  pinMode(2,INPUT);
  pinMode(3,INPUT);
  attachInterrupt(0, ISRpulslang, RISING); // Interrupt an Pin2
  attachInterrupt(1, ISRpulslang_b, RISING); // Interrupt an Pin3
}
void loop(){
   long Pulse = Pulslang();
   long Pulse_b = Pulslang_b();
   if (Pulse >0){
   Serial.print(Pulse);Serial.print("\t");Serial.println(" microsekunden");
   }
//  Serial.println(digitalRead(2));

   if (Pulse_b >0){
   Serial.print(Pulse_b);Serial.print("\t");Serial.println(" microsekunden_b");
   }
//  Serial.println(digitalRead(3));
   delay(100);
   
}

bye juergen

Sorry, ich komme erst morgen wieder an einen Arduino. Und so "trocken" fällt mir nix auf. Vielleicht hat ja einer der Cracks eine Idee?

ich weiß nicht, warum dein Sketch nicht funktioniert.

ich habe den Sketch neu aufgebaut, genau nach den Regeln wie du es auch gemacht hast, und er läuft.

Vermutlich hast du bei copy&paste mit anschliessendem Umbenennen irgendwo was vergessen.

volatile unsigned long TS1, TS2;
volatile boolean ISR, Flanke;

volatile unsigned long TS1_b, TS2_b;
volatile boolean ISR_b, Flanke_b;


void setup(){
  Serial.begin(115200);
  pinMode(2,INPUT);
  attachInterrupt(0, ISRpulslang, RISING); // Interrupt an Pin2
  attachInterrupt(1, ISRpulslang_b, RISING); // Interrupt an Pin2
}

void loop(){
   long Pulse = Pulslang();
   if (Pulse >0){
   Serial.print(Pulse);Serial.print("\t");Serial.print(" ms      ");
   }
   long Pulse_b = Pulslang_b();
   if (Pulse_b >0){
   Serial.print(Pulse_b);Serial.print("\t");Serial.println(" ms_b");
   }
   delay(100);
}
  
  
void ISRpulslang(){
  if (ISR){
    if (Flanke){
      TS1 = micros();
      attachInterrupt(0, ISRpulslang, FALLING); // Interrupt an Pin2
      Flanke = !Flanke;
    } else {
      TS2 = micros();
      attachInterrupt(0, ISRpulslang, RISING); // Interrupt an Pin2
      Flanke = !Flanke;
      ISR = false;
    }
  }
}

void ISRpulslang_b(){
  if (ISR_b){
    if (Flanke_b){
      TS1_b = micros();
      attachInterrupt(1, ISRpulslang_b, FALLING); // Interrupt an Pin2
      Flanke_b = !Flanke_b;
    } else {
      TS2_b = micros();
      attachInterrupt(1, ISRpulslang_b, RISING); // Interrupt an Pin2
      Flanke_b = !Flanke_b;
      ISR_b = false;
    }
  }
}

unsigned long Pulslang(){
  if (!ISR){
    noInterrupts();
    unsigned long pulse = TS2-TS1;
    interrupts();
    ISR = true;
    return (pulse);
  }
  return(0);
} // end Pulslang  



unsigned long Pulslang_b(){
  if (!ISR_b){
    noInterrupts();
    unsigned long pulse_b = TS2_b-TS1_b;
    interrupts();
    ISR_b = true;
    return (pulse_b);
  }
  return(0);
} // end Pulslang_b

Hallo Zusammen

Hallo guntherb

Der Sketch laeuft jezt auch bei mir

Ich hatte die Aenderungen im IDE gemacht und Copy + Paste ins Board kopiert

aber egal es laeuft ja jetzt

Ich bedanke Mich nochmal fuer deine Hilfe

Ich danke auch Serenifly fuer seine Info

bye juergen