Understanding Low Pass Filter On Analog Input


New member
Hi everyone,
I've been doing a lot of reading of old posts and could use some validation of my conclusions/help choosing the correct part values. My background is software and my understanding of EE is very limited so I apologize if any of my questions seem silly.

Project overview:
- Teensy LC
- 4x 10k pots (2 joysticks)
- a bunch of buttons
- 1khz sampling rate
- powered by USB

In my initial iteration I simply connected the pots between the 3.3v and GND. The buttons were all configured to use the internal pullup resistor and shared GND traces with the pots. This produces usable readings but there is noise/jitter as well as interference/crosstalk from the digital signals. I want to decrease the noise as much as possible so that any remaining noise can be blamed on the pots/cost limitations. The analog reads are spaced at minimum 175us apart.

From what I've read some things that would help are:
1. adding a decoupling cap near each analog input which creates a low pass filter in combination with the pot (C1 & C2)
2. adding a resistor before the cap to create a minimum resistance for the low pass filter (R1 & R2)
3. Adding a bypass cap on the 3.3v (C3)

Below is a schematic of these additions
Filtered Schematic.png

By approximating the charge time = 5*R*C, at the maximum position of the pot (R=10k) and a max delay of 1ms (to satisfy 1khz polling rate) the decoupling caps should be 20nF? Most recommendations I have seen are for using a 0.1uF cap which introduces a significant delay. I don't 100% understand how the charge time relates to the sampling frequency tho... Is the cap fully discharged after each sample? Does the charge time apply for any change in voltage or only from 0V (i.e. do small changes have the same delay)?

I don't think #2 is necessary since I am only using the middle ~60% of the pots so the cutoff freq would range from ~4khz to ~1khz depending on position. I don't have access to a scope so I can't say what the frequency of the noise is but I would assume anything resulting from USB will be alot more than 4khz.

How would adding a series resistor affect the output voltage? Would it affect the linearity of the output?

Would #3 have any noticeable effect given that the source voltage technically doesn't matter when using non-absolute sensors? I think I would also need to connect the output of the cap to AREF which would be annoying having to use the inner pins.

Some of the other Teensys have a dedicated AGND which is connected to GND via a small inductor (I think). Is there anything I could do to recreate this/would it have any effect if the ADC is still using GND?

Other things I plan to change:
- Route the digital signals on opposite side of the pcb where possible
- Increase spacing between traces for analog signals
- Use separate GND pins for digital and analog signals (even tho they're connected)

Thanks in advance for any responses
> my understanding of EE is very limited

I encourage you to put the circuit into LTSpice and try a few things. You can simulate some noise and a step change in the joystick.

A trimmed mean in software is an easy way to reduce high frequency noise.
Is the cap fully discharged after each sample? Does the charge time apply for any change in voltage or only from 0V (i.e. do small changes have the same delay)?

No. The charge on a capacitor is C*V. When the ADC samples the signal it connects the analog input to the sampling capacitor.Typical a few pF. (See data sheet for the particular value for your device.)

You start with C1*V1 and end with V2 * (C1 + Ci). Where Ci is the sampling capacitance. Since charge is conserved, C1*V1 = V2 * (C1+Ci) This assumes that the sampling time is so short that current through the resistor can be ignored.

Select C1 so that V2 = V1 * C1/(C1+Ci) meets your needs. Perhaps you require less than 1/2lsb of error.

Sampling time is determined by the ESR of the capacitor. Sampling rate should be slow enough so that the charge sucked off to the sampling capacitor can be replaced before the next sample.
If there is a desire to have very fast (and accurate) response (1kHz sounds like these ultra-high rate joystick/mouse stuff), which requires the relatively high sampling rate, software averaging won't help if the ADC sample rate is already the same 1kHz (and the averaging adds a little bit of latency). It could be used with higher ADC sampling rate, in which case software post-averaging will reduce noise in certain frequency bands... but it still leaves other noise bands around; especially, ones that have aliased down on the band of interest.

Which brings the topic of "anti-alias filtering". Preferably filtering so that the RC attenuates everything already above Nyquist frequency (half the ADC sample rate), at least to some extent. Not necessarily an easy task with just a simple RC filter, but then again, in this use case it might not need to do a perfect job, either, just reduce the noises a bit.

Considering the above, you might try to both increase sample rate (which lets the RC-filter aimed at 1kHz do better job with noises above that 1kHz), then filter more in the software (using either sample averaging, or some better yet simple software filter) to reduce noises and to get the sample rate down to desired.

Note, the filter capacitor does not see just 10k pot in the "max case"; it will see the ~0 ohm other leg, too. Correspondingly for every position for the potentiometer, the opposite leg is still there, which leads to some interesting math near the center positions ... I suggest using the well known U=RI <=> I=U/R, drawing the potentiometer at 5k-5k position, and calculating what the currents will be if the middle point capacitor is hanging (due to previous position) at just 1% above the expected half of supply voltage, things trying to get it to that exact half supply.

#2 can help; If the wire between pot and analog input is longish (relatively speaking), it may pick up some noise, in which case the #2 can help, too. Its effect on the measurement accuracy should be negligible. But more importantly, the ground and supply wires to the pots should be routed near the analog input, and stick close to the signal wire all the way. Otherwise they will create a kind of loop which has larger area to pick up interference, and often the kinds of noises a simple RC filter won't help against at all.

#3 can help, especially if the supply line is noisy. It will give the noise "signal" from supply lines an easier path to flow (through the capacitor to opposite supply/ground, instead of going through the potentiometer to signal wire to filter etc.) Connecting the potentiometer's supply back to ADC system might not be needed, the currents are at such a low level that calibration should be able to handle it mostly. But, if you want to automatically account for possible changes in the supply, you don't need to connect it to AREF input; you can instead measure it with another ADC input, and make compensating changes to samples in software.. Not as accurate method of doing it, but often good enough. (Some chips also have internal selection to measure the chip's supply.)

Before trying to use split supply domains (separate AGND etc.) I'd try how it works with the simpler way. While the separate ground (and thus usually also more or less separate supply voltage) may help with accuracy and reduced noise, it has its own additional things to consider.
Thanks for the responses. I wanted to wait to reply till I had actually tried some of the suggestions and it took me a bit to come back to the project.

Anyways, I did try adding the bypass cap but it didn't make a difference. I realized that most of my noise is actually EMI from the digital signals since I didn't take any care to separate the analog and digital circuits (used Fusion 360's "autorouter" option). I redid all the traces to isolate the analog from the digital signals such that for the most part they are on opposite layers of the PCB and they don't cross over or run close to each other at all. I also did my best to do the same for the 3.3v and GND of the analog signals and used separate ground pins for the analog and digital sections (although they're connected to the same ground so idk if that will make any difference).

Hopefully that makes enough of a difference but if not I'll probably invest in a scope so I can actually measure the noise and evaluate the effectiveness of a any changes
I landed here with the intention to add and tune rc filters to analog input signals similar to the author of this thread.

What i ended up now is using a software filter solution based on the 1euro filter algorithm. It takes only two parameters to tune, which was quickly done in case of my recent application (reading hall sensors on manual input device). I might add hardware filtering in a future version, but this solution works very well so far.

Maybe someone else lands here like me and profits from this lib as well:

And a sublink with a comparison of the 1euro filter against other filter algorithms:
That style of dynamically adjusting filter may introduce distortion (as its not a linear time-invariant system). Sometimes that may matter, but not for the intended application, tracking movement.