Thanks for chasing these ADC improvements. Even with things as-are the ADC is mighty useful
What are your thoughts as to integrating capacitor reduction, still thinking 7/8 reduction? Or is that not required, now
Reducing the integrator cap will help the ADC not muddle up high-frequency inputs. There should be no detrimental effect, other than you'll need to run the ADC at 8MHz+, instead of 1MHz+.
Reducing the cap could allow frequencies near sysclock to be detected more readily. These will alias into our filter's passband.
We might be able to compensate for the loss at higher frequencies with a pre-emphasis circuit or similar. I would prefer to need pre-emphasis for a video input instead of needing bypass caps on typical analog inputs to keep out the RF.
Was it decided that it would not cause loss of linearity?
What about having 1 or 2 ADCs with the reduced capacitance?
Thanks for chasing these ADC improvements. Even with things as-are the ADC is mighty useful
What are your thoughts as to integrating capacitor reduction, still thinking 7/8 reduction? Or is that not required, now
Reducing the integrator cap will help the ADC not muddle up high-frequency inputs. There should be no detrimental effect, other than you'll need to run the ADC at 8MHz+, instead of 1MHz+.
Reducing the cap could allow frequencies near sysclock to be detected more readily. These will alias into our filter's passband.
We might be able to compensate for the loss at higher frequencies with a pre-emphasis circuit or similar. I would prefer to need pre-emphasis for a video input instead of needing bypass caps on typical analog inputs to keep out the RF.
Was it decided that it would not cause loss of linearity?
What about having 1 or 2 ADCs with the reduced capacitance?
It would not cause loss of linearity. It needs to be a global change if we do it.
We can get 12/11/10/8 bits from the four CMA window functions or 11/10/9/8 with Tukey/Tukey/Hann/Blackman, with >8 at almost no extra logic cost. Last night the problem was Sinc3 not providing a stable 16-bit output. Choosing the longest CMA, 12-bit values could be read every ~52 clocks with partial overlapping*. These could be input to a software binomial filter [1,4,6,4,1] to produce a 16-bit output every ~260 clocks.
* The plateau value of the new CMA67 would be 81 without tweaking the algorithm, as Saucy has noticed, but then it won't sum to 4096 or anywhere close so 80 was chosen. The overlapped ramps would sum to 81, which means weighting would not be exactly equal. There are alternatives now from Saucy that I need to study.
I think that the thrice integrated method will always be more efficient than trying to operate in multiple stages. Proof:
Assuming x <= y <= z , all are positive non-zero integers.
The impulse response of cmafilter(x,y,z) is (x+y+z-2) steps long.
The shift register length needs to be (x+y+z+1) bits.
Implementing a 3 stage filter would need (3*x + 2*y + z ) bits.
3x+2y+z > x+y+z+1
This is if we have to account for the memory used. If we used the LUT as a FIFO, we should be able to generate a 16 bit rolling average efficiently.
What's the maximum length of shift register we can have? If we extend it to ~256 bits, the 16 bit samples could happen. Note that if sinc3 is decimated by 256, the actual impulse response length is 766 steps, and we would need a shift register of 769 bits. Does it truly only take 256 clocks to generate an independent 12 bit sample?
I think that the thrice integrated method will always be more efficient than trying to operate in multiple stages. Proof:
Assuming x <= y <= z , all are positive non-zero integers.
The impulse response of cmafilter(x,y,z) is (x+y+z-2) steps long.
The shift register length needs to be (x+y+z+1) bits.
Implementing a 3 stage filter would need (3*x + 2*y + z ) bits.
3x+2y+z > x+y+z+1
This is if we have to account for the memory used. If we used the LUT as a FIFO, we should be able to generate a 16 bit rolling average efficiently.
What's the maximum length of shift register we can have? If we extend it to ~256 bits, the 16 bit samples could happen. Note that if sinc3 is decimated by 256, the actual impulse response length is 766 steps, and we would need a shift register of 769 bits. Does it truly only take 256 clocks to generate an independent 12 bit sample?
There are 3x32 + 1x16 = 112 register bits in each smart pin and allowing for other things max shift register length = 70 including a zero at either end. A CMA67 would need 69, leaving one spare as an extra config bit perhaps.
The existing CMA78 with length 80 won't fit without stealing the trigger bits, which is why I've been striving to get a CMA to fit into 70 bits.
We can get 12/11/10/8 bits from the four CMA window functions or 11/10/9/8 with Tukey/Tukey/Hann/Blackman, with >8 at almost no extra logic cost. Last night the problem was Sinc3 not providing a stable 16-bit output. Choosing the longest CMA, 12-bit values could be read every ~52 clocks with partial overlapping*. These could be input to a software binomial filter [1,4,6,4,1] to produce a 16-bit output every ~260 clocks.
* The plateau value of the new CMA67 would be 81 without tweaking the algorithm, as Saucy has noticed, but then it won't sum to 4096 or anywhere close so 80 was chosen. The overlapped ramps would sum to 81, which means weighting would not be exactly equal. There are alternatives now from Saucy that I need to study.
The too-big-to-fit CMA78 could be used for testing a [1,4,6,4,1] filter, in which case a sample every 64 clocks would have equal bit weighting.
After a lot of experimenting and testing, I'm giving up on the live 16-bit and 12-bit sampling. If >8 bit sampling is wanted, the Sinc3 filter does a vastly superior job of filtering, with the caveat that you only get a sample every Nth clock, instead of on every clock.
This chasing a 'sample every clock' is a nice theoretical exercise, but does it actually 'fit' a P2, given the Analog bandwidth is so much lower than the SysCLK ?
If you relaxed the 'sample every clock' dictate, could the logic impact shrink a significant amount ?
After a lot of experimenting and testing, I'm giving up on the live 16-bit and 12-bit sampling. If >8 bit sampling is wanted, the Sinc3 filter does a vastly superior job of filtering, with the caveat that you only get a sample every Nth clock, instead of on every clock.
This chasing a 'sample every clock' is a nice theoretical exercise, but does it actually 'fit' a P2, given the Analog bandwidth is so much lower than the SysCLK ?
If you relaxed the 'sample every clock' dictate, could the logic impact shrink a significant amount ?
It makes sense to me to sample near the analog bandwidth, but if I am running the prop at a super low sysclk to save power then mightn't the sample-per-clock be about right?
It makes sense to me to sample near the analog bandwidth, but if I am running the prop at a super low sysclk to save power then mightn't the sample-per-clock be about right?
The Nyquist guys would say sample at 2x Analog BW, but scope users might prefer 4~8 samples per sine wave. Note that's still well under the P2 SysCLK ability : 10MHz BW has 20 samples at 200MHz.
P2 is not really a low power device, and the ADC will not actually run at super low sysclk (eg RCSLOW), so you will need to flip-speeds for ADC readings anyways.
I figured out how to target an arbitrary sum value, as long as it's not prime. Hint: the product of the lengths is the sum of the full-scale value.
Re CMAx window function names, I think that my idea of ignoring the leading and trailing zeroes for x was not good. Anyway, CMA(x,y,z) would be better as different x,y,z windows can have the same length. It would be great if we had a BASIC program that could use x,y,z as inputs and generate the same outputs as the current version.
CMA(16,16,32) is a possible option. It has a max value of 256, sum of 8192 (x*y*z), length including the two zeroes of 64 (x+y+z) and needs only six distinct taps. The window overlap is 32 for equal bit weighting.
I have to admit that, after doubting whether this thread is even a worthwhile effort, I'm still confused about what these filters are being applied to. I assume (correctly?) that there are counters that tally the number of one bits from the integrator feedback and that the filter coefficients are being applied to the counts. But where are these counters positioned in the bitstream? IOW, by how many bits is each delayed? Even though I have disparaged this effort multiple times, I would still like to understand it better. Can someone provide a simple block diagram that illustrates the mechanism being discussed?
Today at Parallax, I had some time to work on the filters. So, I went to download SmallBASIC and all that came up was some giant managed-experience Microsoft pig by the same name. I couldn't find the nice little SmallBASIC that I use in Red Bluff. Does anyone have a recommendation for something that is simple and doesn't need an installer?
Today at Parallax, I had some time to work on the filters. So, I went to download SmallBASIC and all that came up was some giant managed-experience Microsoft pig by the same name. I couldn't find the nice little SmallBASIC that I use in Red Bluff. Does anyone have a recommendation for something that is simple and doesn't need an installer?
Today at Parallax, I had some time to work on the filters. So, I went to download SmallBASIC and all that came up was some giant managed-experience Microsoft pig by the same name. I couldn't find the nice little SmallBASIC that I use in Red Bluff. Does anyone have a recommendation for something that is simple and doesn't need an installer?
There are 3x32 + 1x16 = 112 register bits in each smart pin and allowing for other things max shift register length = 70 including a zero at either end. A CMA67 would need 69, leaving one spare as an extra config bit perhaps.
The existing CMA78 with length 80 won't fit without stealing the trigger bits, which is why I've been striving to get a CMA to fit into 70 bits.
It makes sense to me to sample near the analog bandwidth, but if I am running the prop at a super low sysclk to save power then mightn't the sample-per-clock be about right?
The Nyquist guys would say sample at 2x Analog BW, but scope users might prefer 4~8 samples per sine wave. Note that's still well under the P2 SysCLK ability : 10MHz BW has 20 samples at 200MHz.
P2 is not really a low power device, and the ADC will not actually run at super low sysclk (eg RCSLOW), so you will need to flip-speeds for ADC readings anyways.
There's probably not much use for processing ADC data at sysclock rate. The real benefit is being able to read a sample whenever. The streamer collects data at a rate specified by a numerically controlled oscillator. So our sampling rate is controlled by an NCO, we should be able to phase lock it to external inputs. What other microcontroller can do that?
Got what I think is the sinc3 function working in SimpleIDE and Visual Studio, so I can run some simulated bitstreams. The function "sinc3" performs a [1,2,1] convolution and decimation by 2 three times so that for a 32 bit stream the output will be 4 bytes packed at Fs/8. Because carry propagation is not yet implemented the left most byte in not valid, but the center two are … hopefully. Oldest bit is presumed to be in bit 31 of the input and the most recent is in bit0. Output is in "Register 5" packed four bytes to a 32 bit word.
Re CMAx window function names, I think that my idea of ignoring the leading and trailing zeroes for x was not good. Anyway, CMA(x,y,z) would be better as different x,y,z windows can have the same length. It would be great if we had a BASIC program that could use x,y,z as inputs and generate the same outputs as the current version.
CMA(16,16,32) is a possible option. It has a max value of 256, sum of 8192 (x*y*z), length including the two zeroes of 64 (x+y+z) and needs only six taps. The window overlap is 32 for equal bit weighting.
I have written the BASIC program mentioned and posted it below. Having chosen a desired sum, find three factors x,y,z such that sum = x*y*z. How do x, y and z relate to the window shape? If x<=y and x+y<=z, then x is the changing slope length, y-x is the constant slope length and z-y-x is the length of the plateau. The latter two exclude the start or start and end points, respectively. One or both can be zero, therefore the number of different taps is 4, 6 or 8.
Note that the integrator sums are not scaled because I wanted to see the actual values. x=16, y=16 and z=32 could be tried as an example.
'window parameters
'a = 4: b = 0: c = 0
'a = 4: b = 8: c = 0
'a = 8: b = 0: c = 0
'a = 8: b = 16: c = 0
'a = 8: b = 48: c = 0
'convert a,b,c to x,y,z
x = a
y = a + c
z = 2 * a + b + c
'input parameters
'choose sum and find three factors x,y,z where x<=y=z and x+y<=z
xyz:
input "x,y,z? ", x, y, z: if x > y or y > z or x + y> z then goto xyz
'x = 8: y = 10: z = 51
'convert x,y,z to a,b,c
a = x
c = y - x
b = z - y - x
length = x + y + z 'includes leading and trailing zeroes
sum = x * y * z
'sum clamp value m
m = 1
mx2:
m = m * 2: if m < sum then goto mx2
'taps
t0 = 0 ' start of upslope increasing
t1 = t0 + a 'start of upslope constant
t2 = t1 + c 'start of upslope decreasing
t3 = t2 + a 'start of plateau
t4 = t3 + b 'start of downslope increasing
t5 = t4 + a 'start of downslope constant
t6 = t5 + c 'start of downslope decreasing
t7 = t6 + a 'end
topbit = t7
'for x = 1 to 35: print : next x
print " x", " y", " z", "length", " sum": print x, y, z, length, sum: print
print "taps": print t0, t1, t2, t3, t4, t5, t6, t7: print
dim t(topbit)
for x = 0 to topbit: t(x) = 0: next x 'clear bits
inta = 0
intb = 0
intc = 0
'print "iter", "adc", "delt", "inta", "intb", "intc", "samp", "clam"
print "iter", "adc", "d2w", "dw", " w", "intw", "samp", "clam"
'for iter = 0 to topbit * 2 + 1
for iter = 1 to topbit * 2
for x = topbit to 1 step -1: t(x) = t(x - 1): next x 'shift bits
if iter <= topbit then t(0) = 1 else t(0) = 0 'new adc bit
't(0) = 1 - t(1)
't(0) = int(rnd + 0.5)
delt = t(t0) - t(t1) - t(t2) + t(t3) - t(t4) + t(t5) + t(t6) - t(t7) 'd2w
inta = inta + delt 'dw
intb = intb + inta 'w
intc = intc + intb 'intw
clam = int(intc / m)
samp = int(intc / (m / 256)) - clam
print iter, t(0), delt, inta, intb, intc, samp, clam
next iter
I have to admit that, after doubting whether this thread is even a worthwhile effort, I'm still confused about what these filters are being applied to. I assume (correctly?) that there are counters that tally the number of one bits from the integrator feedback and that the filter coefficients are being applied to the counts. But where are these counters positioned in the bitstream? IOW, by how many bits is each delayed? Even though I have disparaged this effort multiple times, I would still like to understand it better. Can someone provide a simple block diagram that illustrates the mechanism being discussed?
Thanks,
-Phil
The window filters are designed for a new smart pin scope mode and generate an output with eight or more bits every clock. There could be four windows of different lengths up to 70 bits and the longer the window the greater the output size. For the window below, an ADC bit is shifted in from the left and the other bits shifted right every clock, therefore it takes 64 clocks for each bit to pass all the way through. As it does so, it is multiplied by the corresponding window value and the resulting sum is the filter output. In order to perform this calculation in hardware, the logic does the same algorithm as the BASIC program posted above, namely a triple-integration of the second derivative, which at a given instant is a function of only eight different shift register bits at most and probably fewer. Amazing!
Okay, I don't believe in magic. If you're basing a computation on 64 shifted bits, you're only going to get six bits of resolution. I don't care what kind of filtering/massaging you apply to it, you won't get more. What am I missing here?
Okay, I don't believe in magic. If you're basing a computation on 64 shifted bits, you're only going to get six bits of resolution. I don't care what kind of filtering/massaging you apply to it, you won't get more. What am I missing here?
-Phil
You're missing the magic. We get more than 8 bits. It's because the bits at the plateau are worth more than '1'. They are worth maybe 8. And we use magic to compute them. It's true.
I think the maths is, even for a single sample, all about overlapping summation of the 1-bits. The central 1s are given the most overlap with others, so represent the strongest component in the signal.
This works best when the window is a progressive moving slide that gives each bit-time a moment at the peak of filter.
Phil, look at this picture. This is a 70-tap Tukey filter (only 70 bits in the whole chain) being used to digitize a rail-to-rail sine wave to 8-bit quality. This is a detail from the apex, being played back at 8x on a DAC, so that you can see the LSB steps in the 8-bit ADC samples. I think the Tukey filter generated an 11-bit value, so the three LSBs were ignored to give an 8-bit sample:
So, you can see the reality of more than 8-bit quality with only 70 sample bits.
It has same advantage as interlaced TV transmissions. Function is not easy to visualise due to the shifting nature of the content but the end result is way better than non-interlaced for a given bandwidth.
And a higher bandwidth display can de-interlace and produce amazing results. Whereas doing that at production time is always a downgrade to the signal.
Okay, I don't believe in magic. If you're basing a computation on 64 shifted bits, you're only going to get six bits of resolution. I don't care what kind of filtering/massaging you apply to it, you won't get more. What am I missing here?
There is no 'free lunch', as these filters have a finite delay and a settling time too. ie you do not get 6 or 8 completely new bits every sysclk, nor can you follow a 0-100% step in 1 sysclk..
A good test is to feed in a staircase, and check the delay & settling times of each step.
The operations we can perform on signals include integration and differentiation. They are complementary operations that counteract the effects of one another, in the same fashion as addition and subtraction as well as multiplication and division. If we differentiate a signal, then integrate it, we are back to where we started. FIR filters are often implemented using convolution. We can differentiate the filter, do the convolution, and integrate to get the same result.
Z^-1 is a delay by one clock.
Why would we want to modify the filter like this? See what happens as we take derivatives of the filter impulse response.
From top to bottom: Filter impulse response, 1st derivative, 2nd derivative, 3rd derivative, 4th derivative. As we continue to take derivatives, the apparent complexity of the filter decreases, for a while. At the 4th derivative we have gone too far. It has 8 non-zero values compared to 4 from the 3rd derivative. We are designing filters that have a response that we like while also having a sparse representation in the 3rd derivative. It doesn't have to be the 3rd derivative. Some of the Tukey filters we did previously were more efficiently calculated using the 2nd derivative. A sinc4 filter would be most efficiently implemented using the 4th derivative. Note that we are neglecting the complexity of the integrators here.
Okay, I don't believe in magic. If you're basing a computation on 64 shifted bits, you're only going to get six bits of resolution. I don't care what kind of filtering/massaging you apply to it, you won't get more. What am I missing here?
-Phil
That's a good assumption IF the noise is uniform. But a Delta-Sigma ADC is designed to shift the quantization noise to higher frequencies. The P2 seems to generate a lot noise between .15 and .2 fs. That's about a 6 bit repeating sequence. The filters we designed are able to provide better rejection of this high frequency noise than a simple moving average. https://beis.de/Elektronik/DeltaSigma/DeltaSigma.html
Omigosh. I can't believe this whole thread has been based on the fiction that you can make a silk purse from a sow's ear! If you're counting bits in a 64-bit window, it doesn't matter how you weight them, you simply cannot get more than an honest six-bit resolution from that window. Granted, you'll get a zillion more different values, depending upon how those 1's and 0's are distributed and weighted. But they don't mean anything as far as what a legitimate 8-, 12-, or 16-bit value would be at any point in time. That data is lost with every bit that disappears from the end of the shift register. I'm sorry, but the math (i.e. information theory) doesn't support the premise of this thread, and I really think -- actually know -- that you guys are deluding yourselves. The output from the filter might look pretty, but it's totally meaningless.
Comments
Reducing the cap could allow frequencies near sysclock to be detected more readily. These will alias into our filter's passband.
We might be able to compensate for the loss at higher frequencies with a pre-emphasis circuit or similar. I would prefer to need pre-emphasis for a video input instead of needing bypass caps on typical analog inputs to keep out the RF.
Was it decided that it would not cause loss of linearity?
What about having 1 or 2 ADCs with the reduced capacitance?
It would not cause loss of linearity. It needs to be a global change if we do it.
* The plateau value of the new CMA67 would be 81 without tweaking the algorithm, as Saucy has noticed, but then it won't sum to 4096 or anywhere close so 80 was chosen. The overlapped ramps would sum to 81, which means weighting would not be exactly equal. There are alternatives now from Saucy that I need to study.
Assuming x <= y <= z , all are positive non-zero integers.
The impulse response of cmafilter(x,y,z) is (x+y+z-2) steps long.
The shift register length needs to be (x+y+z+1) bits.
Implementing a 3 stage filter would need (3*x + 2*y + z ) bits.
3x+2y+z > x+y+z+1
This is if we have to account for the memory used. If we used the LUT as a FIFO, we should be able to generate a 16 bit rolling average efficiently.
What's the maximum length of shift register we can have? If we extend it to ~256 bits, the 16 bit samples could happen. Note that if sinc3 is decimated by 256, the actual impulse response length is 766 steps, and we would need a shift register of 769 bits. Does it truly only take 256 clocks to generate an independent 12 bit sample?
There are 3x32 + 1x16 = 112 register bits in each smart pin and allowing for other things max shift register length = 70 including a zero at either end. A CMA67 would need 69, leaving one spare as an extra config bit perhaps.
The existing CMA78 with length 80 won't fit without stealing the trigger bits, which is why I've been striving to get a CMA to fit into 70 bits.
The too-big-to-fit CMA78 could be used for testing a [1,4,6,4,1] filter, in which case a sample every 64 clocks would have equal bit weighting.
This chasing a 'sample every clock' is a nice theoretical exercise, but does it actually 'fit' a P2, given the Analog bandwidth is so much lower than the SysCLK ?
If you relaxed the 'sample every clock' dictate, could the logic impact shrink a significant amount ?
It makes sense to me to sample near the analog bandwidth, but if I am running the prop at a super low sysclk to save power then mightn't the sample-per-clock be about right?
thanks,
Jonathan
P2 is not really a low power device, and the ADC will not actually run at super low sysclk (eg RCSLOW), so you will need to flip-speeds for ADC readings anyways.
Re CMAx window function names, I think that my idea of ignoring the leading and trailing zeroes for x was not good. Anyway, CMA(x,y,z) would be better as different x,y,z windows can have the same length. It would be great if we had a BASIC program that could use x,y,z as inputs and generate the same outputs as the current version.
CMA(16,16,32) is a possible option. It has a max value of 256, sum of 8192 (x*y*z), length including the two zeroes of 64 (x+y+z) and needs only six distinct taps. The window overlap is 32 for equal bit weighting.
Thanks,
-Phil
https://smallbasic-publicwebsite.azurewebsites.net/
Maybe it was this one ? 4.4MB download ?
https://sourceforge.net/projects/smallbasic/
and there is always https://www.freebasic.net/ ?
Bob, that's the bloatfest I was talking about from Microsoft.
Jmg, the first one is it. Thanks for the link. I feel reileved.
Chip,
It looked small by MS standards LOL however I looked at the https://sourceforge.net/projects/smallbasic/ version that Jmg posted and I see what you mean. It's real small.
It's not just small, but simple and direct. Source lives in a single text file.
There's probably not much use for processing ADC data at sysclock rate. The real benefit is being able to read a sample whenever. The streamer collects data at a rate specified by a numerically controlled oscillator. So our sampling rate is controlled by an NCO, we should be able to phase lock it to external inputs. What other microcontroller can do that?
I have written the BASIC program mentioned and posted it below. Having chosen a desired sum, find three factors x,y,z such that sum = x*y*z. How do x, y and z relate to the window shape? If x<=y and x+y<=z, then x is the changing slope length, y-x is the constant slope length and z-y-x is the length of the plateau. The latter two exclude the start or start and end points, respectively. One or both can be zero, therefore the number of different taps is 4, 6 or 8.
Note that the integrator sums are not scaled because I wanted to see the actual values. x=16, y=16 and z=32 could be tried as an example.
This webpage might help with factoring:
https://www.calculatorsoup.com/calculators/math/factors.php
The window filters are designed for a new smart pin scope mode and generate an output with eight or more bits every clock. There could be four windows of different lengths up to 70 bits and the longer the window the greater the output size. For the window below, an ADC bit is shifted in from the left and the other bits shifted right every clock, therefore it takes 64 clocks for each bit to pass all the way through. As it does so, it is multiplied by the corresponding window value and the resulting sum is the filter output. In order to perform this calculation in hardware, the logic does the same algorithm as the BASIC program posted above, namely a triple-integration of the second derivative, which at a given instant is a function of only eight different shift register bits at most and probably fewer. Amazing!
-Phil
You're missing the magic. We get more than 8 bits. It's because the bits at the plateau are worth more than '1'. They are worth maybe 8. And we use magic to compute them. It's true.
This works best when the window is a progressive moving slide that gives each bit-time a moment at the peak of filter.
So, you can see the reality of more than 8-bit quality with only 70 sample bits.
And a higher bandwidth display can de-interlace and produce amazing results. Whereas doing that at production time is always a downgrade to the signal.
A good test is to feed in a staircase, and check the delay & settling times of each step.
Z^-1 is a delay by one clock.
Why would we want to modify the filter like this? See what happens as we take derivatives of the filter impulse response.
From top to bottom: Filter impulse response, 1st derivative, 2nd derivative, 3rd derivative, 4th derivative. As we continue to take derivatives, the apparent complexity of the filter decreases, for a while. At the 4th derivative we have gone too far. It has 8 non-zero values compared to 4 from the 3rd derivative. We are designing filters that have a response that we like while also having a sparse representation in the 3rd derivative. It doesn't have to be the 3rd derivative. Some of the Tukey filters we did previously were more efficiently calculated using the 2nd derivative. A sinc4 filter would be most efficiently implemented using the 4th derivative. Note that we are neglecting the complexity of the integrators here.
That's a good assumption IF the noise is uniform. But a Delta-Sigma ADC is designed to shift the quantization noise to higher frequencies. The P2 seems to generate a lot noise between .15 and .2 fs. That's about a 6 bit repeating sequence. The filters we designed are able to provide better rejection of this high frequency noise than a simple moving average. https://beis.de/Elektronik/DeltaSigma/DeltaSigma.html
-Phil