Nano 3 external Interrupts

Hey guys. I'm new here so sorry if I ask a dumb question.
I need to connect 3 external interrupts from the Nano. I'm going to use D2, D3 and I would like to know what other pin I can use, as the Atmega328P all pins accept interrupts.

What are the interrupt sources? If they're polled, you can use one pin for multiple sources. Except for pin change interrupts, there are only two pins on the Nano that can be used with attachInterrupt().

Also - often people assume that they need interrupts, when in fact they don't.

Thank you "arrg" for your reply.
The 3 external pulses will never occur at the same time, so their priority can be the same. The falling edges of each pulse will be monitored. I'm opting for interruptions because I can't miss water liter count pulses under any circumstances.

How fast are the pulses? Interrupts are usually required where an instant response is required. That is different than a situation where you have relatively slow pulses and simply can't miss any. You can poll in loop() reliably as long as you don't put any delaying code in loop(), at kilohertz frequencies. Worst case, you can employ a timer to guarantee polling the pulses on a regular basis. That is how IR and 433MHz OOK drivers for the Arduino work. Nothing is ever missed there, and the frequency is much much higher than a water meter pulse train.

Either method would allow you to use as many pins as you like for pulse detection.

By the way, simultaneous transitions on two different interrupt pins will be recognized, regardless of the fact that there is no priority interrupt system on the processor. They just get handled back to back. So you are worrying about that for no reason.

1 Like

The frequency is actually quite low. On the order of 25 to 50Hz.
In this case you don't need the interruption, right? There are some pulse capture functions in Arduino, right? should I use them?

Your problem with using the existing pulse functions, is that they block while they input a pulse, hence can not receive pulses on different pins simultaneously. So you will need to make custom code. millis() or micros() can be used to time things.

Are you doing anything else in your sketch that halts processing in loop() for more than a few milliseconds?

Well, I'm looking to not use anything in Loop() that might block processing. There is only serial communication on 9600 with transmission of a few bytes. Based on what you're telling me, I'm going to try not to block Loop() for anything and use digitalRead to read port D2, D3 and D5 normally, without interruption. I'm going to try this out and see if pulse count losses occur. I believe they will not occur as the frequencies are too low. I take opportunity to thank you for your help. It was valuable a lot. Thanks.

It sounds like you're on the right track. Don't forget, you will need to do some minimal signal processing on the inputs (basically, edge detection and debounce). You can look at switch input examples to get some ideas about that.

Thanks for the tip! As the sensors are hall effect and not reed swtich, I believe there will be no need to debounce. As for edge detection, yes I will need these features. I need to research how to do this. When it was the case of interruption it was clear to me how to do this, but now I don't know how to proceed.

I believe the D2 and D3 external interrupts will trigger on the falling edge, but all the others, including D5, are only pin change interrupts. So D5 will still work, but will need to be coded differently unless there's a library that does all that for you.

Thanks ShermanP. Yes I believe it is possible for me to use interrupts in D5, as the Atmega328P allows interrupts on practically all pins, however I don't have experience to deal with this, especially if the compiler doesn't have a library for this. Because of that, I'll try to work without interruptions, keeping my Loop() without delays, and let's see what happens...

There are several libraries for pin change interrupts available through the library manager.

The one by Nico Hood PinChangeInterrupt.h is very easy because it uses the same syntax as the external interrupts.

"GreyGnome"'s Enable Interrupt is also frequently used.

Thanks Cattledog. Like I said I'm new on the block. I will be verifying your indications.

The switch examples that come with the IDE are examples of edge detection, state change detection in general...

Thanks arrg. I have enough material now to work, learn and research. I really appreciate the collaboration of all of you, and I must confess that I was impressed with the attention given by everyone. Thank you so much. I will inform you of the results soon.

Hello guys! I'm here again to let you know that the solutions discussed here worked. I got three interrupts that work perfectly well! Thank you all for your help.
#include <PinChangeInterrupt.h>
#define PCINT_PIN A5
#define PCINT_MODE FALLING
#define PCINT_FUNCTION H3
//
attachInterrupt(digitalPinToInterrupt(h1), H1, FALLING);
attachInterrupt(digitalPinToInterrupt(h2), H2, FALLING);
attachPCINT(digitalPinToPCINT(PCINT_PIN), H3, FALLING);
//
void H1 (){
digitalWrite (LEDVD, HIGH);
//------------------------------------------------------------------------------------------
For now I have another question to resolve:
I'm using "SoftwareSerial" library and I get 4 lines of data, however I can see the first line. The remaining lines are lost. Does anyone have any idea how I can receive and print on the PC Serial the 4 complete lines?

1. You can adopt the following option of Fig-1:

int125
Figure-1:

2. Test Sketch

#define L 13
#define INT0 2
#define INT1 3
#define T1 5
bool flag1, flag2, flag3;

void setup()
{
  Serial.begin(9600);
  pinMode(L, OUTPUT);
  pinMode(INT0, INPUT_PULLUP);
  pinMode(INT1, INPUT_PULLUP);
  pinMode(T1, INPUT_PULLUP);
  //-------------------------
  attachInterrupt(digitalPinToInterrupt(2), ISRINT0, FALLING);
  attachInterrupt(digitalPinToInterrupt(3), ISRINT1, FALLING);
  //---TC1 Intialization-------
  TCCR1A = 0x00; //normal mode upcounter
  TCCR1B = 0x00; //TC1 is OFF
  bitSet(TIMSK1, TOIE1);  //local interrupt switch is enabled
  TCNT1 = 0xFFFF;    //preset value
  TCCR1B = 0x06;      //TC1 is ON with falling edge trigger of external pulse at DPin-5
  sei();              //global interrupt switch is enabled
}

void loop()
{
  if (flag1 == true)
  {
    blinkRut(L, 2);
    flag1 = false;
  }
  if (flag2 == true)
  {
    blinkRut(L, 4);
    flag2 = false;
  }
  if (flag3 == true)
  {
    blinkRut(L, 6);
    flag3 = false;
  }
}

void ISRINT0()
{
  flag1 = true;
}

void ISRINT1()
{
  flag2 = true;
}
ISR(TIMER1_OVF_vect)
{
  TCNT1 = 0xFFFF;  //reload preset value
  flag3 = true;
}

void blinkRut(int m, int n)
{
  for (int i = 0;  i < n; i++)
  {
    digitalWrite(m, HIGH);
    delay(1000);
    digitalWrite(m, LOW);
    delay(1000);
  }
}

3. Upload sketch of Step-2.
4. Gently press K1 to inject interrupt signal (INT0 interrupt). Check that L (built-in LED of UNO) has bliked for 2 times.

5. Gently press K2 to inject interrupt signal (INT1 interrupt). Check that L (built-in LED of UNO) has bliked for 4 times.

6. Gently press K3 to inject interrupt signal (TC1 interrupt). Check that L (built-in LED of UNO) has bliked for 6 times.

on Nano there are only 2

Please post your code, or better, an MCVE which demonstrates the issue.
(How to create a Minimal, Reproducible Example - Help Center - Stack Overflow)

What is sending to or receiving from software serial?

CattleDog thanks!
I solved the problem!