This is a long post and may contain some small inaccuracies, bear with it, but you really need to get the basics right before jumping into calculations. There is a lot to grok here. I think your solution is severely overengineered; nothing wrong here, I like to sometimes overengineer to learn more, but the risk here is that with such low-demanding use case, you won't see any difference in the final result: it will just work, regardless of what filter you use. For example, if you just accidentally wire input directly to output, completely bypassing the filter, the end result will very likely work just perfectly!
First, you need to understand the ADC requirements. Your typical SAR ADC has a tiny little DC leakage, which is in tens of megaohms; or you can think about it as a tiny bias current. This is usually negligible, and even unspecified, I'm just mentioning it for the sake of completeness.
More importantly, and this is the key, every time the ADC samples, the input signal is connected to the internal sampling capacitor for a very short time, called the sampling time. Of course, connecting the input signal to a capacitor suddenly, causes current only limited by the total resistance to flow. If you have almost zero resistance, a huge current flows, possibly causing multitude of problems (hence some amount of R is suggested by nctnico earlier). In the opposite case, if you have too much resistance, the sampling cap charges slowly; and because the sampling time is only so long, charging the cap remains unfinished when the sampling time is over.
High-speed ADCs typically require input impedances as low as 20-30 ohms, because the sampling time can be as short as some tens to hundreds nanoseconds. If the PIC ADC is specified at 10kOhms as you say, it means it must use a very long (relatively speaking) sampling time internally; it's likely in several microseconds, see the datasheet. This makes your life easier, you can live with some impedance.
Also note, the level of accuracy you require affects the input resistance you can tolerate. For example, assuming sampling capacitor of 20pF, and input resistance of 10kOhms, R*C = 0.2 µs. This means, after 0.2µs of sampling, the result would be 37% off. After 0.4µs, error is 13.5% After 0.6µs, error is 5%. After 1.0µs, error is 0.7%. Say, your sampling time is set to 1µs (by design of the ADC, or sometimes it's user-configurable). Is error of 0.7% acceptable? Sometimes 0.7% is more than good enough, hence 10k source resistance is just fine; sometimes 0.7% is abysmally poor result and you need something orders of magnitude better, hence use longer sampling time, or lower source impedance.
The giveaway is, you need to make a distinction between DC resistance and AC impedance. Adding a 100nF capacitor to the ADC input, like I suggested, very clearly satisfies the 10kOhm impedance requirement. Let's play with the impedance for a minute: for a typical ceramic capacitor (ESR = 20mOhms), mounted close (10nH stray) to the input pin, the impedance at the relevant frequency (inverse of the sampling time, 1µs for now) would be
Z = R_esr + L_esl + 1/(2*pi*f*C ) = 0.02ohms + 2*pi*1MHz*10nH + 1 / (2*pi*1MHz*100nF) = 0.02ohms + 0.06ohms + 1.5ohms
Four orders of magnitude less than your allowed maximum of 10kOhms! Clearly, this impedance constraint is satisfied with the capacitor alone; then we only need to think about how we charge that (externally added) capacitor.
But, it makes more sense to look this in the time domain in terms of current and charge, IMO, so let's get rid of the complex impedance equations:
Say, you have a 100nF input cap and a 20pF sampling cap. When the sampling occurs, in worst case, you transfer approx. 20p/100n = 0.02% of the charge from the input cap to the sampling cap. So the input cap voltage changes just by 0.02%. This is the error you will see in the result!
Now, the only requirement left is that the 100nF input caps needs to be able to replenish. This condition is relaxed when compared to not using input cap; with no input cap, the input signal needs to be able to fully charge the sampling cap during the sampling time; with the added input cap (Cin >> Csampl), the input signal still needs to supply the same amount of charge (it's only the ADC what's consuming it, after all), but has the whole time window between two samples to work with. For example, if sampling time is 1µs, and sampling rate is 1ksamples/second, the input signal has a massive 1ms time to charge the input capacitor, and that input capacitor takes over the job of charging the ADC sampling cap in just 1µs.
But, seeing the ADC is specified to work acceptably (by some arbitrary definition by the PIC datasheet writers) even with such a high input impedance as 10kOhms, you may not even need the input capacitor! You may actually need nothing at all.
But, I strongly recommend using the input capacitor for near-DC measurements. It's cheap (a BOM reuse, your bog standard 0402 power supply bypassing cap does fine), small, does good job at suppressing high-frequency noise at -6dB/oct, protects the input from ESD, and, allows you to use very large input resistances (up until the DC leakage / bias currents start to be a problem), say, 100kOhm to even 1MOhm is usually just fine, with only one condition: don't sample too often. This is the simplest and cheapest way to sense battery voltages, thermistors, and similar.
I rephrase the external input capacitor once more because I have seen it cause confusion: a capacitor that is much larger than the sampling cap (Cin >> Csampl) removes the sampling time from the equations, and replaces it with the sampling interval. The latter is typically at least an order of magnitude longer, often many.
So, the circuit reduces to something like a 10kOhm resistor for limiting current to protection diodes (internal for low-cost solution; external for added robustness; you may want to use two resistors in series, with the midpoint clamped with external protection diodes). This resistor does not cause any significant accuracy problem as you seem to think, as won't your 3k source resistance; the ADC input (with the 100nF input cap) consumes practically zero current, so no voltage drop is generated over those resistors (except when the clamp diodes are conducting due to overvoltage). The input impedance simply doesn't matter much; 10kOhm spec is already quite forgiving, and adding the input cap makes it matter even less (because now we are only interested in the average current the ADC consumes from the signal; not the peak current, which is handled by the input cap!)
---
On the other hand, if you want to look at this as a generic data acquisition system, you should start by specifying your requirements first.
Let's start with the required bandwidth. So, you are detecting key presses. Fine, what's the shortest keypress you want to reliably detect? Let's say 100ms. Say you want to debounce by detecting two consecutive settled values, so for that, the bandwidth should be enough to settle in less than 50ms. So, pass-band BW is in order of 20Hz, and at 20Hz, the amplitude should be close enough to detect the key correctly.
Then let's look at the accuracy of converted numbers. This is catch-all that should include voltage errors due to component tolerances, all noise, ADC resolution, nonlinearities, etc. Let's see your table of values to be detected:
Seek+ 20mV
Seek- 800mV
Vol+ 1440mV
Vol- 2320mV
NoPush 3240mV
Let's calculate the "dead bands" between these expected values:
Seek+ 20mV
(780mV)
Seek- 800mV
(640mV)
Vol+ 1440mV
(880mV)
Vol- 2320mV
(920mV)
NoPush 3240mV
Now let's assign valid ranges for detection, consuming half of these deadbands, leaving half of them to detect "illegal" values:
Seek+ from min_possible to 20mV+780mV/4
Seek- from 800mV-780mV/4 to 800mV+640mV/4
Vol+ from 1440mV-640mV/4 to 1440mV+880mV/4
Vol- from 2320mV-880mV/4 to 2320mV+920mV/4
NoPush from 3240mV-920mV/4 to max_possible
Now what's the maximum allowable total error (due to all combined sources of error)? The smallest margin is between Seek- and Vol+, 640mV, which we divided by 4 to leave forbidden values inbetween. The maximum allowed error is thus +/-160mV, which is +/-4.8% of the (assumed) 3.3V signal and ADC range.
Now, to add extra margin of safety, let's say we want +/-2% accuracy. This leads to the following conclusions:
* 6 bits is enough resolution (each LSB is 1/64 = 1.56% of full range)
* Signal-to-noise ratio needs to be 20*log10(2%) = -34dB
Now, do you need low-pass filtering? Your signal clearly doesn't have intentional interfering components, it's basically a DC level defined by the push buttons. So outside the BW, there is just noise. How much?
Now a key finding that they tell you in every signal processing 101 classroom is this, and this is true: analog filters become more expensive, larger, more costly, and more difficult (or impossible) to design taking component variations into account, the higher the order. This is why they tell you: use a simple/low-cost analog antialias filter, oversample, then implement a more steep (near to a brick-wall) filter in the digital domain. Of course, such complex way of thinking is not needed in your simple application, but the idea is the same. In your case, you won't need to implement a 512-tap FIR with a DSP, no, but you may want to look at the consecutive values in a loop to make sure you have steady values for 100ms, then react to the keypress. This basically is a digital low-pass filter tailored for the application.
I don't know about the sample rate of your PIC ADC, or the processing power you have available, but let's say you really want that 20Hz BW. For that, the minimum Nyquist-defined sample rate is 40smps. I'm quite sure the PIC is able to sample at 1ksmps and run a simple filter at that frequency; with that, we are already at 25x oversampling, NICE. Now, the analog filter needs to be designed with the following parameters:
Passband 0 .. 20 Hz
Transition region 20Hz..500Hz
Stopband 500Hz (half the sample rate)... inf
The digital filter takes care of the loong transition region of the cheap analog filter. Still, any signal over 500Hz will alias, and if you are unlucky, for example, a 10005Hz signal aliases as 5Hz. But do you have extremely strong signals over 500Hz? I don't think so, there is only noise, and noise emissions are regulated by law (for very good reasons).
So I propose using a first-order RC filter, because it's very low cost (< 1 cent), requires no power supply, has tiny PCB area (< 1mm^2 possible), ... and is more than good enough for such purpose - actually it's good enough for an order of magnitude more demanding use cases, such as measuring battery voltages to 0.5% accuracy at tens of Hz!
Let's say we use 22kOhm series resistance, plus 3kOhm source resistance (= total 25kOhm), and a 100nF capacitor.
Corner frequency (-3dB) is at 1/(2*pi * 25e3 ohm * 100e-9 F) = 64Hz
Settling time to 1.8% accuracy (remember we specified 2%) is 3*tau = 3*R*C = 7.5ms. No problem detecting short keypresses!
Attenuates noise (any unwanted signal) at 500Hz to 1/sqrt(1+(2*pi*500Hz*25e3Ohm*100e-9F)^2) = 12.6%
Attenuates noise (any unwanted signal) at 5000Hz to 1/sqrt(1+(2*pi*5000Hz*25e3Ohm*100e-9F)^2) = 1.2%
What's the worst possible case? We have a massive noise source at 501Hz singing somewhere, coupling into the wires. Now this would need to produce at least 1/12.6% * 160mV = 1.27V error signal so it would exceed our 160mV max error specification.
At 5000Hz, the error signal (say, 5001Hz so it would alias at 1Hz) would need to be 1/1.2% * 160mV = 13.3V so it would pass through the 1st order RC filter badly enough.
Connect a scope to your signal wires and measure what noise you see, while the car is running. I'm sure you won't see such huge noise sources. If you do, you likely need completely other ways of fixing and mitigating than increasing the order of analog LPF.
Finally, I think this pseudocode describes what you need:
#define BUT_ILLEGAL -1
#define BUT_SEEKP 0
#define BUT_SEEKM 1
#define BUT_VOLP 2
#define BUT_VOLM 3
#define BUT_NOPUSH 4
#define ADC_BITS 8
#define ADC_CNT(mv) ((256*mv)/3300)
//Seek+ from min_possible to 20mV+780mV/4
//Seek- from 800mV-780mV/4 to 800mV+640mV/4
//Vol+ from 1440mV-640mV/4 to 1440mV+880mV/4
//Vol- from 2320mV-880mV/4 to 2320mV+920mV/4
//NoPush from 3240mV-920mV/4 to max_possible
static const uint8_t mins[5] = {ADC_CNT(0), ADC_CNT(800-780/4), ... }; // generate tables according to the previous comment
static const uint8_t maxs[5] = {ADC_CNT(20+780/4), ...};
// run every 10ms or so:
uint8_t cur_adc = input_adc();
int8_t cur_op = BUT_ILLEGAL; // -1 = illegal
for(int i = 0; i<5; i++)
{
if(cur_adc > mins[i] && cur_adc < maxs[i])
{
cur_op = i;
break;
}
}
static int8_t prev_op = BUT_ILLEGAL;
static uint8_t stable_cnt = 0;
if(prev_op == cur_op)
{
stable_cnt++;
if(stable_cnt > 10)
{
button_is_actually_pressed(cur_op);
}
}
else
{
stable_cnt = 0;
}
prev_op = cur_op;
Hope this helps.