# Does the arduino (ATMEGA328P) ADC really only sample periodically?

I have been experimenting with the Arduino's ADC, and I have noticed some bizarre behaviour. I am wondering if it is normal, or if this is something specific (and bad) about the Atmel ATMEGA328P that the Uno is based around.

Basically, it would appear that the input value on the ADC is sampled at a lower rate than the ADC is actually returning values for:

In this image you can see the sampled input running at full speed connected to a simple pot. As the pot is swept from full to minimum the input voltage drops. As you can see the returned values from the ADC come in steps, where it returns the same (or similar) value for multiple calls to analogRead(), before then dropping down sharply.

What is actually going on here? Is the ADC input running at a different speed to the data output? Is the Arduino code reading the ADC wrong?

I have tried playing with the ADC pre-scaler, and no matter what I set it to (apart from 1:2 or 1:4, where it dies completely) it reads in steps like this.

Edit

• Also see related but not identical SE query here Oct 14, 2011 at 1:40
• Answer: No it doesn't. It's (as usual) my code. But hey - it was late, and I was tired - in the cold light of morning I instantly knew what the problem was. Oct 14, 2011 at 8:57
• @Majenko Don't forget to post your comment as an answer when you can and accept it! Oct 15, 2011 at 11:07
• @Majenko, write an answer explaining the error so others can find the problem and resolution. Feb 8, 2012 at 11:50
• adc's take time to settle and capture in general, this is not an instantaneous thing. need to understand what method they are using to do the conversion. Also, how are you going back to analog? What if you just store a bunch of samples in memory then dump them out later and graph them, eliminate the dac performance hit as well as code hit. Feb 8, 2012 at 14:56

DAC error? : You say the scope trace is displaying the Arduino's ADC input values BUT you are apparently displaying an analog signal. I assume there is a DAC of some sort in the process to convert the ADC readings back to analog.
The trace gives the appearance of a DAC with a massive error in a mid level bit. eg address bit A2 of the DAC may have a resistor value that is say 10 times too small.

Test: Turn the pot VERY slowly, do the gross steps vanish?
ie do you get a smoothly descending level.
If the level steps down like that at any sweep speed you probably have a bit based error post ADC.
Or, just possibly a microcontroller with a bit error in the IC's DAC hardware (less likely) .

ADC speed: Failing the above -

General web feel is that you can do better than what you are seeing.
If that pot sweep is in say 0.1 second then your gross step rate is about 10 mS.
HOWEVER- there seem to be small declining steps on your waveform - perhaops 10 per gross step, for a ministep of say 1 mS.
Even that is longer than you'd reasonably expect.

This discussion suggests 10's f kHz. - 77 kHz is mentioned.

Arduino based scope gives an idea of speed expected.

Energy monitor using ADC again, a guide.

Useful

• I have slept on my problem and think I have come up with the answer. The problem is with my software not with the ADC. The image is drawn by the Arduino and will be blocking waiting for the video device to draw the frame. I should have thought of that last night, since I designed the video device. It was late though... Oct 14, 2011 at 8:10

The reason for the inability to read the ADC smoothly is because of how I was displaying.

It's been three years since I asked this question (how time flies) and I just recently rediscovered it after someone upvoted it, so I have to try and remember all about it now...

Basically I was reading the ADC regularly, but the display output was being done through either PAL or VGA (I can't remember which now) to a TFT screen. Of course, with it being late at night at the time, I forgot that drawing a frame if the display takes time, and that during that time it can't be sampling the ADC - hence the steps.

Lesson learned: sleeping on a problem makes the answer obvious.

There is one ADC and 6 inputs, it samples each input 3 times (i think) then moves to the next input and so on.