dut:
wow great work thanks@Jack Christensen. i try it and it really working for me. i manage to get sample with desired interval. i will try to work on continuous taking sample without stop the time.
Just remember, continuous samples can only be taken for so long at high rates, if there is to be sufficient time to process them.
i wonder, instead of taken one input channel , can we make arduino take sample with 2 or 3 more channel synchronously?
Funny you should ask, my application needs two analog inputs, so that's the next thing I did. This sketch reads ADC channels 0 and 1 alternately.
//Timer-driven ADC sampling.
//Jack Christensen 13Jun2013
#define SAMPLE_SIZE 20
#define PAUSE_BETWEEN_SAMPLES 100 //milliseconds
#define BAUD_RATE 115200
volatile boolean adcBusy;
volatile boolean timerFlag;
volatile int adcVal;
byte mux;
void setup(void)
{
delay(1000);
Serial.begin(BAUD_RATE);
Serial.println(F("adcStart_us, adcLapse_us, adcValue"));
//set up the timer
TCCR1B = 0; //stop the timer
TCCR1A = 0;
TIFR1 = 0xFF; //ensure all interrupt flags are cleared
OCR1A = 1999; //timer runs at 16MHz / 2000 / 8 (prescaler) = 1kHz (1000µs between samples)
OCR1B = 1999;
cli();
TCNT1 = 0; //clear the timer
TIMSK1 = _BV(OCIE1B); //enable timer interrupts
sei();
TCCR1B = _BV(WGM12) | _BV(CS11); //start the timer, ctc mode, prescaler 8
//set up the adc
ADMUX = _BV(REFS0); //use AVcc as reference
ADCSRA = _BV(ADEN) | _BV(ADATE) | _BV(ADIE); //enable ADC, auto trigger, interrupt when conversion complete
ADCSRA |= _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0); //ADC prescaler: divide by 128
ADCSRB = _BV(ADTS2) | _BV(ADTS0); //trigger ADC on Timer/Counter1 Compare Match B
}
void loop(void)
{
unsigned long startTimes[SAMPLE_SIZE]; //adc start time (timer interrupt)
unsigned long endTimes[SAMPLE_SIZE]; //adc complete time (adc interrupt)
unsigned int adcVals[SAMPLE_SIZE]; //values from the ADC
unsigned long tStart; //timer interrupt time from micros()
unsigned long tEnd; //adc interrupt time from micros()
byte i; //array index
i = 0;
while (adcBusy); //if a conversion is in process, wait for it to complete
ADMUX = _BV(REFS0); //force mux0
mux = 0;
do {
while (!adcBusy); //wait for next conversion to start
tStart = micros(); //capture the time
while (adcBusy); //wait for ADC conversion to complete
tEnd = micros(); //capture the time
startTimes[i] = tStart; //save the times
endTimes[i] = tEnd;
cli();
adcVals[i] = adcVal; //save the analog reading
sei();
} while (++i < SAMPLE_SIZE);
//print the data
Serial.println();
Serial.print(millis());
Serial.println(" ms");
for (byte i=0; i<SAMPLE_SIZE; ++i) {
Serial.print(startTimes[i]);
Serial.print(", ");
Serial.print(endTimes[i] - startTimes[i]);
Serial.print(", ");
Serial.println(adcVals[i]);
}
Serial.flush();
#if PAUSE_BETWEEN_SAMPLES > 0
delay(PAUSE_BETWEEN_SAMPLES);
#endif
}
ISR(ADC_vect)
{
adcBusy = false;
adcVal = ADC;
ADMUX = _BV(REFS0) | (++mux & 1); //flip between mux0 and mux1
}
ISR(TIMER1_COMPB_vect)
{
adcBusy = true;
}
Output looks like this:
adcStart_us, adcLapse_us, adcValue
1019 ms
1001436, 204, 115
1002436, 116, 1018
1003436, 108, 115
1004436, 116, 1018
1005436, 108, 115
1006436, 108, 1018
1007436, 108, 115
1008436, 108, 1018
1009436, 108, 115
1010436, 108, 1018
1011436, 108, 115
1012436, 108, 1018
1013436, 108, 115
1014436, 108, 1018
1015436, 108, 115
1016436, 108, 1018
1017436, 108, 115
1018436, 108, 1018
1019436, 108, 115
1020436, 108, 1018
1174 ms
1155436, 108, 115
1156436, 108, 1018
1157436, 108, 115
1158436, 108, 1018
1159436, 108, 115
1160436, 108, 1018
1161436, 108, 115
1162436, 108, 1018
1163436, 108, 115
1164436, 108, 1018
1165436, 108, 115
1166436, 108, 1018
1167436, 108, 115
1168436, 108, 1018
1169436, 108, 115
1170440, 104, 1018
1171436, 108, 115
1172436, 108, 1018
1173436, 108, 115
1174436, 108, 1018
1328 ms
1309436, 108, 115
1310436, 108, 1018
1311436, 108, 115
1312436, 108, 1017
1313436, 108, 115
1314436, 108, 1018
1315436, 108, 115
1316436, 108, 1018
1317436, 108, 115
1318436, 108, 1018
1319436, 108, 115
1320436, 108, 1018
1321436, 108, 115
1322436, 108, 1018
1323436, 108, 115
1324436, 108, 1018
1325436, 108, 115
1326436, 108, 1018
1327436, 108, 115
1328436, 108, 1018