LPC11U24 interuptIn is missing edge

14 Nov 2012

I am using InteruptIn rise and fall to measure the timing of an incoming signal that is connected to pin 21. After having some problems I simplyfied the code and the problem still occurs.

For further investigation I checked with logic analyzer and I found out that INteruptIn seems to miss an edge once in a while. It mostly occurs a rising edge, but I have seen falling edge misses too.

Interestingly polling the same pin 21 in the main loop, does not expose that problem.

  • B0 is input pin21 ir signal
  • B1 is output pin23 set by InteruptIn rise and fall
  • B2 is output pin24 while loop

/media/uploads/mattes/_scaled_img095crop.jpg

As you can see B1 stays zero, while B0 rises.

#include "mbed.h"
 
DigitalOut bitbang(p23);
DigitalOut bitbang2(p24);
InterruptIn evt(p21);
DigitalIn necir(p21);
 
void isr_up() {
   bitbang = 1;
}
 
void isr_down() {
   bitbang = 0;
}
 
int main() {
   //evt.mode(PullNone);
   evt.rise(isr_up);
   evt.fall(isr_down);
 
   while(1) {
      if ( necir.read() )
         bitbang2 = 1;
      else
         bitbang2 = 0;
   }
}
14 Nov 2012

The method you use to attach the functions is not correct.

 //evt.mode(PullNone);
   evt.rise(isr_up);
   evt.fall(isr_down);

should be

 //evt.mode(PullNone);
   evt.rise(&isr_up);
   evt.fall(&isr_down);

There may also be some unexpected behaviour when you define the same pin both as DigitalIn and InterruptIn

InterruptIn evt(p21);
DigitalIn necir(p21);
14 Nov 2012

You can read the InterruptIn (evt) like this:

evt.read()

You don't need to define it as DigitalIn.

Lerche

14 Nov 2012

Normally I also place the '&'s, but not sure if it is actually needed, I think it automatically makes it a pointer. I dont have an LPC11u24, so had to do with my 1768. I ran his code on it, only additions were that I made p22 a PWM output with 1ms period (50% duty cycle), and connected it to p21 (had to make my square wave somehow). Aditionally I added a timer which is reset at every rising edge, and if last time was more than 1ms + 10% ago, it reports it back over serial. So if it would miss a rising edge it prints it. And it simply doesnt print anything, it doesnt miss any edges. (And yes I did verify its behaviour by removing the connection between p21 and p22).

So you would wonder if it is either specific to the LPC11u24, or if it is something else.

14 Nov 2012

I added the '&', but it doesn't make a difference on how the code behaves. Which makes sense since we are talking C/C++ here. My understanding is that a reference to a function automatically is a pointer.

Additionally I changed

InterruptIn evt(p21);
DigitalIn necir(p22);

Again, no difference. I am still missing edges. I wished I had a 1768 to try,

Erik, Could you send me your test code. I am more than happy to give it a spin on my LPC11u24.

Secondly, Is there any way to debug my problem, to get to the bottom of it? One reason I can see for missing an edge, could be the underlying layer is still busy, with some higher priority interrupt. But not knowing much how mbed works internally everything is a guess.

Mat

14 Nov 2012

I kept as much as possible of your program intact, so even though it is unlikely it would have an influence, you never can be sure. Not neatest, was just a quick test :) (p21 and p22 were connected with a wire).

#include "mbed.h"

DigitalOut bitbang(p23);
DigitalOut bitbang2(p24);
InterruptIn evt(p21);
DigitalIn necir(p21);

PwmOut pwm(p22);

Timer timer1;
 
void isr_up() {
   bitbang = 1;
   if (timer1.read()>0.0011)
    printf("%f\n\r",timer1.read());
   
   timer1.reset();
}
 
void isr_down() {
   bitbang = 0;
}
 
int main() {
   //evt.mode(PullNone);
   evt.rise(isr_up);
   evt.fall(isr_down);
   timer1.start();
   
   pwm.period(0.001);
   pwm=0.5;
 
   while(1) {
      if ( necir.read() )
         bitbang2 = 1;
      else
         bitbang2 = 0;
   }
}

What kind of timescale are your interrupts working at? It is known that for the really fast interrupts you want to get directly to the hardware instead of using the mbed layer, but if that can be the problem depends on your frequency. I think that is also the only way us mortals can debug it: directly looking at the state of the hardware (so reading registers).

23 Nov 2012

Erik, Thanks for providing the pwm sample code. I finally got around testing it. Though I had some trouble running it. Once I uploaded the code all LEDs were blinking periodically. In addition I got an message on the USB console: 'pinmap not found for peripheral'.

It seems like the LPC11U24 doesn't like to use pin 22 for pwm out. Once I switched it to

PwmOut pwm(p26);

your sample started working. So far so good, I haven't seen any timer messages popping up.

Quote:

What kind of timescale are your interrupts working at?

I am currently using a NEC style remote. One bit is encoded between 0.5 msec to 2msec.

I lowered the PWM down to 30usec (@50%) and the still no misses with the above code.

Which make me wondering. Why do I encounter those 'edge missing' problems on isr_up() (or down) when the IR receiver toggles the line at even lower frequency?

Polling the pin works fine and it is only that ISR shows misses?

There ought to be an explanation for this behaviour.

13 Mar 2013

Hi,

Was this problem ever resolved? I'm seeing the same problem. I.e. the interrupt is sometimes not triggered, even at low frequency.

Thanks, James