use of attachInterrupt instead of pulseln

I have written a code using Pulseln function to calculate duration of pulse and correspondingly attach some value to a variable. But it is not giving me results accurately as my pulses are of 2ms,5ms and 8 ms and the function is giving me result quite larger than these values. So I want to write code using attachInterrupt. So please help me how should i perform the task. the code for pulseln is given below. Thank you…

int pin = 7;
unsigned long duration;
int i=2;
int a[100];
//a[0]=a[1]=2;

void setup()
{
 Serial.begin(9600);
 pinMode(pin, INPUT);
}

void loop()
{
 duration = pulseIn(pin, HIGH);

 Serial.println(duration);

 if(duration>7950 && duration<8050){

   duration = pulseIn(pin, HIGH);
 Serial.println(duration);

 if(duration>7950 && duration<8050){

   //Serial.println("entered the for loop");

   for(i=2;i<100;i++){

     duration = pulseIn(pin, HIGH);

 Serial.println(duration);

 if(duration>1950 && duration<2050)
 {  
a[i]=0;
 }

 if(duration>4950 && duration<5050)
 {  
a[i]=1; 

 }

 if(duration>7950 && duration<8050)
 {  
a[i]=2;    
 
 }
   
  Serial.println(i);
}


 }
 }
}

So I want to write code using attachInterrupt. So please help me how should i perform the task. the code for pulseln is given below. Thank you...

If you understood what pulseIn() does, and what attachInterrupt() does, this should be trivial.

What should trigger the interrupt handler that attachInterrupt() registers?

What, exactly, should the interrupt handler DO?

Please edit your post and put the code inside code tags. Please copy and paste the serial output and post that also, the same way.

what's the timing / pattern of the input on pin 7??

you understand that while you do your

  Serial.println(duration);

your code is not listening for the next HIGH value on pin 7 for a short while. are you missing some cycles in what you are trying to recognize? would be worth saving your durations in different variables or an array and only after you've captured all the pulsein, print the different values at the different stages to help debug.

Also remember that

 pulseIn(pin, HIGH);

will wait until the next full cycle if the pin is already HIGH when you call the function.

J-M-L: you understand that while you do your

  Serial.println(duration);

your code is not listening for the next HIGH value on pin 7 for a short while. are you missing some cycles in what you are trying to recognize?

But very short, as the serial output is buffered. Not the time it takes to actually transmit.

But very short, as the serial output is buffered.

The time will be short IF there is room in the buffer. The time could be significant if the buffer is full.

PaulS: The time will be short IF there is room in the buffer. The time could be significant if the buffer is full.

Actually, this is a fundamental design flaw in the program, if it is possible for the output to be slower than the input. If the pulses are guaranteed to be widely separated, it's not a problem.

But it's hard to guess, since the questions in reply #1 were never answered.

what's the timing / pattern of the input on pin 7??

void loop() {
  digitalWrite(5,HIGH);
  delay(8);
  digitalWrite(5,LOW);
  delay(2);
  digitalWrite(5,HIGH);
  delay(8);
  digitalWrite(5,LOW);
  delay(2);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(5);
  digitalWrite(5,LOW);
  delay(5);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(5);
  digitalWrite(5,LOW);
  delay(5);
  digitalWrite(5,HIGH);
  delay(8);           
  digitalWrite(5,LOW);
  delay(2);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(5);
  digitalWrite(5,LOW);
  delay(5);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(5);
  digitalWrite(5,LOW);
  delay(5);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);          
  digitalWrite(5,HIGH);
  delay(8);         
  digitalWrite(5,LOW);
  delay(2);
  digitalWrite(5,HIGH);
  delay(5);
  digitalWrite(5,LOW);
  delay(5);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(5);
  digitalWrite(5,LOW);
  delay(5);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(8);        
  digitalWrite(5,LOW);
  delay(2);
  digitalWrite(5,HIGH);
  delay(5);
  digitalWrite(5,LOW);
  delay(5);
  digitalWrite(5,HIGH);
  delay(5);
  digitalWrite(5,LOW);
  delay(5);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(5);
  digitalWrite(5,LOW);
  delay(5);
  digitalWrite(5,HIGH);
  delay(5);
  digitalWrite(5,LOW);
  delay(5);
  digitalWrite(5,HIGH);
  delay(5);
  digitalWrite(5,LOW);
  delay(5);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(8);       
  digitalWrite(5,LOW);
  delay(2);
  digitalWrite(5,HIGH);
  delay(5);
  digitalWrite(5,LOW);
  delay(5);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(8);    
  digitalWrite(5,LOW);
  delay(2);
  digitalWrite(5,HIGH);
  delay(5);
  digitalWrite(5,LOW);
  delay(5);
  digitalWrite(5,HIGH);
  delay(5);
  digitalWrite(5,LOW);
  delay(5);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(8);     
  digitalWrite(5,LOW);
  delay(2);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(8);        
  digitalWrite(5,LOW);
  delay(2);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(8);          
  digitalWrite(5,LOW);
  delay(2);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(5);
  digitalWrite(5,LOW);
  delay(5);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(5);
  digitalWrite(5,LOW);
  delay(5);
  digitalWrite(5,HIGH);
  delay(5);
  digitalWrite(5,LOW);
  delay(5);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(5);
  digitalWrite(5,LOW);
  delay(5);
  digitalWrite(5,HIGH);
  delay(5);
  digitalWrite(5,LOW);
  delay(5);
  digitalWrite(5,HIGH);
  delay(8);      
  digitalWrite(5,LOW);
  delay(2);
  digitalWrite(5,HIGH);
  delay(5);
  digitalWrite(5,LOW);
  delay(5);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(5);
  digitalWrite(5,LOW);
  delay(5);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(5);
  digitalWrite(5,LOW);
  delay(5);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
  digitalWrite(5,HIGH);
  delay(5);
  digitalWrite(5,LOW);
  delay(5);
  digitalWrite(5,HIGH);
  delay(2);
  digitalWrite(5,LOW);
  delay(8);
}

I have created the pulse in UNO and giving that in Due after decreasing voltage level from 5v to 3.3v. I want to calculate the duration of pulse when it is HIGH using attachInterrupt().

You don't need to use interrupts to measure pulses as long as 2ms. You could time them with micros(). Is there other code running concurrently?

On an Nano this works, on a Due I don't know it works unchanged.

const byte pulsePin = 2;

volatile unsigned long duration;
volatile bool newDurationAvailable;
unsigned long edgeUp;
unsigned long edgeDown;

void takeEdges() {
  if (digitalRead(pulsePin)) {
    edgeUp = micros();
  } else {
    edgeDown = micros();
    if (!newDurationAvailable) {
      duration = edgeDown - edgeUp;
      newDurationAvailable = true;
    }
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(pulsePin, INPUT);
  attachInterrupt(digitalPinToInterrupt(pulsePin), takeEdges, CHANGE);
}

unsigned long lastPrint;

void loop() {
  unsigned long topLoop = millis();

  if (newDurationAvailable) {
    if (topLoop - lastPrint >= 100) {
      Serial.print(F("duration: "));
      Serial.println(duration);
      lastPrint = topLoop;
    }
    newDurationAvailable = false;
  }
}

@aarg

I agree it's buffered and return quick, but still it's a big unknown that can trigger challenges

In his case, he has 8ms HIGHs and 2ms low and your serial is set to 9600bds

at 9600 bds, you send ~1 character per millisecond.

So in 2ms you have only sent 2 chars of the ASCII representation of the duration - which is probably 6 to 8 chars in his case + the time to execute the Serial.println(duration);

In my opinion after a short while (in his 100 iteration loop) the serial buffer will fill up and create challenges;

@Sumit_jain: a quick check would be to set Serial at 115200 instead of 9600 and see if you get different results.

Also, is the serial just for debug, or needed for the final program?

On an Nano this works, on a Due I don't know it works unchanged.

Sorry for late reply..

@Whandall, your code is working fine initially but after some iteration, it is just showing pulse of 8 ms only. the SerialMonitor output is shown below..

duration: 5011
duration: 2009
duration: 2013
duration: 2013
duration: 2012
duration: 5010
duration: 8009
duration: 8017
duration: 8011
duration: 8007
duration: 8008
duration: 8008
duration: 8009
duration: 8009
duration: 8004
duration: 8005
duration: 8009
duration: 8009
duration: 8009
duration: 8012
duration: 8007
duration: 8009
duration: 8009
duration: 8005
duration: 8005
duration: 8009
duration: 8010
duration: 8009
duration: 8009
duration: 8009
duration: 8007
duration: 8007
duration: 8009
duration: 8009
duration: 8009
duration: 8009
duration: 8009
duration: 8009
duration: 8005
duration: 8009
duration: 8009
duration: 8006
duration: 8007
duration: 8009
duration: 8009
duration: 8009
duration: 8010
duration: 8010
duration: 8008
duration: 8005
duration: 8005
duration: 8009
duration: 8011
duration: 8007
duration: 8006
duration: 8005
duration: 8009
duration: 8009
duration: 8005
duration: 8006
duration: 8004
duration: 8009
duration: 8009
duration: 8007
duration: 8007
duration: 8009
duration: 8005
duration: 8009
duration: 8009
duration: 8010
duration: 8009
duration: 8009
duration: 8009
duration: 8009
duration: 8007
duration: 8008
duration: 8005
duration: 8009
duration: 8009
duration: 8009
duration: 8009
duration: 8010
duration: 8009
duration: 8009
duration: 8005
duration: 8007
duration: 8006
duration: 8009
duration: 8009
duration: 8009
duration: 8005
duration: 8009
duration: 8005
duration: 8009
duration: 8009
duration: 8009

Please copy and paste the serial output and post that also, the same way.

Serial out of the code that uses pulseln function is given below:

2612
6506
6506
6500
2612
10397
6500
2612
2612
2613
2615
2612
2612
2612
2612
10399
6505
6506
2612
2607
2613
2607
2612
2612
2612
10398
2612
2613
2612
2618
2611
2613
2607
2612
2610
10394
2612
2613
2612
2611
2612
2612
2612
2607
2612
10394
2612
6505
2613
2612
6505
6506
2613
6508
6505
10399
6500
2612
6500
2612
6506
2612
2612
6506
2612
10398
10398
2613
6505
2612
2607
2612
2617
2607
6506
10398
2612
2615
2612
6505
2612
6500
2612
2607
2612
10398
6506
2612
2611
2612
2612
2607
6505
2612
2607
10399
6503
6505
2612
2612
2612
6506
6505
6505
2607
10396
6500
2612
2613
2612
2612
2612
2612

My code only prints a new measurements all 100 ms.

If you want to see all measurements you could remove the time moderation or store the values in an array and print them all later.

If you want to see all measurements you could remove the time moderation or store the values in an array and print them all later.

Sorry but i am unable to understand what you are suggesting me to do. Is removing time moderation means removing " newDurationAvailable " or what??

const byte pulsePin = 2;

volatile unsigned long duration;
volatile bool newDurationAvailable;
unsigned long edgeUp;
unsigned long edgeDown;

void takeEdges() {
  if (digitalRead(pulsePin)) {
    edgeUp = micros();
  } else {
    edgeDown = micros();
    if (!newDurationAvailable) {
      duration = edgeDown - edgeUp;
      newDurationAvailable = true;
    }
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(pulsePin, INPUT);
  attachInterrupt(digitalPinToInterrupt(pulsePin), takeEdges, CHANGE);
}

unsigned long lastPrint;

void loop() {

  if (newDurationAvailable) {
    Serial.println(duration);
    newDurationAvailable = false;
  }
}

The very first measurement could be garbage, so you should discard it. This could be handled by the ISR, but would add unneeded complexity and therefore runtime.

As always: you don't get something for nothing.

The

   if (!newDurationAvailable) {

stops the ISR from overwriting the unhandshaked previous duration, it could be dropped, but then the duration needs a noInterrupts/interrupts even for a copy. This overrun could be counted easily by adding an else part to that if.