I am working on an Arduino borad and I have previously no experince with it, unfortunately. I need to sense the voltage signal from a sensor through ADC of the Arduino. I have an Arduino Due,manual of which says It has upto 12 useable bins for ADC input.I want to acquire 4 analog signal. However, I have two questions:
1: I want to fetch the data at high frequency. So Let's say if sampling time of Due is 60 uS, A)will it take all of 4 analog signals at T= 60 uS and then convert them to digital ? or B) it will take first signal at 60 uS and fetch second analog signal from pin 2 at 120 uS and so on from 4th pin at 240 uS? Which one of these is the correct scenario.
2: It says that Arduino Due can take 1M sample per seconds. Of course, this is an ideal figure. But, will these 4 analog signals count toward 1 sample of Due or 4 samples ?
I want to fetch the data at high frequency*
What frequency ?
For a precise sampling rate, you want to trigger conversions with a Timer Counter, In the sketch below, there is an internal connection between TIOA2 output and ADC peripheral to trigger conversions at 44.1 KHz:
/*****************************************************************/
/* ADC conversions at 44.1 KHz */
/*****************************************************************/
volatile uint32_t lastConversion;
volatile boolean Flag;
void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
adc_setup();
tc_setup();
}
void loop()
{
if (Flag== true)
{
Flag = false;
// A new conversion is available
}
}
/************* Configure ADC function *******************/
void adc_setup() {
PMC->PMC_PCER1 |= PMC_PCER1_PID37; // ADC power on
ADC->ADC_CR = ADC_CR_SWRST; // Reset ADC
ADC->ADC_MR |= ADC_MR_TRGEN_EN // Hardware trigger select
| ADC_MR_TRGSEL_ADC_TRIG3 // Trigger by TIOA2
| ADC_MR_PRESCAL(1);
ADC->ADC_ACR = ADC_ACR_IBCTL(0b01); // For frequencies > 500 KHz
ADC->ADC_CHER = ADC_CHER_CH7; // Enable ADC CH7 = A0
ADC->ADC_IER = ADC_IER_EOC7; // Interrupt on End of conversion
NVIC_EnableIRQ(ADC_IRQn); // Enable ADC interrupt
}
void ADC_Handler()
{
static uint32_t Count;
lastConversion = ADC->ADC_CDR[7];
//lastConversion = ADC->ADC_LCDR;//Do NOT clear EOC7 bit
Flag = true;
if(Count++ > 44117)
{
Count = 0;
PIOB->PIO_ODSR ^= PIO_ODSR_P27;
}
}
/************* Timer Counter 0 Channel 2 to generate PWM pulses thru TIOA2 ************/
void tc_setup() {
PMC->PMC_PCER0 |= PMC_PCER0_PID29; // TC2 power ON : Timer Counter 0 channel 2 IS TC2
TC0->TC_CHANNEL[2].TC_CMR = TC_CMR_TCCLKS_TIMER_CLOCK2 // MCK/8, clk on rising edge
| TC_CMR_WAVE // Waveform mode
| TC_CMR_WAVSEL_UP_RC // UP mode with automatic trigger on RC Compare
| TC_CMR_ACPA_CLEAR // Clear TIOA2 on RA compare match
| TC_CMR_ACPC_SET; // Set TIOA2 on RC compare match
TC0->TC_CHANNEL[2].TC_RC = 238; //<********************* Frequency = (Mck/8)/TC_RC Hz = 44.117 Hz
TC0->TC_CHANNEL[2].TC_RA = 40; //<******************** Any Duty cycle in between 1 and 874
TC0->TC_CHANNEL[2].TC_CCR = TC_CCR_SWTRG | TC_CCR_CLKEN; // Software trigger TC2 counter and enable
}
You set a sampling rate, you set the number of ADC channels you want to enable and automatically all enabled ADC channels will be sampled at the correct pace (provided that Enabled channels X The sampling rate < 1 Msps).
Note: Both Graynomad pinout diagram and Sam3x datasheet are most useful for direct register programming.
Thank you for your recommendation. I want to sample the data at about 50 kHz. Could you please elaborate a bit about the sampling? i.e. Is it possible to fetch each of these 4 analog signals at the same time?
Let's say you need a 50KHz sampling rate for each analog channel:
1/ You set the Timer Counter to output a 50KHz wave form at TIOA2
2/ Automatically ADC peripheral "knows" that each eanabled channel has to be sampled at 50 KHz
The ADC peripheral will sample, one after the other, each enabled channel. If 4 ADC channels have been enabled, the ADC peripheral will sample at 50 KHz * 4 = 200 KHz, AND select channel 0 for conversion then channel1, then channel 2, then channel3, then channel 0, etc...