Arduino Interrupt pins problem

Dear All,

it seems a problem with my interrupt pin 2. I want to calculate the RPM of a motor. The simple code is quite well through int pin 3, but when I change it to int pin 2 the result is not correct. What should be the problem?
I check it on two arduino uno boards, same problem.

thanks

int ir_sensor = 2;
unsigned int ir_rpm = 0;
unsigned int numOfRotations = 0;
int pulsesPerTurn = 1;
unsigned long lastTime = 0;

void counter(){
numOfRotations++;
}

void setup() {

Serial.begin(115200);

pinMode(ir_sensor,INPUT);

attachInterrupt(digitalPinToInterrupt(ir_sensor), counter, FALLING);

}

void loop() {
stop_ir_Interrupt();

Serial.print(" "); Serial.println(ir_rpm);

}

void stop_ir_Interrupt(){

if(millis() - lastTime >= 1000){
detachInterrupt(digitalPinToInterrupt(ir_sensor));
ir_rpm = (numOfRotations * 60) / pulsesPerTurn;
lastTime = millis();
numOfRotations = 0;
attachInterrupt(digitalPinToInterrupt(ir_sensor), counter, FALLING);
}

}

you should declare your numOfRotations as ' volatile unsigned int ' as it appears in both main thread and the ISR routine

you can google what 'volatile ' means

KASSIMSAMJI:
you should declare your numOfRotations as ' volatile unsigned int ' as it appears in both main thread and the ISR routine

you can google what 'volatile ' means

well it is recommended to use variables as volatile inside interrupts. but It doesn't influence on your result generally.
I tried all of them and got same results.

the problem is, the result from pin2 and pin 3 are not same with same conditions!

ebarash:
well it is recommended to use variables as volatile inside interrupts. but It doesn't influence on your result generally.
I tried all of them and got same results.

the problem is, the result from pin2 and pin 3 are not same with same conditions!

try INPUT_PULLUP in pinMode

CHANGE over FALLING in attachInterrupt()

KASSIMSAMJI:
try INPUT_PULLUP in pinMode

CHANGE over FALLING in attachInterrupt()

I tried all of them. I have different results!

I use the program in this link to detect the speed of a small motor. Note how simple the ISR code is and how there is no need for detachInterrupt()

...R

Robin2:
I use the program in this link to detect the speed of a small motor. Note how simple the ISR code is and how there is no need for detachInterrupt()

...R

Thanks for your answare. The problem is with interrupt 0(pin2). I don't know why, but it does not give me the right answare. interrupt 1 (pin 3) is good and I don't have any problem with my code.

ebarash:
Thanks for your answare. The problem is with interrupt 0(pin2). I don't know why, but it does not give me the right answare. interrupt 1 (pin 3) is good and I don't have any problem with my code.

Is that true with my program ?

...R

Robin2:
Is that true with my program ?

...R

I used your code. It is working well on both of pins 2,3. Also my simple code is working well when I use a delay() (at leats with 100ms) in my void loop().

The problem comes when I don't use any delay in void loop. I am wondering about this result. What should be the problem?

The number of pulses per second should be counted inside interrupt function and finally the value will be printed in main loop! why this miskate happens without delay?

ebarash:
I used your code. It is working well on both of pins 2,3.

So why not use it?

...R

Robin2:
So why not use it?

...R

The reason is that I have some other datas which should be save in an array together with rpm and they are comming in several milliseconds, so I cannot wait one second to save them.Your code has also one second delay to write pulses and without that is not working.

ebarash:
Your code has also one second delay to write pulses and without that is not working.

That is not an important part of my program. I just did it like that so the info appears at a rate that makes sense for the human viewing the screen. There is no need to display the data and you can update things every time there is a pulse if you wish.

I don't know what you mean by "without that is not working"

...R

Robin2:
I don't know what you mean by "without that is not working"

...R

this is oart of your code.
I mean what if you remove the one second waiting time to show data?

void loop() {
getIsrData();
// (millis() - prevDisplayMillis >= 1000) {
// prevDisplayMillis += 1000;
showData();
// }
}

pulses per second will not be true if you unable those lines!

ebarash:
pulses per second will not be true if you unable those lines!

You don't need a 1 second interval to know the pulse rate. All you need to know is the interval between two pulses (or the interval between a larger number if you want an average.

And even if you do want to show the data once per second the rest of your program does not have to be limited to once per second.

Rather than pick small holes in specific pieces of code that were just prepared as a typical example why not tell us exactly what you want to achieve?

...R

Robin2:
You don't need a 1 second interval to know the pulse rate. All you need to know is the interval between two pulses (or the interval between a larger number if you want an average.

Rather than pick small holes in specific pieces of code that were just prepared as a typical example why not tell us exactly what you want to achieve?

...R

Thanks for your advices but the problem is I am very curious about pin 2 which is not stable as pin 3. It seems there is a problem with timing. With 1 second intervals to show data it works well( or with baud rate of lower than 9600), but without that delay only pin 3 gives me the right results. Pin 2 is not stable and gives the higher rpm. even with your nice code it will happens.

At all, I don't have any problem with my code because I am using pin3.

Just to know if someone had same problem or knows the reason. Because it happens even with a very simple code.

ebarash:
Pin 2 is not stable and gives the higher rpm. even with your nice code it will happens.

When you said (in Reply #8) "I used your code. It is working well on both of pins 2,3" I had assumed there were no problems.

Please post the version of my code that is giving rise to the incorrect readings when using pin2 and working properly when using pin3.

Also please post some samples of the output in each case.

...R

Robin2:
Also please post some samples of the output in each case.

...R

well, this is your code and I just added marked line with #### to show the number of pulses in 1 second

const byte fwdPin = 9;
const byte revPin = 10;
const byte potPin = A1;

int potVal;
int pwmVal;

unsigned long revMicros;
unsigned long prevRevMicros;
unsigned long revDuration;
unsigned long revCount;

unsigned long prevDisplayMillis;
unsigned long displayInterval = 1000;

// variables for the ISR
volatile unsigned long isrMicros;
volatile unsigned long isrCount;
volatile bool newIsrMicros = false;

void setup() {
Serial.begin(115200);
Serial.println("SimpleISRdemo.ino");
pinMode (fwdPin, OUTPUT);
pinMode (revPin, OUTPUT);

isrCount = 0;
attachInterrupt(1, revDetectorISR, RISING);
}

//==========

void loop() {
getIsrData();
if (millis() - prevDisplayMillis >= displayInterval) {
prevDisplayMillis += displayInterval;
showData();
isrCount=0; //####
readPot();
updateMotorSpeed();
}
}

//===========

void readPot() {
potVal = analogRead(potPin);
}

//===========

void updateMotorSpeed() {
pwmVal = potVal >> 2;

digitalWrite(revPin,LOW);
analogWrite(fwdPin, pwmVal);
}

//===========

void getIsrData() {
if (newIsrMicros == true) {
prevRevMicros = revMicros; // save the previous value
noInterrupts();
revMicros = isrMicros;
revCount = isrCount;
newIsrMicros = false;
interrupts();
revDuration = revMicros - prevRevMicros;
}
}

//===========

void showData() {
Serial.println();
Serial.println("===============");
Serial.print("PWM Val "); Serial.println(pwmVal);
Serial.print(" Rev Duration ");
Serial.print(revDuration);
Serial.print(" Rev Count ");
Serial.print(revCount);
Serial.println();
}

//===========

void revDetectorISR() {
isrMicros = micros();
isrCount ++;
newIsrMicros = true;

}


and this the result with both pins 2 and 3

Rev Duration 44644 Rev Count 22



Now I changed it just a little:

changes marked with //####

const byte fwdPin = 9;
const byte revPin = 10;
const byte potPin = A1;

int potVal;
int pwmVal;

unsigned long revMicros;
unsigned long prevRevMicros;
unsigned long revDuration;
unsigned long revCount;
unsigned long lastMillis=0; //####

unsigned long prevDisplayMillis;
unsigned long displayInterval = 1000;

// variables for the ISR
volatile unsigned long isrMicros;
volatile unsigned long isrCount;
volatile bool newIsrMicros = false;

void setup() {
Serial.begin(115200);
Serial.println("SimpleISRdemo.ino");
pinMode (fwdPin, OUTPUT);
pinMode (revPin, OUTPUT);

isrCount = 0;
attachInterrupt(1, revDetectorISR, RISING);
}

//==========

void loop() {
getIsrData();
// if (millis() - prevDisplayMillis >= displayInterval) { //####
prevDisplayMillis += displayInterval;
showData();
readPot();
updateMotorSpeed();
// } //####
}

//===========

void readPot() {
potVal = analogRead(potPin);
}

//===========

void updateMotorSpeed() {
pwmVal = potVal >> 2;

digitalWrite(revPin,LOW);
analogWrite(fwdPin, pwmVal);
}

//===========

void getIsrData() {
if (newIsrMicros == true) {
prevRevMicros = revMicros; // save the previous value
noInterrupts();
revMicros = isrMicros;
if(millis() - lastMillis>=1000){ //####
revCount = isrCount; //####
lastMillis += 1000; //####
isrCount=0; //####
} //####
newIsrMicros = false;
interrupts();
revDuration = revMicros - prevRevMicros;
}
}

//===========

void showData() {
Serial.println();
Serial.println("===============");
Serial.print("PWM Val "); Serial.println(pwmVal);
Serial.print(" Rev Duration ");
Serial.print(revDuration);
Serial.print(" Rev Count ");
Serial.print(revCount);
Serial.println();
}

//===========

void revDetectorISR() {
isrMicros = micros();
isrCount ++;
newIsrMicros = true;

}

this is the result with arduino pin 3

Rev Duration 44660 Rev Count 22

but for pin 2

Rev Duration 44684 Rev Count 37



You can see by same code I have defferent results.

But if I apply delay(1000) in void loop, or unmark this line

// if (millis() - prevDisplayMillis >= displayInterval) { //####

the result will be same again.

To make it easy for people to help you please modify your post and use the code button </> so your code looks like this and is easy to copy to a text editor. See How to use the Forum

Your code is too long for me to study quickly without copying to my text editor. The text editor shows line numbers, identifies matching brackets and allows me to search for things like all instances of a particular variable or function.

Also please use the AutoFormat tool to indent your code for easier reading.

...R

To make it easy for people to help you please modify your post and use the code button </>

Sorry if I wrote like that, I am new.

this is your code and I just added marked line with #### to show the number of pulses in 1 second

and this the result with both pins 2 and 3

Rev Duration 44644 Rev Count 22

const byte fwdPin = 9;
const byte revPin = 10;
const byte potPin = A1;

int potVal;
int pwmVal;

unsigned long revMicros;
unsigned long prevRevMicros;
unsigned long revDuration;
unsigned long revCount;


unsigned long prevDisplayMillis;
unsigned long  displayInterval = 1000;

    // variables for the ISR
volatile unsigned long isrMicros;
volatile unsigned long isrCount;
volatile bool newIsrMicros = false;



void setup() {
    Serial.begin(115200);
    Serial.println("SimpleISRdemo.ino");
    pinMode (fwdPin, OUTPUT);
    pinMode (revPin, OUTPUT);

    isrCount = 0;
    attachInterrupt(1, revDetectorISR, RISING);
}

//==========

void loop() {
    getIsrData();
    if (millis() - prevDisplayMillis >= displayInterval) {
        prevDisplayMillis += displayInterval;
        showData();
        isrCount=0;                                       //####  
        readPot();
        updateMotorSpeed();
    }
}

//===========

 void readPot() {
    potVal = analogRead(potPin);
}

//===========

void updateMotorSpeed() {
    pwmVal = potVal >> 2;

    digitalWrite(revPin,LOW);
    analogWrite(fwdPin, pwmVal);
 }

//===========

void getIsrData() {
    if (newIsrMicros == true) {
        prevRevMicros = revMicros; // save the previous value
        noInterrupts();
            revMicros = isrMicros;
            revCount = isrCount;
            newIsrMicros = false;
        interrupts();
        revDuration = revMicros - prevRevMicros;
    }
}

//===========

void showData() {
    Serial.println();
    Serial.println("===============");
    Serial.print("PWM Val "); Serial.println(pwmVal);
    Serial.print("  Rev Duration ");
    Serial.print(revDuration);
    Serial.print("  Rev Count ");
    Serial.print(revCount);
    Serial.println();
}

//===========

void revDetectorISR() {
    isrMicros = micros();
    isrCount ++;
    newIsrMicros = true;

}

and this is with a little change:

changes marked with //####

this is the result with arduino pin 3

Rev Duration 44660 Rev Count 22

but for pin 2

Rev Duration 44684 Rev Count 37

You can see by same code I have defferent results.

But if I apply delay(1000) in void loop, or unmark this line

// if (millis() - prevDisplayMillis >= displayInterval) { //####

the result will be same again.

const byte fwdPin = 9;
const byte revPin = 10;
const byte potPin = A1;

int potVal;
int pwmVal;

unsigned long revMicros;
unsigned long prevRevMicros;
unsigned long revDuration;
unsigned long revCount;
unsigned long lastMillis=0;                          //####

unsigned long prevDisplayMillis;
unsigned long  displayInterval = 1000;

    // variables for the ISR
volatile unsigned long isrMicros;
volatile unsigned long isrCount;
volatile bool newIsrMicros = false;



void setup() {
    Serial.begin(115200);
    Serial.println("SimpleISRdemo.ino");
    pinMode (fwdPin, OUTPUT);
    pinMode (revPin, OUTPUT);

    isrCount = 0;
    attachInterrupt(1, revDetectorISR, RISING);
}

//==========

void loop() {
    getIsrData();
 //   if (millis() - prevDisplayMillis >= displayInterval) {  //####
        prevDisplayMillis += displayInterval;
        showData();
        readPot();
        updateMotorSpeed();
  //  }                                                                       //####
}

//===========

 void readPot() {
    potVal = analogRead(potPin);
}

//===========

void updateMotorSpeed() {
    pwmVal = potVal >> 2;

    digitalWrite(revPin,LOW);
    analogWrite(fwdPin, pwmVal);
 }

//===========

void getIsrData() {
    if (newIsrMicros == true) {
        prevRevMicros = revMicros; // save the previous value
        noInterrupts();
            revMicros = isrMicros;
           if(millis() - lastMillis>=1000){     //####
            revCount = isrCount;                //####
            lastMillis += 1000;                   //####
            isrCount=0;                             //####
           }                                             //####
            newIsrMicros = false;
        interrupts();
        revDuration = revMicros - prevRevMicros;
    }
}

//===========

void showData() {
    Serial.println();
    Serial.println("===============");
    Serial.print("PWM Val "); Serial.println(pwmVal);
    Serial.print("  Rev Duration ");
    Serial.print(revDuration);
    Serial.print("  Rev Count ");
    Serial.print(revCount);
    Serial.println();
}

//===========

void revDetectorISR() {
    isrMicros = micros();
    isrCount ++;
    newIsrMicros = true;

}