I know this is not a new idea, but I found that explanations of how to use oversampling with an Arduino were spread out in bits and pieces all over the web, and much of that material was really hard for a beginner to follow. As I slowly worked through it all, mostly by trial & error, I decided to gather what I could find into one place so others could give it a go.
If you are using a standard UNO, Qwerty's Triangular dither method works a treat, provided you give the circuit enough time to settle before you start taking samples.
With 3.3v 328p based boards, I prefer the pin-toggling noise method, as it seems to suffer from fewer synchrony issues when you speed up the ADC. But you might have to experiment to find the optimal pin-current for your board, as they all have different stabilizing capacitors, which are trying hard to fight against the noise you are generating.
In all cases I would say that the 'real' improvement in your sensor resolution with these methods is not quite as good as some people claim it is. When I looked at the data critically, it seemed to me that after 4-5 extra bits the technique offers diminishing returns. Though the resolution numbers kept increasing as I took more and more samples, the graphs did not look any smoother. There are probably good reasons for that, but I'm still a bit boggled by the math involved...
Anyway, it's a fun thing to try with resistance based sensors like thermistors, and it was big learning experience for me. I'd like to add a BIG thank-you here to N.G. as his asynchronous ADC reading code was crucial to making it all work.
You want to help everybody get started, but sometimes it's hard to know when it is worth the effort to make one of those long tutorial-style posts, and sometimes I miss the mark pretty badly. Judging from the traffic stats, my mum was about the only person who bothered to read the post I made on using the Arduino as a DAQ...and she didn't get much out of it
I have read carefully most of your post in your blog because you are one of the few guys that has testes your projects for years and gained a lot of experience.
As I wrote in a comment in your blog, I believe that maybe it's better to use another platform if you need better resolution.
STM32F103 cheap board are a good alternative using the STM32duino Arduino-like core. Maybe they need more power than an Atmega328.
There are lots of great mcu/platforms out there, and the engineers I know keep asking me why I'm not using pic's instead. And with the ADS1115 modules below $2.50 on eBay, it's always possible to buy better hardware for the job in one form or another.
But I'm still quite happy with Atmegas as you can easily go up to the 1284p in the Moteino Mega for more memory, or down the family to the ATtiny processors, with very few changes to my logger codebase. I also have to admit that I like the Arduino's for sentimental reasons, since it was the first prototyping platform I learned, and I could not have done that without the Arduino community.
The other thing that people often miss about our project is that we are not really trying to optimize things to the level of professionally designed equipment - what we are after is something that is generally capable, while still being easy for beginners to learn and modify on their own. Dithering & oversampling fits nicely into that approach.
You say "With such a low value shunt resistor the ADC seems to read fine even if you crank it up to about 40k samples/second. Unfortunately you pass a point of diminishing returns due to the processing overhead with the interrupt based asynchronous readings"
There is an alternative technique, whereby you just burst read the raw samples into RAM. It'll go even faster written in C rather than Arduino language. All processing is then performed later in batch, and the data sent serially at leisure. If your display updates twice a second, so what? That'll be like pressing the RUN/STOP button on the Rigol. Also you read at 8 bit resolution. Before you scoff, your Rigol only reads 8 bits as do most modern oscilloscopes. You only need 8 bits, because if you think about it, 8 bits gives a resolution of 1/256th of the available display area. A sine wave will appear fairly smooth at that resolution. That's less than 1 vertical pixel /sample on the world's best selling full bench oscilloscope (Rigol DS1052). When you change vertical scale, you resample.
You then process the data after storage. I can easily get 1k samples into an Uno's RAM. This is how a digital storage oscilloscope works. Following the oscilloscope analogy, you don't really need much raw vertical sensitivity. That can be accomplished with an elementary op amp.
I'd be interested in how fast you can crank the internal ADC to get -3dB readings from a low impedance source...
There are two principle reasons I don't use pics for anything.
They're hard to use. Because of that, they're unpopular. Because of that, there is little community support compared to the Arduino universe. There's probably nothin' that ain't bin done already with an Arduino. Assembler, C and reset indirection vectors???
They're very expensive. No not the chips, but the tools. Programmers, compilers, linkers and development boards. There's little free stuff out there that's compatible with popular pics.
If they were an amateur friendly platform, would'd we all be using them? Wouldn't schools? The devices are marketed at opposite ends of the spectrum. An Arduino just works. You then get it to do additional wonderful things as and when your skills improve. A pic can do everything, but does nothing at the start without a great deal of knowledge and experience. The BASIC STAMP was similar. It's like when you buy a gun for your kid. You'd get them a cheapo Remington rifle with which they can knock squirrels over. Or you get them an AR15 but they have to assemble it blindfolded first.
I believe in the market, and the market has said no.
Yes I saw a few Arduino Oscilloscopes out there taking 8bit readings from the ADC's free running mode an putting them into ram. And if I really wanted an optimized build I would probably use the 1284p Moteino for the extra memory room there. My logger sleep currents are so low that I need the extra 10 bit resolution at the low end of the range, or that data just goes to a bunch of zeros if I am also trying to catch the 50-100mA SD card writing spikes.
But I was just having fun, and for me the most important thing was being able to stretch the sampling time window ( via the oversampling loop at the Github example) as some of my data logger events have unpredictable SD housekeeping events in the middle of them that stretch the events past what I could display on the serial plotter without post processing. I'm sure it could all be done better, but I have to admit I really love using that plotter for quick reviews of 'events' in real time.