Hey folks,
I'm working on a ultrasonic range finder project with my new Due, and I had a quick question re: sampling from the ADC.
Basically, I want to be able to sample a signal for a period of time (40-50 ms) at about 100,000 khz. I've wrote the code below that allows me to change the sample num of samples and the sampling frequency; it uses a timer to handle the sampling. However, I wondered, should I be just running a loop in a function to collect the samples instead of using the timer? Would that result in a consistent sample frequency (sampling at ADC speed)?
Code is below:
//timer library
#include <ARMtimer.h>
#undef HID_ENABLED
int result = 0;
int sampleCount = 0;
int sampleFrequency = 60000;
// unsigned long sampleTime = 1000; //in millis
const int numSamples = 20000;
int resultArray[numSamples];
unsigned long programtime = 0;
//boolean readready = FALSE;
//setup adc function
void prepareADC(){
//adc_init(ADC, SystemCoreClock, ADC_FREQ_MAX, ADC_STARTUP_FAST);
adc_init(ADC, 42000000, 21000000, 3);
// adc_init(ADC, SystemCoreClock, ADC_FREQ_MAX, ADC_STARTUP_FAST);
adc_configure_timing(ADC, 0, ADC_SETTLING_TIME_3, 1);
//Port 0 = ADC_Channel_7
adc_enable_channel(ADC, ADC_CHANNEL_7);
ADC->ADC_MR |=0x80; // free running
//adc_set_comparison_channel(ADC, ADC_CHANNEL_7);
//adc_set_comparison_mode(ADC, ADC_EMR_CMPMODE_IN);
//adc_set_comparison_window(ADC, 0, 3300);
adc_enable_interrupt(ADC, ADC_IER_DRDY);
//adc_configure_trigger(ADC, ADC_TRIG_SW, 0);
NVIC_EnableIRQ(ADC_IRQn);
adc_start(ADC);
}
void ADC_Handler(void) {
//Check the ADC conversion status
if ((adc_get_status(ADC) & ADC_ISR_DRDY) == ADC_ISR_DRDY)
{
//Get latest digital data value from ADC and can be used by application
result = adc_get_latest_value(ADC);
// Serial.println("test");
}
}
volatile void receivedata()
{
//this should happen sample frequency
if (sampleCount < numSamples){
//put analog value into array
resultArray[sampleCount] = result;
// Serial.println(resultArray[sampleCount]);
// Serial.println(sampleCount);
// Serial.println(numSamples);
// Serial.println(result);
}
sampleCount = sampleCount + 1;
// Serial.println(sampleCount);
if (sampleCount == numSamples){
sampleCount = 0;
// Serial.println(sampleCount);
}
}
//function to send array to serial
void sendData(){
for (int j=0; j<= numSamples; j++){
Serial.println(resultArray[j]);
}
}
void establishContact() {
while (Serial.available() <= 0) {
Serial.print('A'); // send a capital A
delay(300);
}
}
void setup() {
//setup serial
Serial.begin(115200);
prepareADC();
// Start timer. Parameters are:
// TC1 : timer counter. Can be TC0, TC1 or TC2
// 0 : channel. Can be 0, 1 or 2
// TC3_IRQn: irq number. See table.
// 2 : frequency (in Hz)
// myTimedPrint : function pointer to the function you want executed
//read 100 times per second
// Paramters table:
// TC0, 0, TC0_IRQn
// TC0, 1, TC1_IRQn
// TC0, 2, TC2_IRQn
// TC1, 0, TC3_IRQn
// TC1, 1, TC4_IRQn
// TC1, 2, TC5_IRQn
// TC2, 0, TC6_IRQn
// TC2, 1, TC7_IRQn
// TC2, 2, TC8_IRQn
// put your setup code here, to run once:
//setup timer to trigger 10hz
//setup adc to capture on trigger
//on trigger add value to array
programtime = millis();
}
void loop() {
// programtime = millis();
// Serial.println(programtime);
// if (programtime > sampleTime+1){
// stopTimer(TC3_IRQn);
// }
if (Serial.available() > 0) {
// read the serial buffer;
// you don't care about the value of
// the incoming byte, just that one was
// sent:
int inByte = Serial.read();
startTimer(TC1, 0, TC3_IRQn, sampleFrequency, receivedata);
// delay(100);
//for (int i = 0; i<= numSamples-1; i++){
// Serial.print(resultArray[i]);
// Serial.write((uint8_t *)resultArray[numSamples], numSamples);
sendData();
// Serial.println("\n");
stopTimer(TC3_IRQn);
sampleCount = 0;
}
// check to see whether there is a byte available
// to read in the serial buffer:
// if (Serial.available() > 0) {
// read the serial buffer;
// you don't care about the value of
// the incoming byte, just that one was
// sent:
// int inByte = Serial.read();
// }
// if (sampleCount == numSamples){
// sampleCount = 0;
// Serial.println('new sample');
//start another sample
// }
}