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

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.

Hi.

Try Express PCB, its a simple package, free and no added extra internet apps that are a pain to get rid of.

Tom..... :slight_smile:

MaxBlitz:
Implementing the end switches with interrupts saves 2x polling the switches for every step, which is quite significant.

Does it?

So how does this stepper loop know how to stop when the interrupt occurs?

How "quite significant" to your loop is two microseconds?