Simple question, I have set my ADC to read in "continuous"/interrupt mode and I take the reading the following way:

ISR(ADC_vect) {
   int val = ADCL;
   val += ADCH << 8;
   ... //Code to do stuff with reading here.

My question is does the ADC start the new reading as soon as I have read the ADCH register or does it wait for the code inside the interrupt to finish? Basically I need to know if having more instructions in the interrupt will slow down my reading rate.

I don't have an oscilloscope or any good way to measure my reading rate accurately enough to know if a few extra lines of codes is affecting the rate or not.


Your answer is correct. The ADC does indeed keep going independently of what the ISR does. There is, however, a point I would like to make clearer. You asked:

My question is does the ADC start the new reading as soon as I have read the ADCH register or does it wait for the code inside the interrupt to finish?

The ADC starts a new reading as soon as it is done taking the previous one, irrespective of whether you read ADCH or not. When your ISR starts, the ADC is already busy making the following conversion. This guarantees a steady conversion rate, at one A/D conversion every 13 ADC clock cycles exactly.

As a side note, you can read the result with

int val = ADC;

No need to read the bytes separately unless you are using a very ancient version of gcc that does not know how to read a 16-bit register.

  • Thanks for the clarification :) Quick unrelated question (if you don’t know the answer I’ll delete this comment). In some debugging efforts I hooked up the A0 pin I was reading from to ground with a 300k resistor between them and got some rather significant ( up to 20 ) readings from it, fluctuating like a wave. I would expect it to be 0, what exactly is being measured when doing this? I thought the ADC did not recieve any voltage inside itself so where is the voltage comming from? :s guessing this is related to ”floating pin readings”, but I am still confused. Jun 6 '20 at 20:35
  • @BeaconofWierd that's probably your circuit catchinh some electromagbetic radiation and 300kOhm is simply too high to pull the analog pin to ground in that case. If you imagine you increase this resistance, at some point you would consider the pin floating (maybe at 1MOhm or at 100MOhm?).
    – Sim Son
    Jun 6 '20 at 22:06
  • @BeaconofWierd: I agree with Sim Son that the resistance is too high. According to the datasheet, the ADC should be fed the voltage to be measured from a source with no more than 10 kΩ of internal impedance. Jun 6 '20 at 22:17

Ok, I'm pretty sure I know the answer to this one now after some more testing. I played around with the number of instructions performed inside the ADC interrupt call and simply timed it using micros(). Though it did not give me super precise accuracy there was a clear and quick drop in read frequency when the number of CPU cycles needed inside the interrupt call exceeded the number of CPU cycles needed by the ADC while the frequency was hardly affected when the CPU cycles needed for the instructions were less than the cycles needed for the ADC. The only way I can make sense of this is if the ADC keeps going independently of the code that's inside the interrupt.

If someone wants to correct me/add some details here I would be very happy. But for my purposes this answer is enough :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.