Sharp Range Sensor I2C Adapter prototypes. |
Read on to see how I improved performance with oversampling and filtering.
This is what I was seeing before on both board designs using dedicated I2C ADCs.
Before: the full range is 10-bit (1024 lsb) |
Here's the new design with signal processing prototyped on a Tiny85, configured for 13-bit resolution and mild filtering.
After: the full resolution is 13-bit (8192 lsb) |
I'd say that's better, wouldn't you? The noise is 2 LSB, 2-bit out of 13-bit resolution through oversampling and filtering implemented with a so-called leaky integrator.
Signal bandwidth can keep up with me rapidly waving my hand back and forth in front of the sensor so bandwidth seems to be in the ball park.
Oversampling
Oversampling involves sampling a stable signal with a little bit of noise a bunch of times to arrive at a sort-of average, but with a higher resolution.Say you have a 10-bit ADC with a range of 0 to 210 and you want to oversample to add n=2 bits of resolution (12 bit total). To do that, you have to sample it 42 (16) times. If instead you wanted n=6 bits of additional resolution (16 bit total) you would oversample 46 (4096) times.
So you take your 4n samples, during which time the signal must remain stable, yet slightly noisy, and add them up. When you're done adding, you decimate, dividing by 2n (right shift by n). For 16 bit resolution, n=6, for 12 bit, n=2 assuming a 10-bit ADC.
Frequency of sampling is important. The Nyquist-Shannon theorem says that you have to sample a signal at greater than twice its frequency. Not surprisingly, when you oversample, you have to sample at 4n times the Nyquist frequency (where n is the number of added bits of resolution).
Put another way, the more you oversample at a given sampling frequency, the lower the bandwidth of your system. My ATtiny is programmed to sample at 125kHz, far above the Sharp sensor's bandwidth, so more oversampling is possible before we fall below the bandwidth of the sensor.
Leaky Integrator
In addition to the oversampling, I also wanted to implement some filtering. I turned to my old pal, the leaky integrator. It's fast and it works great.The idea is that you add up values while some amount of the total leaks out at each addition. It's a first order, recursive low pass filter that can be implemented with additions and shifts.
The higher the shift value, the lower the cutoff frequency and bandwidth. Here's the filter code:
#include <stdint.h>
#include "registers.h"
static uint32_t filtsum = 0; // running sum for filter
static uint8_t shift = 3; // leaky integrator filter shift
/** Leaky integrator filter */
uint16_t filter(uint16_t value) {
filtsum += (value - (filtsum >> shift));
return (filtsum >> shift);
}
GitHub RepositoryThe final version will be a similar size, with a SOIC MCU for reliable hand-assembly. I'm still deciding on the best connector.
Hi Michael! How is your progress with this awesomw thing?
ReplyDeleteI need to make something similar with Sharp sensors. Are your schematics and firmware sources published somewhere?