Interrupts

Hi everyone, I am learning on interrupts and I wrote a simple sketch just for practice. The interrupt it doesn't look to work fine... I am using an Arduino Nano for the experiment. I have set pin 8 to HIGH and pin 2 as the interrupt pin. With a jumper cable, I attach/de-attach pin 8 to pin 2 in order to enable the interrupt and I measure the attachments with a counter.

The problem is that when I attach pin 8 to pin 2 and the interrupt is activated, pin2 reads high for more time than I actually have the jumper cable attached. For example, I attach the jumper cable for 1s and then de-attach but pin 2 is still high for around 4-5 seconds with consequence the counter does not count during this period... I cannot figure out what is going on... It is like something keeps tie pin2 to high...

Any help?

# include <Arduino.h>
# define pinOut 8
# define pinToInterrupt 2 //For Arduino Nano the interrupts pins are 2 and 3

volatile int counter;

void counterFunc(){
counter++;
}

void setup(){
    Serial.begin(9600);

    pinMode(pinOut,OUTPUT);
    pinMode(pinToInterrupt,INPUT);
    PORTB = B00000001; // Set digital pin 8 to high through PORTB register

    attachInterrupt(digitalPinToInterrupt(pinToInterrupt),counterFunc, RISING); //Interrupt occurs when as soon as pin 2 go from LOW to HIGH
}

void loop(){

Serial.print("The counter is: "); Serial.println(counter); 
}

do you have something to pull pin 2 to ground when the jumper is then detached? a pull-down resistor like a 10K ohm resistor would do.

The pins in an open state act as a capacitor holding the last value for a time.

Z

You should initialize the counter value:

volatile int counter = 0;

Hmm It's more convinient to use the internal pull up and interrupt with a ground signal then..

But If I want to measure the pulses of a hall sensor then a pull down resistor is the only solution?

I will try the counter initiallization as well, but this is not the problem..

You are using jumper as a mechanical switch which when breaks makes a good number of bounces; so, you have multiple interrupts though you have broken the jumper only for once. You need to engage de-bouncer using hardware or software.

thehardwareman:
You should initialize the counter value:

volatile int counter = 0;

crt0 already did that.

TheMemberFormerlyKnownAsAWOL:
crt0 already did that.

crt0, in general, initializes every variable that it didn't initialize by the programmer?

Nikosant03:
crt0, in general, initializes every variable that it didn't initialize by the programmer?

No.
Just globals and statics.

Pin 2 and 3 are reserved for INT0 and INT1, these are used for millis and delay loops by the core. If you are not using delays your code will work. You need not jumper your pin 2 to the other pin you mention. I stand to be corrected if I am wrong.

kssoin:
. I stand to be corrected if I am wrong.

INCOMING.

The pins are not "reserved".
They have nothing to do with millis or delays.

You're welcome.

Thank you guys, I suppose that the problem is due to the open-drain configuration. I will test later and I will come with feedback.

kssoin:
Pin 2 and 3 are reserved for INT0 and INT1[...]

TheMemberFormerlyKnownAsAWOL:
The pins are not "reserved".

When alternate functions like 'external hardware interrupts' are selected, then are DPin-2 and DPin-3 not reserved for INT0 and INT1 interrupts respectively?

atmega328pPin.png

atmega328pPin.png

GolamMostafa:
When alternate functions like 'external hardware interrupts' are selected, then are DPin-2 and DPin-3 not reserved for INT0 and INT1 interrupts respectively?

Yes, but those "External" interrupts are not associated with Timer0 and Timer1.

Nikosant03:
Thank you guys, I suppose that the problem is due to the open-drain configuration. I will test later and I will come with feedback.

For Open Drain (or Open Collector) outputs your input pin must provide a pull-up resistor. Try setting pinMode(2, INPUT_PULLUP);, setting your interrupt mode to "FALLING", and use a jumper from 2 to GND to cause an interrupt

johnwasser:
[...] but those "External" interrupts are not associated with Timer0 and Timer1.

Yes! The following diagram reveals that DPin-4(PD4) and DPin-5(PD5) (and not the interrupt pins) are associated with Timer-0 and Timer-1 respectively.
tcy.png

tcy.png

johnwasser:
For Open Drain (or Open Collector) outputs your input pin must provide a pull-up resistor. Try setting pinMode(2, INPUT_PULLUP);, setting your interrupt mode to "FALLING", and use a jumper from 2 to GND to cause an interrupt

Yes, that's what I was intended to do :slight_smile:

Internal pull-up is about 20k - 50k; will it behave as a strong pull-up?

GolamMostafa:
Internal pull-up is about 20k - 50k; will it behave as a strong pull-up?

What is a good value for a pull up resistor, <10K or <4.7K or < 3.3 K ?

kssoin:
What is a good value for a pull up resistor, <10K or <4.7K or < 3.3 K ?

It is depended on your application. For example, for I2C bus you have to be careful.

In order to select the appropriate pull-up resistor, you have to calculate the min and max pull-up resistance. There are two equations for Rmax and Rmin and you must take into consideration the supply voltage Vcc, the capacitance of the line as well as the rise time

You can find an application report from TI as well a good tutorial regarding the pull-up resistor calculation for I2C bus here

A nice source is also here:

https://learn.sparkfun.com/tutorials/pull-up-resistors/all

In general, a low resistor value is called a strong pull-up (more current flows), a high resistor value is called a weak pull-up (less current flows).

The value of the pull-up resistor needs to be chosen to satisfy two conditions:

  1. When the button is pressed, the input pin is pulled low. The value of resistor R1 controls how much current you want to flow from VCC, through the button, and then to ground.

  2. When the button is not pressed, the input pin is pulled high. The value of the pull-up resistor controls the voltage on the input pin

For condition 1, you don't want the resistor's value too low. The lower the resistance, the more power will be used when the button is hit. You generally want a large resistor value (10kΩ), but you don’t want it too large as to conflict with condition 2. A 4MΩ resistor might work as a pull-up, but its resistance is so large (or weak) that it may not do its job 100% of the time.

The general rule for condition 2 is to use a pull-up resistor (R1) that is an order of magnitude (1/10th) less than the input impedance (R2) of the input pin. An input pin on a microcontroller has an impedance that can vary from 100k-1MΩ. For this discussion, impedance is just a fancy way of saying resistance and is represented by R2 in the picture above. So, when the button is not pressed, a very small amount of current flows from VCC through R1 and into the input pin. The pull-up resistor R1 and input pin impedance R2 divides the voltage, and this voltage needs to be high enough for the input pin to read a high state.

For example, if you use a 1MΩ resistor for the pull-up R1 and the input pin's impedance R2 is on the order of 1MΩ (forming a voltage divider), the voltage on the input pin is going to be around half of VCC, and the microcontroller might not register the pin being in a high state. On a 5V system, what does the MCU read on the input pin if the voltage is 2.5V? Is it a high or a low? The MCU doesn’t know and you might read either a high or a low. A resistance of 10k to 100kΩ for R1 should avoid most problems

The way I read the data sheet, an avr input pin has an equiv resistance of 5.5M to 110M ohms (leakage current 0.05 to 1 uA.)
(Tiny85 datasheet...)