THE EXPLANATION:
Points that may be relevant. I'm sampling an analog input using a prescaler that speeds up the sample rate. (Based on - http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1208715493/11 )
I switch between two interrupt functions, one that sits and waits for relevant signals on the analog pin and another that samples the relevant signals.
It's the sampling interrupt that shows the problem. The code for the other interrupt is not posted here.
THE CODE:
#include "TimerOne.h"
// defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
#define SAMPLES 500
enum {
Start = 1,
Sample = 2,
Done = 3,
};
volatile int sampleCount; // max SAMPLES
volatile byte records[SAMPLES + 10]; // 10 spare records for overreading interrupt
const unsigned int kWaitFrequency = 2000;
const unsigned int kWaitPeriod = 1000000 / kWaitFrequency;
const unsigned int kSampleFrequency = 10000;
const unsigned int kSamplePeriod = 1000000 / kSampleFrequency;
byte toneSampleState;
void readToneData() // interrupt function in question
{
records[sampleCount++] = analogRead(0);
}
void waitForTone() // another interrupt function
{
// REMOVED TO REDUCE THE SIZE OF THE POST
// sets the variable toneSampleState to Start when a tone is detected
}
void setup()
{
// set A/D prescale to 16
sbi(ADCSRA,ADPS2) ;
cbi(ADCSRA,ADPS1) ;
cbi(ADCSRA,ADPS0) ;
sampleCount = 0;
Serial.begin(115200);
toneSampleState = Done;
Timer1.initialize(kWaitPeriod);
Timer1.attachInterrupt(waitForTone);
}
void loop()
{
switch (toneSampleState)
{
case Start:
Timer1.detachInterrupt(); // detach waitForTone
Timer1.attachInterrupt(readToneData, kSamplePeriod);
toneSampleState = Sample;
break;
case Sample:
if (sampleCount >= SAMPLES)
{
// PROBLEM APPEARS HERE
Serial.print((int) sampleCount);
Serial.print(" samples\n");
Timer1.detachInterrupt(); // detach readToneData
// OTHER STUFF HAPPENS HERE
sampleCount = 0;
Timer1.attachInterrupt(waitForTone, kWaitPeriod);
toneSampleState = Done;
}
break;
default: // i.e. Done
break;
}
}