chipKIT® Development Platform

Inspired by Arduino™

Problems with interrupt and coretimer.

Created Thu, 07 Nov 2013 16:30:28 +0000 by MarkSerino


MarkSerino

Thu, 07 Nov 2013 16:30:28 +0000

The project was to basically to make a frequency counter, so I wrote some code using the interrupt on pin2 and the coretimer function. The interrupt would trigger on a falling edge, calculate the microseconds from the last falling edge and store it in an array that would later be sent to the PC. The problem is I would get a periodic offset in my data and it would change depending on the frequency I was measuring. I have run the code with the Uno32, uC32 and the Max32 boards and still get periodic offsets(slightly different between boards but all exhibit basically the same offset) on all the boards.

I've included the code I am using along with an image of the data at different frequencies.

I eventually went with another processor board that did what I needed. I just want to let people know about this in case someone else is doing something similar. But, I am curious if there is a solution to this or maybe why this is happening.

Code--------------------------------------

#include <plib.h>

word wTotalCnt = 5000;
word wCountIdx = 0;
byte bData[5000];

boolean blnIsCaptureRunning = false;
boolean bIsDataReady = false;

unsigned long ulPrevValue = 0;
unsigned long ulCurrValue = 0;
unsigned long ulOffsetValue = 0;
unsigned long ulMicroSecValue = 0;
#define INT1 1
byte bytSelect = 0;
//=====================================================================
void setup() {
  Serial.begin(115200);

  pinMode(2, INPUT);
  attachInterrupt(INT1, IsrCapture, FALLING);

}
//=====================================================================
void loop() {

  if (Serial.available() > 0 && !blnIsCaptureRunning) {
    bytSelect = Serial.read();
    if(bytSelect == 32){
      InitCapture();
    }
  }
  //===================================================================

  if(bIsDataReady){
    for(wCountIdx = 0; wCountIdx < wTotalCnt; wCountIdx++){
      Serial.write(bData[wCountIdx]);
    }
    bIsDataReady = false;
  }

}//end of Loop
//=====================================================================
//Interrupt Routines
//=====================================================================
void InitCapture() {

  ulPrevValue = ReadCoreTimer();
  wCountIdx = 0;
  blnIsCaptureRunning = true;
}
//=====================================================================
//Interrupt Service Routine
void IsrCapture() {//runs when a falling edge is detected
  
  if(blnIsCaptureRunning){

    ulCurrValue = ReadCoreTimer();
    ulMicroSecValue = ulCurrValue - ulPrevValue;
    ulPrevValue = ulCurrValue;
    
    bData[wCountIdx] = (byte)(ulMicroSecValue / 40);//convert to microseconds
    
    wCountIdx++;
    if(wCountIdx > wTotalCnt){
      blnIsCaptureRunning = false;
      bIsDataReady = true;
    }
  }
}

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


majenko

Thu, 07 Nov 2013 18:33:21 +0000

My guess is that another interrupt (probably the millis() core timer interrupt task) is interrupting (or overriding) your external interrupt, so it's getting delayed. That makes a slightly longer gap between edges, and the next interrupt will appear to be sooner - making a smaller gap - thus the almost heartbeat shaped waveform you're seeing.