-
-
Notifications
You must be signed in to change notification settings - Fork 0
Oversampling & Decimation
(original content here and here )
In oversampling, instead of taking the bare minimum number of samples you need you take extra samples and average them together. But as was demonstrated, this only works if you’ve got enough noise in the system already. If you don’t, you can actually make your output more accurate by adding noise on the input. That’s the counterintuitive bit. If you’re curious about oversampling.
At first bounce, the method appeared to be incredibly simple, to get n extra bits of resolution, you need to read the ADC four to the power of n times. Generally you have to add three extra bits (43= 128 samples) to see approximately an order of magnitude improvement in your real world resolution. With thermistor dividers, you typically get about 0.1°C from the default ADC readings, and 128 samples bumps that to 0.012°C. Taking (46= 4096) samples would bump that up to ~0.0015°C.
uint32_t extraBits=0; // use an unsigned integer or the bit shifting goes wonky
for (int k = 0; k< 255; k++) {
extraBits = extraBits +analogRead(AnalogInputPin);
}
which is then decimated by bit shifting right by n positions:
Oversampled ADC reading = (extraBits >> 4);
This combination lets you infer the sub-LSB information provided there is enough random noise in the signal for the lowest ADC bits to toggle up and down while you gather those readings. But without the noise, all of the original ADC readings are the same, and the oversampling technique does not work. To figure out how fast your ADC is running:
System clock / prescalar = ADC clock, ADC clock /13 = # of ADC reads/second
The core clock speed on 3.3v promini style boards is 8 MHz, providing:
8 MHz / 64 = 125 kHz /13 ticks = 9600 /sec (256 reads =27.6ms, 1024 =106ms, 4096 =426ms) (default)
8 MHz / 32 = 250 kHz /13 = 19230 /sec (256 reads = 13ms, 1024=53ms, 4096=200ms)
8 MHz / 16 = 500 kHz /13 = 38000 /sec (256 reads = 6.7ms, 1024=27ms, 4096=108ms)
8 MHz / 8 = 1 MHz /13 = 76900 /sec (256 reads = 3.3ms, 1024=13ms, 4096=53ms)
more info see here.
Your sensors output must be stable while you gather these samples and this limits what kind of phenomenon you can measure. At the default ADC clock speed, trying to add six extra bits of resolution (46 = 4096 readings) means you can only capture about 2 samples per second. That’s pretty darned slow for data acquisition! In fact, it’s so pokey that some people implement ring-buffer schemes to provide access to an oversampled reading at any time, without having to grab a whole new set of samples. A neat trick if you are continuously monitoring a sensor that changes slowly, and you have enough memory to play with. Given the powers of 4 relationship between the different bit depths, it’s easy to see how you might hop-scotch through shorter 64 sample readings, and then combine those into a sort of rolling average version of a 256 sample reading if you don’t have quite enough ram for the full ring buffer approach.
// Note: Before calling this function, I change to the internal 1.1v aref and set the ADC prescalars
// but you can leave them at the defaults: see: https://www.gammon.com.au/adc for more details
volatile int adcReading;
volatile boolean adcDone;
boolean adcStarted;
unsigned int adc_read;
unsigned long asyncOversample(int readPin, int extraBits)
{
int i=0;int j=0;
int var=256; //default is 4bits worth of oversampling
if(extraBits == 5){var=1024;}
if(extraBits == 6){var=4096;} //I’ve only included three options here, but hopefully you see the pattern
unsigned long accumulatedReading = 0;
adc_read=analogRead(readPin); // a throw away reading to connect the ADC channel
//delete me: simply as spacer
pinMode(5, OUTPUT); digitalWrite(5, LOW); // set the pin you are toggling to OUTPUT!
//delete me: simply a spacer a spacer comment for blog layout
while(i < var){ // asynchronous ADC read from http://www.gammon.com.au/interrupts
if (adcDone)
{adcStarted = false; accumulatedReading += adcReading; adcDone = false;i++;}
if (!adcStarted)
{adcStarted = true; ADCSRA |= bit (ADSC) | bit (ADIE);}
PORTD ^= B00100000; // [XOR toggle](http://jeelabs.org/2010/08/27/flippin%E2%80%99-bits/) D5 w green LED & 30k limit resistor (see below for details)
} // end of while (i < var)
pinMode(5, INPUT);digitalWrite(5, LOW); //turn off the toggle pin
if(extraBits == 4){accumulatedReading=(accumulatedReading >> 4);} // Decimation step for 4 extra bits
if(extraBits == 5){accumulatedReading=(accumulatedReading >> 5);} // 5 bits
if(extraBits == 6){accumulatedReading=(accumulatedReading >> 6);} // 6 bits
return accumulatedReading;
} //end of asyncOversample function
ISR (ADC_vect) // ADC complete ISR needed for asyncOversample function
{ adcReading = ADCL | (ADCH << 8);adcDone = true; }
(more info here )
Read answers on Stackoverflow here
The 16-bit ADS1115 has a programmable amplifier at the front end, with the highest gain setting providing a range of +/- 0.256 v and a resolution of about 8 microvolts. Original article here
🟢 Fully tested and working
A green circle means the hardware electronics or the programming code was fully tested, each of its functionalities and capabilities. And it can be installed in a vehicle. Keep in mind this does not mean errors won't happen. As in everything related to electronics and software, there are revisions and updates. This open hardware is no different.
💯 Fully tested & working, no improvements necessary - already being sold online
🆓 Fully Open hardware \ source code
🤪 There's better than this. don't use it
🔐 Fully closed hardware \ source code
⚡️ fully tested and working, however, it is a dangerous solution to deploy
🟡 Not tested. Working capability is unknown, it may work or not.
A yellow circle means the hardware electronics or the programming code was not fully tested, each of its functionalities and capabilities. This does not mean it not working, it simply means testing is needed before giving a green circle of approval.
🔴 Fully tested but not working.
A red circle means the hardware electronics or the programming code was fully tested, and found some kind of critical error or fault. This means the electronics or firmware code cannot be used in a vehicle.
⌛ Not started.
The hourglass means the hardware electronics or the programming hasn't started. Most likely because is waiting for the necessary test components needed for reverse engineering and also engineering of the new open solution.
🆕 New updated contents
The new icon means the link next to it was recently updated with new contents
💬 Comments on the Discussion page
The comments icon means there are useful and even new comments on the discussions page of the repository important for what you are seeing or reading.
Join the beta program to test and debug to provide feedback, ideas, modifications, suggestions, and improvements. And in return, write your own article blog or post on social media about it. See participation conditions on the Wiki.
The Beta Participant Agreement is a legal document being executed between you and AeonLabs that outlines the conditions when participating in the Beta Program.
Bug reports and pull requests are welcome on any of AeonLabs repositories. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
- Contributing
Please make sure tests pass before committing, and add new tests for new additions.
You can get in touch with me on my LinkedIn Profile:
You can also follow my GitHub Profile to stay updated about my latest projects:
The PCB design Files I provide here for anyone to use are free. If you like this Smart Device or use it, please consider buying me a cup of coffee, a slice of pizza or a book to help me study, eat and think new PCB design files.
Make a donation on PayPal and get a TAX refund*.
Liked any of my PCB KiCad Designs? Help and Support my open work to all by becoming a GitHub sponsor.
Before proceeding to download any of AeonLabs software solutions for open-source development and/or PCB hardware electronics development make sure you are choosing the right license for your project. See AeonLabs Solutions for Open Hardware & Source Development for more information.