Reading ADC with ADC interrupts and Timer Compare

Hi I am currently trying to write a code through registers to read three different analog readings from 3 different pins, here is my methodology:

  1. Timer compare 1 will turn on the flag to turn on the ADC interrupt
  2. ADC interrupt starts the conversion
  3. Timer compare 2 change the ADMUX register so that i can read from a different pin
  4. ADC interrupt starts conversion again

This is what i hope to achieve and it needs to be achieved in less than 1ms (the whole reading and changing port process)

Is this possible?

Hi @arduinouser1111
Welcome to the forum.

What is your project that needs that type of analog measurement?

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

Broadly speaking yes, something like this is possible. The important thing of course is to consult the data sheet: https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf

The ADC can be set to auto-trigger from a variety of different sources. The best way to do it can depend on exactly what you're trying to do.

  1. How often do you need take the sample? If it's very slow (like once per second) you can just poll it in code rather than fussing with interrupts.

  2. Do these measurements need to be taken in close temporal proximity? Or can their readings be evenly spread out within the required time interval?

To do it exactly how you want it, I would broadly do it this way:

  1. Start by setting up the ADC to trigger off of Timer1 overflow.

  2. Set up Timer1 to overflow at the interval I want.

  3. In the ADC ISR, keep a sequence counter variable that tracks which point of the reading sequence I'm on. On the first trigger of the sequence, change the ADC trigger to free-running, then make sure to set it at the proper point in the sequence so that the trigger source is Timer 1 overflow again after the last conversion. The sequence counter will also be necessary to determine which channel is being read from and which channel to set up for the next conversion.

Step 3 there will require a significant amount of thinking on your part to work out exactly how to juggle setting the trigger source so it is set back to Timer 1 at the right point in the sequence. You also have to take into account that in free-running mode the next conversion is already running, so even after you set the multiplexer in the ISR the next trigger will be for the old MUX settings. It's not super hard to work this out, but you will need to put your thinking cap on.

Do you mean "three analog readings from each of three different pins" (9 total readings) or "one analog reading from each of three different pins" (3 total readings)?

You can read one full-resolution ADC reading in just over 0.1 milliseconds so three total readings would be no problem but 9 would be a little tight.

Hi Jiggy-Ninja!

  1. I might need to sample quite often so interrupts is the best way for me to achieve it
  2. Yes the measurements need to be taken in close temporal proximity as i need to detect if there is a drop of voltage(to 0) immediately

Do you mean i should trigger the ADC by setting a flag in Timer1 so that when the timer overflows, the flag turns 1, and bitset the ADSC?

I'll take note on Step 3 and look through it, thanks for your help!

Hi John!
I meant by one analog reading from each of three different pins (3 total readings), sorry for my poor english though.

"Quite often" is not precise. Exactly how often are you trying to measure each signal?

What are you measuring? If the signals are fairly independent of each other, there's probably no need to read all of them at once. Reading them one at a time at an interval might be good enough, and is probably easier to handle.

As for your other question, go to section 23.9.4 in the datasheet I linked to. The ADTS bits of the ADCSRB register allow you to set the auto-trigger source for the ADC. If you set it to autotrigger, the ADC will automatically start when one of those trigger sources happens. You won't have to do anything to manually start it, you just need to set of the ADC conversion interrupt to handle the result once it's finished.

Hi, @arduinouser1111

What model Arduino are you using?

What is the project?
Why within 1ms?

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.