Created Thu, 07 Nov 2013 16:30:28 +0000 by 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;
}
}
}
//=====================================================================
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.