Go Down

Topic: DUE problem with micros() inside interrupts (Read 3 times) previous topic - next topic

mcgavinz26

Hi internet,

I have a project that is working refectly with an UNO but not so well with the DUE.  The problem seems to be that the interrupt type is changing or not working as expected.  I have an UNO generating a 490hz 50% PWM signal as the test input to pin 2 on the DUE.  I am using a Parallax oscilloscope to monitor the input signal and it is spot on.  Here is a simple piece of code I have loaded on the DUE that highlights the fault:
Code: [Select]

void setup() {
  Serial.begin(115200);
  attachInterrupt(2, FallEdge, FALLING);
}

void loop() {
  interrupts();
}

void FallEdge(){
  Serial.println(micros());
}

If I open the serial monitor, copy the output into a spreadsheet, write an equation to get the difference from one cell to the next ("=A2-A1") ... I can see that every 200 to 80 cycles it only reads about 1040 and then 3040 instead of 2040. It is not a consistent number of cycles from one error to the next. 

This seems like it is trigger on the rising edge instead of the falling edge once in a while, then ignoring a falling edge before going back to working off of falling edges.  I have the circuit protected with a 3.0V zener diode and fed in through a 1kohm resistor so that it doesn't get the UNO's 5V peak output.  Again, on the oscilloscope it looks solid, 3.0V.

As a check on the hardware I also used a frequency generator set at about 3.3v and removed my resistance/zener circuit protection entirely.  I am using Arduino IDE 1.5.2, had the same problem with previous release, 1.5.1r2.

Can someone else setup the same test and verify my sanity?  Has anyone else seen any problems with the interrupts on the DUE?

pito

Printing within isr is not recommended as it takes time (0.5ms in your case). Try to print outside the isr..

mcgavinz26

At 490Hz the 0.5ms time to print shouldn't matter though.  Plenty of time to do it and move on, right?  I also tried a little less than 400Hz and had the same problem.  And actually, I noticed the problem without the serial commands.  The example code I posted is just the easiest way to demonstrate the problem.  The program I wrote worked fine on the UNO, but not on the DUE.  The only reason I need the DUE is that I need more memory than the UNO has available.

gbduino

In such cases and for test purposes I prefer to change an output pin to be minimum invasive (compared the used serial command).
Invert an output inside- and each time the interrupt is called and watch the result with an oszilloscope, logic analizer etc. The comparison between the input signal and the output should show you if the interrupt is missing something.
Another solution might be to use two counters. One inside the interrupt and a second one outside (at this frequency the signal will be detected easily also not using an interrupt). If both count up at the same rate - it should be OK.
I hope I could help.

mcgavinz26

Thanks for the idea.  That was what the original program was doing in the interrupt along with a little math.  Originally I wasn't using any serial commands.  I started to write this topic before I was totally done debugging and thats why the title doesn't exactly make sense for how I described it (forgot to change it).  At first I thought it was something specific to the micros() command, but when I realized the time stamps were happening only at a rising or falling edge it started making a little more sense... although it still doesn't make much sense to me.  Seems like something is busted.

Go Up