Arduino Due fires Interrupt when i get out of my chair or people move in room

This is what I get for reading 6 threads at the same time... :blush:

I'd be using some form of anti-bounce.

In hardware, this could be just a 0.01uF capacitor from the input pin to ground.

This hardware filter will provide a 10ms fall, 20ms rise filter that will make the D10 interrupt input immune to noise and AC signal pickup.

Time Constant Calculator

Note that alternatively, with some register level programming of the D10 input, the hardware debouncing feature in the SAM3X can be used.

Note that there is a difference as to how a typical debouncer and a filter work:
A debouncer will respond instantaneously to a signal transition then have a time-out interval.
A filter slows the rise and fall time of the signal.
The average response time for a person to react and press a button is around 1/4 second.

See: Interference on my digital input - suggested fixes? - General Electronics - Arduino Forum

dlloyd's solution looks like a good one to try. I also use twisted pair if going any distance.

dlloyd:
This hardware filter will provide a 10ms fall, 20ms rise filter that will make the D10 interrupt input immune to noise and AC signal pickup.

Time Constant Calculator

Note that alternatively, with some register level programming of the D10 input, the hardware debouncing feature in the SAM3X can be used.

Note that there is a difference as to how a typical debouncer and a filter work:
A debouncer will respond instantaneously to a signal transition then have a time-out interval.
A filter slows the rise and fall time of the signal.
The average response time for a person to react and press a button is around 1/4 second.

Hey Thanks!

Your circuit works very good in my firt test. It only triggered one false positive and that was when i touched the door handle nearby and got zapped bystatic electricity ( I did not have physical contact with any part of the circuit at that point, so it mustve transmitted through the air).

I had another circuit used in hardware debouncing of interrupts by Jeremy Blum using an inverted schmitt trigger and an rc circuit. This reduced the bouncing but didnt help with the eletrostatic noise / false positives whatsoever.

That was the circuit i used before (only the lowest of the 3 depictured):

Hey Thanks!

Your circuit works very good in my firt test. It only triggered one false positive and that was when i touched the door handle nearby and got zapped bystatic electricity ( I did not have physical contact with any part of the circuit at that point, so it mustve transmitted through the air).

As per your Thomas Edison quote, an improvement might be to add 1K series resistance in the ground wire to the switch and clhange the capacitor to 2.2µF.

dlloyd:
As per your Thomas Edison quote, an improvement might be to add 1K series resistance in the ground wire to the switch and clhange the capacitor to 2.2µF.

Haha, yeah you got me on that one...can you please explain why the change of the capacitor and the resistor should bring improvement? I am not from an electronics background.

I still havent totally solved the problem with the interrupts, since now i dont get false positives, but when i call

attachInterrupt(PIN_SWITCH_MOTOR, calibrateMotorSide, FALLING);
attachInterrupt(PIN_SWITCH_END, calibrateEndSide, FALLING);

the interrupt fires ONE time, then after that it works like it should. Where does that initial interrupt come from? How can i prevent this? This seems to be a huge flaw in the Arduino provided interrupt functions.

I tried to solve this problem in this Thread, but so far no luck.

I need a clue, tried so many things already, nothing helped. Please help guys!

I'm going to move this to the Due section, as this is a Due problem now.

However on the Uno, an initial interrupt will come because the flag for that interrupt has been set in the processor before you do the attachInterrupt, and thus it immediately fires. There may be a way of clearing that flag on the Due (like there is on the Uno).

Hi,

Have you got this set up on protoboard?

Please can you post a picture of your project?

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png or pdf?

Can you describe your application, what is it accomplishing?

Thanks.... Tom... :slight_smile:

MaxBlitz:
I still haven't totally solved the problem with the interrupts, since now I don't get false positives, ...

All very well and good for "an academic/ learning exercise", but the bigger question here, is why you would be using an interrupt in the first place, for a totally inappropriate purpose - monitoring a pushbutton?

Haha, yeah you got me on that one...can you please explain why the change of the capacitor and the resistor should bring improvement? I am not from an electronics background.

The series resistor would help reduce transients or spikes on the ground wire to the switch and the capacitor change is probably not required if the original filter on the interrupt input already works. As Paul__B has pointed out, I'm also curious why an interrupt would be required in monitoring a pushbutton.

This works: (I know it's an UNO and not a DUE. I just thought it might work for the OP)

The push button is connected to pin d7. There is no other circuitry other than described here. No caps.
No resistors. Nothing. (except the push button switch has the standard 10k pullup and the switch has
a 1 k pulldown to ground on the other terminal so a button press connects d7 to GND through the 1 k pulldown.)

d4 is jumpered to d2 (d2 is the interrupt input pin)

A button press less than about one second does not trigger the interrupt.
The push button is a substitute for input from the reed relay. I don't have a reed relay to use to test it.
You can adjust the debounce time if it is too long for you.

#define SWITCH_1 7
#define in_terrupt 2
#define signal 4
#define ledpin 13
#define  debounce_time 250
unsigned long  start_time;
unsigned long elapsed_time ;
int val;
volatile boolean interrupt_occured = false;

void setup() 
{
pinMode(SWITCH_1,INPUT);
pinMode(in_terrupt,INPUT);
pinMode(signal,OUTPUT);	
Serial.begin(19200);
attachInterrupt(in_terrupt, switchPressed, FALLING);	
}

void loop() 
{
  

  val= digitalRead(SWITCH_1);
  if (val == LOW) 
    {
       start_time = millis();
           do  
             {
                elapsed_time = millis();
                val= digitalRead(SWITCH_1);
             } while (elapsed_time - start_time < debounce_time ) ;
             
               if (val == LOW) 
                 { 
                 
                    digitalWrite(ledpin, HIGH);
                    delay(500);
                    digitalWrite(ledpin, LOW);
                    delay(500);
                    digitalWrite(ledpin, HIGH);
                    delay(500);
                    digitalWrite(signal, LOW);
                    delay(500);
                    Serial.println("Switch press");
                    Serial.print("start_time: ");
                    Serial.println(start_time);
                    Serial.print("elapsed_time: ");
                    Serial.println(elapsed_time);
                    unsigned long difference = elapsed_time - start_time;
                    Serial.print("difference: ");
                    Serial.println(difference);
                    Serial.println();
                    interrupt_occured = true;
                    
                 }
                 
     }
  
      if (interrupt_occured)
	{	
		Serial.println("Switch pressed");
                Serial.println();
	}
      interrupt_occured = false;
     
}

void switchPressed()
{  
    interrupt_occured = true;
}

Paul__B:
All very well and good for "an academic/ learning exercise", but the bigger question here, is why you would be using an interrupt in the first place, for a totally inappropriate purpose - monitoring a pushbutton?

In my case this approach is very appropriate. I am monitoring two end switches of a high powered camera slider with expensive professional equipment on it. When driving the stepper, each time i pass through the loop, i am calling a function called "stepper.run()" to perform one single step of the motor. If i monitor the end switches with two digitalRead() function i have a significant slowdown of the stepper pulses, because stepper.run() cant be called as fast. Implementing the end switches with interrupts saves 2x polling the switches for every step, which is quite significant.

Yes, you are absolutely right. Clearing the interrupt flag is exactly what i am looking for. I think in an Uno, it is done with cli();, as you described in your very good tutorial. Unfortunately i didnt find a similar solution for the SAM3X processor yet...

TomGeorge:
Hi,

Have you got this set up on protoboard?

Please can you post a picture of your project?

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png or pdf?

Can you describe your application, what is it accomplishing?

Thanks.... Tom... :slight_smile:

Hi Tom,

thanks for the offer to give some guidance. I am willing to give you some detailed material. I will make some pictures. What is the quickest circuit drawing program you would recommend to me? I will draw the circuit then.

MaxBlitz:
Yes, you are absolutely right. Clearing the interrupt flag is exactly what i am looking for. I think in an Uno, it is done with cli();, as you described in your very good tutorial. Unfortunately i didnt find a similar solution for the SAM3X processor yet...

No that is not at all what I am talking about. The processor remembers a RISING/FALLING/LOW event on a pin, which is configured for such interrupts, even if interrupts are not currently enabled. Thus you need to clear that "event" flag (not just clear interrupts).

On this page I have an example: Gammon Forum : Electronics : Microprocessors : Interrupts

EIFR = bit (INTF0);  // clear flag for interrupt 0

You notice that is not doing a cli() call.

I'm not an expert on the Due processor but a quick skim of the datasheet seems to indicate this is similar to what happens on the Atmega328:

12.20.9.1
Hardware and software control of interrupts
The Cortex-M3 latches all interrupts. A peripheral interrupt becomes pending for one of the fol-
lowing reasons:
• the NVIC detects that the interrupt signal is HIGH and the interrupt is not active
• the NVIC detects a rising edge on the interrupt signal
• software writes to the corresponding interrupt set-pending register bit, see “Interrupt Set-
pending Registers” on page 161, or to the STIR to make an SGI pending, see “Software
Trigger Interrupt Register” on page 166.
A pending interrupt remains pending until one of the following:
The processor enters the ISR for the interrupt. This changes the state of the interrupt from pend-
ing to active. Then:
– For a level-sensitive interrupt, when the processor returns from the ISR, the NVIC
samples the interrupt signal. If the signal is asserted, the state of the interrupt
changes to pending, which might cause the processor to immediately re-enter the
ISR. Otherwise, the state of the interrupt changes to inactive.
– If the interrupt signal is not pulsed while the processor is in the ISR, when the
processor returns from the ISR the state of the interrupt changes to inactive.
• Software writes to the corresponding interrupt clear-pending register bit.

(My emphasis of relevant sentence).

This is possibly the appropriate register:

12.20.5
Interrupt Clear-pending Registers
The ICPR0-ICPR1 register removes the pending state from interrupts, and show which inter-
rupts are pending.

This comment may be too late to be relevant, but if you check the ATmel full document on SAM3X8E ( Due)
you will find some interesting "news".
Internal pull-up resistor ( on all I/O pins) in range of 100 kOhms, debouncing (!) etc.

Essentially it does some of the stuff suggested in this discussion internally.

I would be surprised if some kinda of ESD circuit / protection is NOT implement also, but I have not looked for it.
Generally, and I mean generally, once the circuit is terminated ( connected to pull-up ) ESD should not be an issue. I would not discard possibility of some other (power) problem.