Go Down

Topic: Interrupt - FALLING verhält sich wie CHANGE?! (Read 890 times) previous topic - next topic

Mahimus

Feb 09, 2019, 01:04 am Last Edit: Feb 09, 2019, 06:30 pm by Mahimus
Hallo,

Ich habe ein seltsames Problem wenn ich meinen digitalen Drehzahlsensor mit Interrupt auslesen möchte. Und zwar passiert das gleiche, wenn ich beim Einrichten des Interrupt eine fallende oder eine sich ändernde Flanke als Trigger verwenden möchte. In beiden Fällen wird die ISR bei einem Wechsel von HIGH zu LOW oder umgekehrt ausgeführt. Glaubt mir jetzt sicher keiner, ist aber so. Hab deshalb eine ewige Fehlersuche hinter mir da die Werte nie gestimmt haben. Vielleicht kann mir jemand sagen warum das so sein könnte oder jemand zeigt mir meinen Denkfehler auf.

Hier der Code und unten angefügt ein Plot davon, was der Sensor so ausgibt. Der tut tatsächlich was er soll und fällt mMn als Fehlerquelle raus.

Code: [Select]


volatile byte Flanken_L = 0;  
volatile byte Flanken_R = 0;  
volatile unsigned long t4_interrupt;
volatile unsigned long t5_interrupt;

void setup() {

  attachInterrupt(digitalPinToInterrupt(2), count_Flanken_R , CHANGE);  //rechter Raddrehzahlsensor
  attachInterrupt(digitalPinToInterrupt(3), count_Flanken_L , CHANGE);  //linker Raddrehzahlsensor


  Serial.begin(9600);
  
}

void loop() {

  Serial.println(Flanken_L);

}

void count_Flanken_R(){
  if(millis()-t4_interrupt>5){
   Flanken_R++;
   }
   t4_interrupt = millis();
}

void count_Flanken_L(){
  if(millis()-t5_interrupt>5){
   Flanken_L++;
   }
   t5_interrupt = millis();
}





Whandall

Code: [Select]
  attachInterrupt(digitalPinToInterrupt(2), count_Flanken_R , CHANGE);  //rechter Raddrehzahlsensor
  attachInterrupt(digitalPinToInterrupt(3), count_Flanken_L , CHANGE);  //linker Raddrehzahlsensor


Der Kode soll ja auch bei CHANGE triggern, macht also genau was er soll.
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

DrDiettrich

Wozu soll die seltsame Bremse mit millis() dienen?

Ein glaubhafter Test wäre das selbe Signal auf beiden Pins, und ein Interrupt mit CHANGE und der andere mit RISING oder FALLING, und dann die Ausgabe beider Zähler alle Sekunde oder so.

Rentner

Hallo,

wie hoch sind denn die Frequenzen die Du messen willst. Die Bremse mit den 5 ms / halber Periode  soll ja entprellen. damit kannst du also nur alle 5ms  eine Flanke erkennen. Wenn jetzt beide Flanken erkannt werden sollen "Change" kann das dazu führen das die 5 ms noch nicht abgelaufen sind, damit wird dann nur wieder jede zweite gezählt was identisch mit falling oder rising wäre.

5ms *2 =10ms je Periode -> 100Hz ist nicht viel

Heinz

postmaster-ino

Hi

Wieso der Plot (kann Das die IDE selber?) per analogRead, wenn DU im späteren Programm auf die Flanke, also DIGITAL, reagieren willst?

Nichts desto Trotz, bei CHANGE wird bei jeder Flanke gewechselt.
Sofern Dein Sensor kein Mechanischer ist, kannst Du Dir die millis()-Bremse sparen, elektronische Sensoren prellen nicht (wäre mir zumindest noch Keiner untergekommen).

Die Idee von Whandall klingt zielführend!
Setze einen Interrupt auf CHANGE, den Anderen auf RISING/FALLING und lasse Dir in der loop() alle Sekunde die Zählerstände ausgeben.

Dafür wird aber wohl BYTE als Typ für die Zähler zu Klein sein, oder hast Du nur 255 (127) Impulse pro Sekunde?
... also ohne die Bremse - mit, wie gerade auch gepostet wurde, sind's maximal 100 Erkennungen/Sekunde.

MfG
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

DrDiettrich

Die Idee von Whandall klingt zielführend!
Setze einen Interrupt auf CHANGE, den Anderen auf RISING/FALLING und lasse Dir in der loop() alle Sekunde die Zählerstände ausgeben.
Grummel! Wer klaut da meine Lorbeeren?

Mahimus

100Hz ist die absolute höchste Frequenz die auftritt. Der Sensor prellt manchmal. Ich habe natürlich beides, FALLING und CHANGE, ausprobiert. Jedes mal zählt das Programm bei einer Radumdrehung genau 40 Flanken. Die Lochscheibe hat 20 Löcher. Mehrfach ausprobiert.

Ich habe den Sensor mal analog ausgelesen, weil ich genau wissen wollte was der so ausspuckt. Dann hab ich ihn natürlich wieder an den digitalen Pin gehängt bevor jetzt einer fragt.

Rentner

Hallo,

analog ?? wozu sollte das sein, wolltest Du die Kurvenform sehen .

Hast Du mal an den IR Registen rumgespielt ?

Muss jetzt noch mal fragen ,
was ist das für ein Sensor
wie hast du den Sensor angeschlossen
wie hast Du den Pin mit pinMode eingestellt.

schreib mal einen ganz normalen Sketch und finde raus ob die Pegel richtig erkannt werden.

Heinz




Mahimus

#8
Feb 09, 2019, 02:05 pm Last Edit: Feb 09, 2019, 03:11 pm by Mahimus
Hallo,

analog ?? wozu sollte das sein, wolltest Du die Kurvenform sehen .

Hast Du mal an den IR Registen rumgespielt ?

Muss jetzt noch mal fragen ,
was ist das für ein Sensor

wie hast du den Sensor angeschlossen

wie hast Du den Pin mit pinMode eingestellt.

schreib mal einen ganz normalen Sketch und finde raus ob die Pegel richtig erkannt werden.

Ja, wollte genaus sehen was der ausgibt, also die Kurvenform. Sieht gut aus, Sensor funktioniert also. Das war Teil der Fehlersuche.

Es ist dieser Sensor: https://www.ebay.de/itm/Dual-Drehzahlsensor-Counting-Modul-fur-Odometrie-Drehzahlmessung-Arduino-Raspb/201448285399?hash=item2ee740e4d7:g:0NoAAOSwumFbfpQ6:rk:1:pf:1

Ich habe ihn richtig angeschlossen. Irgendwie weiß ich nicht was ich da anderes sagen soll, er funktioniert wunderbar, was soll ich da jetzt zum dritten mal die Verkabelung prüfen.

Ich hab wie du oben im Code siehst keinen PinMode Befehl gegeben, daher sind sie ganz normal auf Input eingestellt.

Hab ich schon geprüft. Hier ist mal ein Code der auch funktioniert und pro Radumdrehung 20 Flanken zählt, also das was ich erwarten würde von Interrupt mit Falling:

Code: [Select]

 bool Status_R = digitalRead(2); 
     if(letzterStatus_R == LOW && Status_R == HIGH){
         Flanken_R++;
         }
       letzterStatus_R = Status_R;
       Radumdrehungen_R = Flanken_R/20.0;
       
     bool Status_L = digitalRead(3); 
     if (letzterStatus_L == LOW && Status_L == HIGH){
          Flanken_L++;
          }
       letzterStatus_L = Status_L;
       Radumdrehungen_L = Flanken_L/20.0;


Whandall

#9
Feb 09, 2019, 04:59 pm Last Edit: Feb 09, 2019, 05:01 pm by Whandall
CHANGE und FALLING funktionieren genau wie erwartet und dokumentiert (auf einem Mega),
also  Interrupt - FALLING verhält sich wie CHANGE:

Code: [Select]
const byte pinD2 = 2;
const byte pinD3 = 3;

uint16_t toggle2;
uint16_t toggle3;

volatile uint16_t countISR2;
volatile uint16_t countISR3;

void isr2() {
  countISR2++;
}
void isr3() {
  countISR3++;
}
void setup() {
  Serial.begin(250000);
  pinMode(pinD2, OUTPUT);
  pinMode(pinD3, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(pinD2), isr2, FALLING);
  attachInterrupt(digitalPinToInterrupt(pinD3), isr3, CHANGE);
}

void loop() {
  static uint32_t lastSecond;
  static uint32_t lastToggle2;
  static uint32_t lastToggle3;
  uint32_t topLoop = millis();
  if (topLoop - lastSecond >= 1000) {
    lastSecond = topLoop;
    noInterrupts();
    uint32_t copy2 = countISR2;
    uint32_t copy3 = countISR3;
    countISR2 = 0;
    countISR3 = 0;
    interrupts();
    Serial.print(F("D2: toggled "));
    Serial.print(toggle2);
    Serial.print(F(" counted "));
    Serial.print(copy2);
    Serial.print(F(", D3: toggled "));
    Serial.print(toggle3);
    Serial.print(F(" counted "));
    Serial.println(copy3);
    toggle2 = 0;
    toggle3 = 0;
  }
  if (topLoop - lastToggle2 >= 7) {
    toggle2++;
    digitalWrite(pinD2, !digitalRead(pinD2));
    lastToggle2 += 7;
  }
  if (topLoop - lastToggle3 >= 5) {
    toggle3++;
    digitalWrite(pinD3, !digitalRead(pinD3));
    lastToggle3 += 5;
  }
}

Code: [Select]
D2: toggled 142 counted 71, D3: toggled 199 counted 199
D2: toggled 143 counted 71, D3: toggled 200 counted 200
D2: toggled 143 counted 72, D3: toggled 200 counted 200
D2: toggled 143 counted 71, D3: toggled 200 counted 200
D2: toggled 143 counted 72, D3: toggled 200 counted 200
D2: toggled 143 counted 71, D3: toggled 200 counted 200
D2: toggled 142 counted 71, D3: toggled 200 counted 200
D2: toggled 143 counted 72, D3: toggled 200 counted 200
D2: toggled 143 counted 71, D3: toggled 200 counted 200
D2: toggled 143 counted 72, D3: toggled 200 counted 200
D2: toggled 143 counted 71, D3: toggled 200 counted 200
D2: toggled 143 counted 72, D3: toggled 200 counted 200
D2: toggled 143 counted 71, D3: toggled 200 counted 200
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

Mahimus

Danke für die Mühe, aber hilft mir jetzt nicht wirklich weiter. Wenn jemand meinen Code auf einem Uno ausprobiert und etwas anderes beobachtet als ich es tue wäre das aussagekräftiger. Ich glaub nämlich eigentlich auch nicht so ganz, dass die "Modi" prinzipiell nicht funktionieren. Dann wäre ja viel früher einer drauf gestoßen. Aber das was du so selbstsicher durchstreichst ist eben das, was ich bei mir beobachte.

Whandall

#11
Feb 09, 2019, 05:40 pm Last Edit: Feb 09, 2019, 06:05 pm by Whandall
Benutze alle Mechanismen meines Sketches und deine Symptome verschwinden.
Oder es wird von der Hardware verursacht, was man aber ziemlich auschließen kann.

"Interrupt - FALLING verhält sich wie CHANGE" ist einfach falsch.

Uno hattest du noch nicht erwähnt, spielt aber für diese beiden externen Interrupts auch keine Rolle.

P.S.: Deine 6 ms Debounce-Zeit ist auf alle Fälle viel zu lang für ein 100 Hz Signal (20%);

Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

postmaster-ino

Hi

Da es sich bei dem Sensor - wie erwartet - um eine Elektronik handelt, prellt Da Nichts.
Wenn Du wider Erwarten dort Mehrfach-Signale bekommst, dann erkennen die Lichtschranke Mehrfach!
Denke, Du hast Fusseln oder so Was auf der Schlitzscheibe.
Alternativ wäre eine wesentlich kürzere Entprellzeit ein Versuch wert - der Sensor selber prellt nicht!

MfG
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

Doc_Arduino

Hallo,

mach folgenden Test. Nimm einen ausgeleierten Taster. In dem Fall hier soll er prellen. Den schließt du an beide Interrupt Pins an. Einen mit change und den anderen mit falling (oder rising) konfiguriert. Jetzt muss der falling/rising konfigurierte stets den halben Zählerstand zeigen als der change.
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Doc_Arduino

Hallo,

@ Whandall:  #9  pinD2 und pinD3 sind sicherlich keine Ausgänge. ;)
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Go Up