2 attachinterrupts on the same board. Arduino Nano

Hi

I have this code in which the digital pins 2 and 3 goes to a different sensor. With this code I am only able to make the attachinterrupt work on only one pin, the other pin keeps detecting the movement by the sensor but it doesn’t make the attach interrupt. The pin that doesn’t work properly keeps adding numbers instead of reseting the account.

I’ve been working on this code for making the attachinterrput works on the pins 2 and 3, reseting the acount in each one. Unfortounately I still don’t find the answer. Probably with a boolean? Here’s the code and 3 images of de serial monitor:

pruebaDfMWffforo.ino (3.34 KB)

I see two problems

Don’t have a delay() in the ISR. An ISR should complete in a few microseconds.

void stateChange() { //Interrupt service function
  delay(1);
  (number = number + 1);
  if (number <= 1) {
    number == 0;//Interrupted once, the number +1
  }
}

You are using 2-byte ints (called number and number2) in your ISR. If you want to read the value of that in another part of your program you should suspend interrupts and copy the data to a working variable to avoid the situation in which an interrupt occurs while you are reading the variable. Same goes for writing to the variable. If you can reduce the size of the variable to a byte or a char then this problem goes away.

To copy a multi-byte variable you can use code like this

noInterrupts()
   copyOfNumber = number;
interrupts();

And a third thing, variables that are used in an ISR should be declared volatile so the compiler understands that they may get values it is not expecting. Like this

volatile int number = 0;

And a fourth thing … in the ISR code I have quoted above the value of number cannot be made less than 0 so there is no need to test for it. If it is being made less than zero outside the ISR then that is the place to deal with it.

…R

Your code:

#include <MsTimer2.h>           //Timer interrupt function library
int pbIn = 0;                    // Define interrupt 0 that is digital pin 2
int pbIn2 = 1;
int ledOut = 13;
int ledOut2 = 12; // Define the indicator LED pin digital pin 13
int number = 0;                   //Interrupt times
int number2 = 0;
volatile int state = LOW;         // Defines the indicator LED state, the default is not bright
volatile int state2 = LOW;


void stateChange2() { //Interrupt service function

  number2++;  //Interrupted once, the number +1
}


void Handle()   //Timer service function
{
  if (number > 1) //If in the set of the interrupt time the number more than 1 times, then means have detect moving objects,This value can be adjusted according to the actual situation, which is equivalent to adjust the threshold of detection speed of moving objects.
  {
    delay (1000);
    state = HIGH;
    digitalWrite(ledOut, state);    //light led
    number = 0; //Cleare the number, so that it does not affect the next trigger
  }
  else
    number = 0; //If in the setting of the interrupt time, the number of the interrupt is not reached the threshold value, it is not detected the moving objects, Cleare the number.
}

void Handle2()   //Timer service function
{
  if (number2 > 1) //If in the set of the interrupt time the number more than 1 times, then means have detect moving objects,This value can be adjusted according to the actual situation, which is equivalent to adjust the threshold of detection speed of moving objects.
  {
    state2 = HIGH;
    digitalWrite(ledOut2, state2);    //light led
    number2 = 0; //Cleare the number, so that it does not affect the next trigger
  }
  else
    number2 = 0; //If in the setting of the interrupt time, the number of the interrupt is not reached the threshold value, it is not detected the moving objects, Cleare the number.
}

void stateChange() { //Interrupt service function
  delay(1);
  (number = number + 1);
  if (number <= 1) {
    number == 0;//Interrupted once, the number +1
  }
}

void setup()
{
  Serial.begin(9600);
  pinMode(ledOut, OUTPUT);//
  pinMode(ledOut2, OUTPUT);
  attachInterrupt(pbIn, stateChange, FALLING); // Set the interrupt function, interrupt pin is digital pin D2, interrupt service function is stateChange (), when the D2 power change from high to low , the trigger interrupt.
  attachInterrupt(pbIn2, stateChange2, FALLING);
  MsTimer2::set(1000, Handle); // Set the timer interrupt function, running once Handle() function per 1000ms
  MsTimer2::set(1000, Handle2);
  MsTimer2::start();//Start timer interrupt function
}

void loop()
{
  Serial.print("sensoruno");
  Serial.println(number);
  Serial.print("sensordos");
  Serial.println(number2);// Printing the number of times of interruption, which is convenient for debugging.
  Serial.println("-");
  delay(100);
  if (state == HIGH) //When a moving object is detected, the ledout is automatically closed after the light 2S, the next trigger can be carried out, and No need to reset. Convenient debugging.
  {
    delay(100);
    state = LOW;
    digitalWrite(ledOut, state);

    if (state2 == HIGH) //When a moving object is detected, the ledout is automatically closed after the light 2S, the next trigger can be carried out, and No need to reset. Convenient debugging.
    {
      delay(100);
      state2 = LOW;
      digitalWrite(ledOut2, state2);//turn off led
    }
  }
}

All variables used inside an ISR and the main code have to be declared volatile.
All multi byte variable have to be accessed in an atomic block (with disabled interrupts) from the main code.

delay does not work inside an ISR, millis() needs interrupts to tick.

I would use digitalPinToInterrupt instead of using the raw interrupt numbers.

Have a look at Gammon Forum : Electronics : Microprocessors : Interrupts.

The variable names number and number2 are abysmal IMHO.

Hi

The problem wasn't there, anyway I do change to volatile ints and consider all the things posted here.

The problem was heree:

MsTimer2::set(1000, Handle2);
MsTimer2::set(1000, Handle);

I put the Handle2 function inside the Handle function.

Thank you for taking the time for reading my code