Interrupts & Internal Pull Resistors

Hello everyone

I currently have this weird issue in my program, and I just can’t figure it out. I am using INT0 and INT1 on my Arduino. I have the the internal pull-up resistors turned on at INT0 & INT1. I making use of a push button (connected to INT0 - Pin 2) and smoke sensor (connected to INT1 - Pin 3). The push button has a pull down resistor connected to it. I currently have my interrupt to be triggered when it detects a rising edge (so going from low to high).

Now here is the weird part, when I disconnect the wire at the push button end, the interrupt is triggered (but once in a while it will just switch back, as if the interrupt wasn’t triggered), but however when I disconnect the wire at the Arduino header, the interrupt is not triggered. I have tried connecting an external pull up resistor as well but no luck.

What I am trying to achieve is having two push buttons connected, one has a greater priority than the other one, I can get it to successfully override the other push button. However when the push button that is connected to INT0 is disconnected, I want it to change the state of pin 8 and keep it that way.

#include <util/delay.h> 

volatile unsigned char LED [] = {8,9};          
volatile unsigned char BUTTON [] = {0,5};      // Button[0] interrupt 0 is located on Pin 2
                                                              // Pin 5 Push Button 2                                                                               
unsigned char Smoke_Sensor = 1;                 // Interrupt 1 located on Pin 3, which is used for Smoke Sensor (MQ-2)      
boolean Exit_Switch_Operated = false;           // Set Emergency Switch as FALSE (Not Pressed)

// ===========================================================================================
// Setup Routine - Executes only once when reset it pressed/arduino powered for first time
// ===========================================================================================

void setup(){
  for (int i = 0; i < 2; i++){
    pinMode(BUTTON[i], INPUT);
    digitalWrite(BUTTON[i], INPUT_PULLUP);    // Turn on internal Pull-Up Resistor
    pinMode(LED[i], OUTPUT);           
  }
  
  pinMode(Smoke_Sensor, INPUT);
  pinMode(Smoke_Sensor, HIGH);
  
  attachInterrupt(BUTTON[0], override_delay, RISING);          // RISING to trigger when the pin goes from low to high
  attachInterrupt(Smoke_Sensor, smoke_override_delay, RISING);    // LOW to trigger the interrupt whenever the pin is low
}

// ===========================================================================================
// Main Program - Repeats over and over again
// ===========================================================================================

void loop(){
  
  Exit_Switch_Operated = digitalRead(BUTTON[1]);
  delay_ms(50);      // Used for debouncing of switch
  
  if (Exit_Switch_Operated == LOW){
      digitalWrite(LED[0], LOW);
      digitalWrite(LED[1], LOW);
   }
   else{
      delay_ms(3000);
      digitalWrite(LED[0], HIGH);
      delay_ms(2000);
      led_flash();
   }  
    
}

// ===========================================================================================
// Interrupt Code
// ===========================================================================================

// Execute this code when external interrupt 0 is activated
void override_delay(){
  digitalWrite(LED[0],HIGH);
  led_flash();
  delay_ms(1000);
}

// Execute this code when external interrupt 1 is activated
void smoke_override_delay(){
  digitalWrite(LED[0],HIGH);
  digitalWrite(LED[1], HIGH);
  delay_ms(1000);
}

// ===========================================================================================
// LED Flash Function
// ===========================================================================================

void led_flash()
{
  digitalWrite(LED[1], HIGH);
  delay_ms(1000);
  digitalWrite(LED[1], LOW);
  delay_ms(1000);
}

// ===========================================================================================
// Delay Function
// ===========================================================================================

void delay_ms(unsigned int time) 
{ 
  while (time--) 
    _delay_ms(1); 
}

Any suggestions would be greatly appreciated.

Thank you

Hi, maybe I'm not reading your post right, but it sounds like you are saying you have the internal pullup and an external pulldown on the same pin?

Can you post a scematic please. Just a hand drawn one of the relevant parts.

Paul

Hello Paul

I currently have my push button connected as the sketch below:

http://www.arduino.cc/en/Tutorial/button

I did have the internal pull and an external pulldown on the same pin, I have changed that since, I now only have the pulldown resistor as shown in the link above. When the wire from the board to the push button disconnects (whether I pull it out from push button or header from Arduino), I want the program ALWAYS to trigger the interrupt, but that doesn't always happen. Do I maybe have to change my push button configuration for it to work as intended?

Hello,

what is the pull-down resistor value ? you activate the internal pull-up resistor on pin2 in your setup. The pull-up and pull-down resistor make a voltage divider on pin2 . The voltage value on pin2 when the button is not pressed depends on the value of the pull-down resistor and the internal pull-up resistor, which is, afaik, 20k. If the pull-down resistor value is too high, the state of pin2 might never be "LOW"

skandebaba: I did have the internal pull and an external pulldown on the same pin, I have changed that since, I now only have the pulldown resistor as shown in the link above.

Hi,

For the reason alnath explains above, don't use internal pullup and an external pulldown at the same time. But you have disabled the internal pullup now.

skandebaba: When the wire from the board to the push button disconnects (whether I pull it out from push button or header from Arduino), I want the program ALWAYS to trigger the interrupt, but that doesn't always happen. Do I maybe have to change my push button configuration for it to work as intended?

That won't work. When you remove the link wire, at either end, the Arduino input is left "floating" and can't be relied on to read either high or low, so can't be used to make the predictable interrupt you want.

This would work: go back to the internal pullup so that the input can't "float". Remove the external pulldown resistor. Replace the pushbutton (which is probably a push-to-make type) with a push-to-break button. Connect the new button from the link wire to ground. Now, the input will read low normally and will go to high if you either press the button or disconnect the link wire.

If you absolutely want this to work with your current push-to-make button, there are ways, for example using a transistor, but a push-to-break button would be simpler.

Paul

Hello Paul

I have now ordered some push-to-break buttons, I will keep you updated on how I go.

Another question, where my LED[0] is, so LED on pin 8, I have connected a relay (I do have a transistor driving it, and a flywheel diode connected it). When I have nothing connected to the relay (so its just changing states), my program works fine, but the moment when I do connect something to the relay to drive, my interrupts get triggered, even though they aren't meant to. Do you maybe know why this would be happening?

where does the power for the “something” you connect to the relay come from ? Is it the same power source than the arduino ?
does it need a lot of current ? what kind of load is it (capacitive, inductive, resistive) ?

You can use the make type normally open push button switch with internal pull-up resistor. You just connect it to the ground and fire on LOW instead of HIGH. You attachInterrupt(INT0, override_delay, FALLING) instead of RISING, and it should work fine.

Except that you should probably not use delay() in your interrupt service routine. Maybe use time stamps and differences instead.

I have an electromagnetic lock connected to my relay (so should be an inductive load), it is connected to its own power supply as it is rated at 9V 400mA. I do however use the Arduino to supply the transistor that switches the relay, is it maybe possible that this causes the interrupts to trigger? Like I said, when I don’t have my load connected to the relay, it works fine, but the moment I connect my load, it triggers the interrupts when its not meant to.

Thanks TanHadron, I will try that now and I see if it works.

Sounds like electromagnetic interference caused by the relay contacts opening and closing with that large-ish current being switched and it being an inductive load. You could try a 220nF Metalised polyester cap across the relay switch terminals.

Paul

Hello Paul

I have now connected a 330nF capacitor across the common and N/O connection of the relay, and this seems to have fixed my problem. Thank you for the advice.

I am still waiting for my push-to-break push buttons, but once they arrive I will let you know how I go.

Thank you to alnath and TanHadron for your input as well :)

skandebaba: I have now connected a 330nF capacitor across the common and N/O connection of the relay, and this seems to have fixed my problem. Thank you for the advice.

I recommend you connect a low-value resistor in series with the capacitor, otherwise there will be high peak currents when the relay closes, which may lead to premature failure of the capacitor. 10 ohms should be about right.

An alternative solution would have been to connect a flyback diode across the door solenoid.