Go Down

Topic: Arduino Due fires Interrupt when i get out of my chair or people move in room (Read 7543 times) previous topic - next topic

MaxBlitz

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

Code: [Select]


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!


nickgammon

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).
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

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... :)
Everything runs on smoke, let the smoke out, it stops running....

Paul__B

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?

dlloyd

Quote
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.

raschemmel

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.

Code: [Select]

#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;
}

Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,<br />DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

MaxBlitz

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.


MaxBlitz

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).
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...

MaxBlitz

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... :)
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.

nickgammon

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: http://www.gammon.com.au/interrupts

Code: [Select]

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


You notice that is not doing a cli() call.
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

nickgammon

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:

Quote
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:

Quote
12.20.5
Interrupt Clear-pending Registers
The ICPR0-ICPR1 register removes the pending state from interrupts, and show which inter-
rupts are pending.
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

Vaclav

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.

TomGeorge

Hi.

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

Tom..... :)
Everything runs on smoke, let the smoke out, it stops running....

Paul__B

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?

Go Up