Go Down

Topic: INT0 ISR acts strange once in 30-50 interrupts (Read 54 times) previous topic - next topic

Hi
Please help. I can't find the error in this.
I have an old "grandfathers clock" 2m tall. I am trying to detect how many "gongs/hit on the bell" when the clock is 1, 2, 3 ... half past etc. When the clock is i.e. 5 the distance in time between the hits are app 1.5 sec.
I am using INT0 for triggering my code using an Arduino Uno rel 3
Variables modified during the interrupt are declared volatile.
Below you can find a log of what is happening.
My problem can be seen in line 20 "2 - one Gong only: 1    Activated twice - and then all this happens"
and the next three lines.
I do not understand why it can go into "2" without have been in "1" before.
The sensor is a Hall element with fair hardware filtering. The nature of the code should also help on debouncing.

Interrupts are disabled during the if-sentences even though it should not be needed.
it does not help anyway.

I am sure someone out there can teach me.
Many thank you in advance.

Please see code below - and logfile very below
/*
  Knock on a bell caught on INT0
  Name: Bornholmer4
  the purpose of this code is to detect the hammer in an old "Grandfather's clock"
  to get how many hits (3 hits at 3 o'clock) I dont care if only 1 hit i.e. half past and at 1 o'clock
  bellHit is run each time the bell is hit.
  First if sentence is run each time the bell is hit because WakeUp was set true in the ISR. Timeout reset
  The second if sentence is run if only one hit before Bell timeout
  The third if sentence is run after at least 2 hits and the timeout has run out
*/

volatile int bellCount = 0;
volatile int WakeUp = false;

unsigned long gongInterval = 2000;  // Bell timeout
volatile unsigned long previousMillis = 0;

void setup()
{
  attachInterrupt(0, bellHit, FALLING);
  Serial.begin(9600);
  Serial.println("First shot on a statemachine with INT0 from the bell in a big clock");
}

void loop()
{
  if (WakeUp == true){  // First if sentence
    noInterrupts();  // should not be needed
    previousMillis = millis();
    WakeUp = false;
    Serial.print("1 Interrupt - Gongs: ");   
    Serial.println(bellCount);
    interrupts();    // should not be needed
  }
  if ((unsigned long)(millis() - previousMillis) >= gongInterval & bellCount == 1){  // Second if sentence
    noInterrupts();  // should not be needed
    Serial.print("2 - one Gong only: ");   
    Serial.println(bellCount);
    Serial.println();
    bellCount = 0;
    interrupts();  // should not be needed
  }
  if ((unsigned long)(millis() - previousMillis) >= gongInterval & bellCount >= 2){  // Third if sentence
    noInterrupts();  // should not be needed
    Serial.print("3 -  2 or more: " );   
    Serial.println(bellCount);
    Serial.println();
// do the work needed, when the clock is 2 or more.
    bellCount = 0;
    interrupts();    // should not be needed
  }
}

void bellHit()  // ISR
{
  noInterrupts();
  WakeUp = true;
  bellCount = bellCount + 1;
  interrupts();
}

logfile:
First shot on a statemachine with INT0 from the bell in a big clock
1 Interrupt - Gongs: 1   Activated once
2 - one Gong only: 1   OK

1 Interrupt - Gongs: 1   Activated once
2 - one Gong only: 1   OK

1 Interrupt - Gongs: 1   Activated twice
1 Interrupt - Gongs: 2
3 -  2 or more: 2   OK

1 Interrupt - Gongs: 1   Activated twice
1 Interrupt - Gongs: 2
3 -  2 or more: 2   again OK

1 Interrupt - Gongs: 1   Activated twice
1 Interrupt - Gongs: 2
3 -  2 or more: 2   again OK

2 - one Gong only: 1   Activated twice - and then all this happens

1 Interrupt - Gongs: 0
1 Interrupt - Gongs: 1
2 - one Gong only: 1   only one is counted up - should have been two

1 Interrupt - Gongs: 1   Activated twice
1 Interrupt - Gongs: 2
3 -  2 or more: 2   again OK

1 Interrupt - Gongs: 1   Activated twice
1 Interrupt - Gongs: 2
3 -  2 or more: 2   again OK

More examples below - usually OK :-(

1 Interrupt - Gongs: 1
1 Interrupt - Gongs: 2
1 Interrupt - Gongs: 3
3 -  2 or more: 3

1 Interrupt - Gongs: 1
1 Interrupt - Gongs: 2
1 Interrupt - Gongs: 3
1 Interrupt - Gongs: 4
3 -  2 or more: 4

1 Interrupt - Gongs: 1
2 - one Gong only: 1

1 Interrupt - Gongs: 1
1 Interrupt - Gongs: 2
1 Interrupt - Gongs: 3
1 Interrupt - Gongs: 4
1 Interrupt - Gongs: 5
1 Interrupt - Gongs: 6
1 Interrupt - Gongs: 7
3 -  2 or more: 7


Solved
Second if sentence was missing one condition marked bold

  if ((unsigned long)(millis() - previousMillis) >= gongInterval & bellCount == 1 & WakeUp == false){

That solved the problem
Sorry.

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy