I've stripped everything that I'm sure is not relevant out of my code below. Basically we're inputting a signal through pin A0 and sending samples over serial. It's a relatively simple project but because we want to maximize speed we're trying to avoid using analogRead(). However instead of getting a curve back we get a flatline that doesn't respond to any input, only to the prescaler values.
I've verified all of the register changes and they are all set correctly. If we run the system with the analogRead() code then it works so I know the circuit is working. I can not find any clear information around about why this might be happening. I've played around with the ADMUX channel select to see if maybe I was on the wrong channel but I'm not. Overall I'm very confused by this right now!
// defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
void setup() {
// Opens up the serial port with a baud of 115200
Serial.begin(115200, SERIAL_8E2);
pinMode(A0, INPUT);
digitalWrite(A0, HIGH);
// Enable ADC Completion Interrupt
sbi(ADCSRA,ADIE) ;
sei() ;
// Select the correct pin for the ADC
cbi(ADMUX,MUX3);
cbi(ADMUX,MUX2);
cbi(ADMUX,MUX1);
cbi(ADMUX,MUX0);
// Set the ADC to left adjust so that MSB is in low Byte
sbi(ADMUX,ADLAR) ;
sbi(ADCSRA,ADEN) ;
sbi(ADCSRA,ADSC) ;
}
void loop()
{
}
ISR(ADC_vect)
{
Serial.write(ADCH);
cbi(ADCSRA,ADIF);
sbi(ADCSRA,ADSC);
}
Sorry to thread dig, but i came across some information that may help others. Looks like @UncleO is on the right track there. Since you aren't setting the Prescaler ADPS[2:0], they default to 0 (division factor 2), which i too fast for the ADC to reliably approximate the value (http://www.gammon.com.au/adc):
Note that the datasheet (Table 28-7. ADC Characteristics) mentions that the ADC clock frequency range is 50 kHz to 1000 kHz. Thus (at this CPU clock speed of 16 MHz) the smallest prescaler you are allowed to use is 16, which is born out by testing below.
Prescaler 2 Analog port = 0, average result = 1023 Analog port = 1, average result = 1023 Analog port = 2, average result = 1023 Analog port = 3, average result = 1022 Time taken = 26220 Prescaler 16 Analog port = 0, average result = 1022 Analog port = 1, average result = 672 Analog port = 2, average result = 509 Analog port = 3, average result = 0 Time taken = 73164
The reason why it's working when you use the analogRead function is the prescalar is set to 128 within that library