Hi All,
I am trying to use the arduino duemilanove board to perform some real time digital filtering. I intend to read-in an analog signal using the on-board ADC, perform some filtering operations on the digitized signal and then use an external serial DAC (LTC 1660CN) to output the filtered analog signal. Thus far, I have been able to read in an analog signal and use the DAC to output it back. In order to have a fixed sampling rate, I am using an interrupt based program to perform the ADC/DAC operations. Using the Timer2 Overflow Interrupt, I was able to get a sampling rate of 13.9 KHz. I would like to push this higher. I tried using the Timer in CTC mode, to enable faster triggering of the interrupts. I also tried to load TCNT2 register with a number <255 (eg. 128 so it takes half as much time to trigger the interrupt), but both approaches give me the same sampling rate. I am not sure what I am missing. Below is my code.
// Program Arduino board to sample an analog signal
// and output an analog signal after Digital to Analog Conversion
#define ANIN 2 // analog input
#define CS_LD 7 // Enable pin for DAC
#define SCK 8 // Clock input to DAC
#define DATA 9 // Serial data input to DAC
// defines for setting and clearing register bits
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
// Variables to hold sampled signal and digital number to write.
uint16_t valadc;
uint16_t valdac;
void setup()
{
// DAC pin definitions
pinMode(DATA, OUTPUT);
pinMode(SCK,OUTPUT);
pinMode(CS_LD,OUTPUT);
digitalWrite(DATA,LOW);
digitalWrite(SCK,LOW);
digitalWrite(CS_LD,LOW);
// Timer 2 settings
TCCR2A = 0;
// Timer2 Clock Prescaler to : 1
sbi(TCCR2B,CS20);
cbi(TCCR2B,CS21);
cbi(TCCR2B,CS22);
OCR2A = 2;
//Timer2 Overflow Interrupt Enable
//TIMSK2 = 1<<TOIE2;
// Timer compare interrupt enable
TIMSK2 = (1<<OCIE2A);
//Set counter value to 128
//TCNT2 = 128;
// set ADC prescale to 16 to enable fast sampling
sbi(ADCSRA,ADPS2) ;
cbi(ADCSRA,ADPS1) ;
cbi(ADCSRA,ADPS0) ;
}
// Interrupt Service Routine for Timer2
//ISR(TIMER2_OVF_vect) {
ISR(TIMER2_COMPA_vect) {
valadc = analogRead(ANIN);
valdac = valadc;
// We perform digital read/write operations using PORT manipulations.
// as described in Arduino Reference - Arduino Reference
// Here the seventh bit of PORTD is the digital I/O pin 7 which is the CS_LD
// pin of the DAC
cbi(PORTD,7);
//load address of DAC (4 bits)
for (int i=2;i>=0;i--){
// Pin 0 of PORTB is digital I/O 8 and Pin 1 is D I/O 9
// which are clock and data inputs to the DAC respectively.
cbi(PORTB,1);
sbi(PORTB,0);
cbi(PORTB,0);
// Alternatively,
// PORTB &= B01; //data = 0
// PORTB |= B01; //clock = high
// PORTB &= B00; //clock = low
// or
//digitalWrite(DATA,0);
//digitalWrite(SCK,HIGH);
//delayMicroseconds(HALF_CLOCK_PERIOD);
//digitalWrite(SCK,LOW);
//delayMicroseconds(HALF_CLOCK_PERIOD);
}
sbi(PORTB,1);
sbi(PORTB,0);
cbi(PORTB,0);
//send the 10 bit data word to the DAC
for(int i=9;i>=0;i--){
if ( ((valdac&(1<<i)))>>i ){
sbi(PORTB,1);
}
else{
cbi(PORTB,1);
}
sbi(PORTB,0);
cbi(PORTB,0);
}
//write don't care bits (2 bits)
cbi(PORTB,1);
sbi(PORTB,0);
cbi(PORTB,0);
cbi(PORTB,1);
sbi(PORTB,0);
cbi(PORTB,0);
//latch enable, DAC output is set
sbi(PORTD,7);
//TCNT2 = 128;
OCR2A = 2;
}
void loop(){
;
}