Events Zählen mit Interrupt (Arduino, Zeitproblem)

OP #6117181
Lesenswert?

Nach langer Zeit bin ich mal wieder zurück im Forum, gleich mit einer 
Frage.
Ich möchte einen Geigerzähler am Arduino anbinden. Alles was der Arduino 
machen soll, ist die Impulse in 10 sek. Zählen, mit 60 multiplizieren 
und anschließend ausgeben und dann wieder messen usw.
Die Impulse sind als Interrupt eingebunden, das klappt auch ganz gut. 
Allerdings hab ich das Gefühl, dass jeder Impuls und damit der Interrupt 
die Messzeit verlängert, und bei 5000 Imp. ist das schon sehr spürbar. 
Kann man das umgehen? Im Anhang der aufs Wesentliche gekürzte Code:






  Void setup(){
  attachInterrupt(0,countPulse,FALLING);
}

void loop(){
  if (millis()-timePreviousMeassure > 10000){
    countPerMinute = 6*count;
    radiationValue = countPerMinute * CONV_FACTOR;
    timePreviousMeassure = millis();
    Serial.print("cpm = ");
    Serial.print(countPerMinute,DEC);
    Serial.print(" - ");
    Serial.print("uSv/h = ");
    Serial.println(radiationValue,4);
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("CPM=");
    lcd.setCursor(4,0);
    lcd.print(countPerMinute);
    lcd.setCursor(0,1);
    lcd.print(radiationValue,4);
    lcd.setCursor(6,1);
    lcd.print(" uSv/h");

    count = 0;

  }

}

void countPulse(){
  detachInterrupt(0);
  count++;
  while(digitalRead(2)==0){
  }
  attachInterrupt(0,countPulse,FALLING);
}
#6117214
Lesenswert?

Daniel O. schrieb:
> Im Anhang der aufs Wesentliche gekürzte Code:

Gekürzter Code ist immer Mist, wenn Du ihn nicht getestet hast.
Und Du hast ihn nicht angehängt, sondern eingefügt.
Häng den exakten getesteten Code an.

Was auffällt, zwischen
>    timePreviousMeassure = millis();
und
>    count = 0;
ist noch ein riesen Codewust für Ausgaben. Das kostet natürlich Zeit, wo 
nicht gezählt wird.

yesitsme schrieb:
> Warum detach/attach im ISR?

Ja, sowas macht man nicht.
#6117270
Lesenswert?

- count ist nicht volatile
- digitalRead ist so ziemlich die langsamste variante, um einen pin zu 
lesen -> würde ich nie in einer isr verwenden
- while in der isr? sofort raus damit!!
- wie schon geschrieben -> die isr kommt nur bei einer flanke. wozu also 
auf eine pinänderung warten?
- code verlinken ist blöd! schreib wenigstens dazu, dass er gaaaanz 
unten auf der seite ist - dann muss ich nicht so viel scrollen sondern 
kann gleich auf ende drücken
- count direkt nach der berechnung von countperminute nullen, nicht erst 
so spät
Gast #6117284
Lesenswert?

Nur mal so ins blaue geratet.

Je mehr Signale du bekommst, desto langsamer ist dein Update auf dem 
Monitor/LCD? So habe ich dein Problem verstanden. Arduino Reference sagt 
dazu

millis() relies on interrupts to count, so it will never increment 
inside an ISR

Und wenn in deiner Main steht

if (millis()-timePreviousMeassure > 10000)

und millis bekommt kein update mehr, dann wird das ganze etwas länger 
dauern.

By the way, Arduino Reference solltest du dir wirklich mal anschauen. Da 
steht nämlich auch

attachInterrupt(digitalPinToInterrupt(pin), ISR, mode) (recommended)

Weil die Interruptzahl 0 hätte ich auf 0x00 geschätzt und das wäre der 
Reset Interupt.

Cheers

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren