Hi,
I want to know the ADC sampling rate of the following code. Here I try to set different sampling rate using ADC prescalers and timer top
const byte adcPin = 0; // A0
//const int MAX_RESULTS = 256;
const int MAX_RESULTS = 512;
volatile int results [MAX_RESULTS];
volatile int resultNumber;
byte b0=0;
struct sdata {
uint8_t mode; // Stores sampling mode
uint8_t prescaler; // Stores timer1 prescaler
uint8_t adcp; // Stores adc timer prescaler
uint16_t timerTop; // Stores value of TOP register
};
static struct sdata sdata_1;
// ADC complete ISR
ISR (ADC_vect)
{
if (resultNumber >= MAX_RESULTS)
ADCSRA = 0; // turn off ADC
else
results [resultNumber++] = ADC;
} // end of ADC_vect
EMPTY_INTERRUPT (TIMER1_COMPB_vect);
void setup ()
{
Serial.begin(2000000); // set baudrate
// Set sdata_1 to dummy values and then configure the adc / timer registers using adcSetup(sdata_1). Then if we recieve a command
// to sample data before we recieve a command to configure registers the Arduino will still function correctly
sdata_1.mode = 8;
sdata_1.prescaler = 1;
sdata_1.adcp = 3;
sdata_1.timerTop = 159;
adcSetup(sdata_1);
}
void loop()
{
if (Serial.available())
{
// Store the last 1 bytes of data from serial
b0=Serial.read();
grabvalues(&sdata_1, b0);
// Set the ADC / timer registers for desired opperation
adcSetup(sdata_1);
// Begin conversions
adcStart();
logData();
}
}
void logData () {
while (resultNumber < MAX_RESULTS) { }
for (int i = 0; i < MAX_RESULTS; i++)
{
Serial.println (results [i]*(5.0 / 1023.0));
// wait 200 milliseconds before the next loop for the analog-to-digital
// converter to settle after the last reading:
delay(1);
}
resultNumber = 0; // reset counter
// Stop the ADC
ADCSRA = 0;
// ADCSRA = bit (ADEN) | bit (ADIE) | bit (ADIF)| bit (ADPS2) | bit (ADATE); // turn ADC ON
}
//// This interrupt is required in order to clear the OCF1B bit in register TIFR1. This bit is set when Timer1 equals the value of ICR1.
//ISR(TIMER1_COMPB_vect)
//{
//}
void adcStart ()
{
cli();
// Enable the ADC
ADCSRA |= (1 << ADEN);
// Set conversion bit to zero
ADCSRA |= (1 << ADSC);
// Set auto trigger of adc (adc will trigger on the selected signal, in this
// case timer1 reaching a certain value)
ADCSRA |= (1 << ADATE);
// Enable adc interrupts (this allows an interrupt to be called once the adc has
// finished a conversion
ADCSRA |= (1 << ADIE);
// Allow timer interrupts for timer1 B
TIMSK1 |= (1<<OCIE1B);
// Set timer value to 0
TCNT1 = 0;
sei();
}
void adcSetup(struct sdata sdata_1)
{
cli();
// Set Up timer1 //
// TCCR1A to 0 (no pwm), and initialise TCR1B to 0
TCCR1A = 0;
TCCR1B = 0;
ADCSRA = 0;
// Set timer1 prescaler
TCCR1B |= sdata_1.prescaler;
// Set CTC Mode with TOP value set to be ICR1
TCCR1B |= (1 << WGM12);
TCCR1B |= (1 << WGM13);
// Set TOP value of timer1 to give desired frequency
ICR1 = sdata_1.timerTop;
// Set input as A0 pin
ADMUX = bit (REFS0) | (adcPin & 7);
// Set ADC clock prescaler
ADCSRA |= sdata_1.adcp;
// // Set the trigger source for adc trigger to timer1 compare match B
// ADCSRB |= (1 << ADTS2);
// ADCSRB &= ~(1 << ADTS1);
// ADCSRB |= (1 << ADTS0);
// Set the trigger source for adc trigger to free running mode
ADCSRB &= ~(1 << ADTS2);
ADCSRB &= ~(1 << ADTS1);
ADCSRB &= ~(1 << ADTS0);
sei();
}
void grabvalues(struct sdata* sdata_1, byte byte0)
{
sdata_1->mode = byte0;
if (sdata_1->mode == 0)
{
// 0.2K
sdata_1->prescaler = 1;
sdata_1->adcp = 7; // Sets division factor to 128
sdata_1->timerTop = 79999;
}
else if (sdata_1->mode == 1)
{
// 0.5k
sdata_1->prescaler = 1;
sdata_1->adcp = 7; // Sets division factor to 64
sdata_1->timerTop = 31999;
}
else if (sdata_1->mode == 2)
{
// 1k
sdata_1->prescaler = 1;
sdata_1->adcp = 7; // Sets division factor to 32
sdata_1->timerTop = 15999;
}
else if (sdata_1->mode == 3)
{
// 2k
sdata_1->prescaler = 2;
sdata_1->adcp = 5; // Sets division factor to 64
sdata_1->timerTop = 999;
}
else if (sdata_1->mode == 4)
{
// 5K
sdata_1->prescaler = 1;
sdata_1->adcp = 7; // Sets division factor to 128
sdata_1->timerTop = 3199;
}
else if (sdata_1->mode == 5)
{
// 10k
sdata_1->prescaler = 1;
sdata_1->adcp = 6; // Sets division factor to 64
sdata_1->timerTop = 1599;
}
else if (sdata_1->mode == 6)
{
// 20k
sdata_1->prescaler = 1;
sdata_1->adcp = 5; // Sets division factor to 32
sdata_1->timerTop = 799;
}
else if (sdata_1->mode == 7)
{
// 50k
sdata_1->prescaler = 1;
sdata_1->adcp = 4; // Sets division factor to 16
sdata_1->timerTop = 319;
}
else if (sdata_1->mode == 8)
{
// 100k
sdata_1->prescaler = 1;
sdata_1->adcp = 3; // Sets division factor to 8
sdata_1->timerTop = 159;
}
else if (sdata_1->mode == 9)
{
// 200k
sdata_1->prescaler = 1;
sdata_1->adcp = 2; // Sets division factor to 4
sdata_1->timerTop = 79;
}
else if (sdata_1->mode == 10)
{
// 500k
sdata_1->prescaler = 1;
sdata_1->adcp = 1; // Sets division factor to 2
sdata_1->timerTop = 31;
}
}