Hello everyone,
I am trying to trigger the adc measurement with a fixed sample rate, so I am using the timer 2 to generate the interrupt to start the adc measurement.
It all seems to work fine, the adc gets started, the adc interrupt gets triggered but for some reason the result is always read as a 0.
Testing the input with a normal analogRead returns reasonable values.
Right now I have trippechecked the datasheet but I can not find the mistake. I am now sitting the second day at this problem and just do not understand what is wrong.
#include <Arduino.h>
volatile uint8_t _val[5];
volatile uint8_t _curVal = 0;
volatile uint8_t _sampleNow = 0;
volatile uint8_t _selectedDetector;
void sampleData();
ISR(ADC_vect)
{
_val[_curVal] = ADCH;
_curVal++;
if (_curVal == 5)
_curVal = 0;
}
ISR(TIMER2_COMPA_vect) //New Measurement
{
sampleData();
}
ISR(TIMER2_COMPB_vect) //Sample & Hold already happend
{ //Deactivate to reduce power
if (_selectedDetector == 1)
//PORTD &= ~ (1<<PD3); //Detector 1 Disable
;
else
{
TIMSK2 &= ~ (1<<OCIE2B); //Disable Comp B Interrupt
//PORTC &= ~ (1<<PC0); //Detector 2 Disable
//PORTB &= ~ (1<<PB1); //IR LED Disable
}
}
void setupADC()
{
if (_selectedDetector == 1)
ADMUX = bit(REFS0) | bit(ADLAR) | bit(MUX2) | bit(MUX1); //Detector 1 = ADC Chanel 6, Left Adjusted, AVcc as Ref
else
ADMUX = bit(REFS0) | bit(ADLAR) | bit(MUX2) | bit(MUX1) | bit(MUX0); //Detector 2 = ADC Chanel 7, Left Adjusted, AVcc as Ref
ADCSRA = bit(ADEN) | bit(ADIE) | bit(ADPS1) | bit(ADPS0); //Interrupt & ADC Enable & Prescaler 8
}
void setupTimer2()
{
cli(); //Disable Interrupts globally
TCCR2B = 0; //Set controlregister to 0
TCCR2A = 0;
if (_selectedDetector)
{
OCR2A = 125; //2000 Hz samplerate => f_clk / pre / f_sample = counts = 8MHz / 32 / 2kHz = 125
OCR2B = 4; //16ADC clocks => 16* f_clk / pre / (f_clk / pre_adc) = 16* pre_adc / pre = 16 * 8 / 32 = 4
TCCR2A = 1 << WGM21; //No output, ctc
TCCR2B = 1 << CS21 | 1 << CS20; //Perscaler 32 -> 8MHz / 32 = 250kHz
}
else
{
OCR2A = 156; //400 Hz samplerate => f_clk / pre / f_sample = counts = 8MHz / 128 / 400Hz = 156
OCR2B = 1; //16ADC clocks => 16* f_clk / pre / (f_clk / pre_adc) = 16* pre_adc / pre = 16 * 8 / 128 = 1
TCCR2A = 1 << WGM21; //No output, ctc
TCCR2B = 1 << CS22 | 1 << CS20; //Perscaler 128 -> 8MHz / 64 = 62,5kHz
}
sei();
}
void sampleData()
{
if (bit_is_set(ADCSRA,ADSC)) //If converstation is running
return; //Exit
if (_selectedDetector)
{
PORTD = PORTD | 1<<PD3; //Detector 1 Enable
ADCSRA |= bit(ADSC); //ADC start conversion
}
else if (_sampleNow) //Measure every second interrupt
{
_sampleNow = 0;
PORTC = PORTC | 1<<PC0; //Detector 2 Enable
PORTB = PORTB | 1<<PB1; //IR LED Enable
ADCSRA |= bit(ADSC); //ADC start conversion
TIMSK2 |= 1 << OCIE2B; //Enable comp B interrupt
}
else
{
_sampleNow = 1;
}
}
void startSampleing(void)
{
if (_selectedDetector)
{
TIMSK2 = 1<<OCIE2A | 1<<OCIE2B; //Enable Comp A & Comp B Interrupt
}
else
{
TIMSK2 = 1<<OCIE2A; //Enable Comp A Interrupt
}
}
void setup()
{
/* Port Setup */
pinMode(9,OUTPUT); //IR LED
pinMode(3,OUTPUT); //Detector 1 Enable
pinMode(A0,OUTPUT); //Detector 2 Enable
pinMode(A6,INPUT); //Detector 1 Input
pinMode(A7,INPUT); //Detector 2 Input
pinMode(A2,OUTPUT); //CS Poti
pinMode(A1,OUTPUT); //Shutdown Poti
pinMode(2,OUTPUT); //Writecontrol EEPROM
pinMode(A3,OUTPUT); //Select EEPROM
digitalWrite(A1,HIGH);
/* ADC Setup */
_selectedDetector = 0;
setupADC();
/* Timer 2 Setup */
setupTimer2();
startSampleing();
Serial.begin(115200);
}
void loop()
{
while (_curVal > 0)
{
Serial.println(_val[_curVal]);
_curVal--;
}
}
However testing it without the timer interrupt works fine:
#define IRLED 9
#define DETECTOR2 A7
#define DET2EN A0
#define POTISHTDWN A1
#define POTIPIN A2
volatile int test;
volatile unsigned int val;
ISR(ADC_vect)
{
test = 1;
val = ADCH;
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
pinMode(POTISHTDWN,OUTPUT);
pinMode(POTIPIN,OUTPUT);
pinMode(DET2EN, OUTPUT);
pinMode(IRLED,OUTPUT);
pinMode(DETECTOR2,INPUT);
digitalWrite(POTISHTDWN,HIGH); //Digital Potentiometer enable
ADMUX = bit(REFS0) | bit(ADLAR) | bit(MUX2) | bit(MUX1) | bit(MUX0); //Detector 2 = ADC Chanel 7, Left Adjusted, AVcc as Ref
ADCSRA = bit(ADEN) | bit(ADIE) | bit(ADPS1) | bit(ADPS0); //Interrupt & ADC Enable & Prescaler 8
}
void loop()
{
digitalWrite(DET2EN,HIGH); //Detektor 2 enable
digitalWrite(POTISHTDWN,HIGH); //Digital Potentiometer
digitalWrite(IRLED,HIGH); //IR LED enable
ADCSRA |= bit(ADSC);
while (test == 0)
{
}
test = 0;
digitalWrite(POTISHTDWN,LOW);
digitalWrite(DET2EN,LOW);
digitalWrite(IRLED,LOW);
Serial.println(val);
}
Has anyone an idea why this happens?