I have a fuel level sensor that varies its resistance from 9.5 ohm(empty) to 155ohm(full). The sensor is powered using 12V battery connected to a 30kVA Generator.

The problem is that the level that I get fluctuates,i.e, 47.57% for 30s and then 48.4 for 30s or so. The level is calculated using the equation level(%)=187.41 * V(adc port) - 7.38. The fuel level sensor forms a voltage divider with a 1.2k resistance. The voltage at the ADC pin does change but very little about +-1mV.

I have two more analog signals connected to ADC of 16f877a. The other two signals namely battery voltage and temperature are fairly stable.

I using 7805 to power up the controller circuit and a separate 7805 to power up the SIM900 module

• So what is the question? – Andy aka May 17 '16 at 7:39

The voltage difference needed to cause this difference in fuel level is (48.4-47-57)/187.41=4.4mV, so the measured fluctuation is indeed too low.

But your ADC has 10Bit, i.e. gives 1024 different values. At an ADC range of 5V, one step is 5V/1024=4.883mV, which corresponds to 0.9% fuel level. This is the resolution of your circuit, and a change of voltage by 1mV can cause a change of ADC reading by 1 step, which results in a fuel level change by 0.9%. (The difference between 4.4mV and 4.883mV can be due to rounding or not exact 5V supply voltage)

An analog low pass filter, as suggested by @Edesign can help to reduce the frequency of changes, but can not eliminate them. And: the jumps are still 0.9%.

Averaging of several ADC measurements is similar to the low pass filter. It also makes the fuel level looking smoother, since it blurs the 0.9% steps.

What you can do to reduce the fluctuation is applying a dead band. Something like
Accept ADC value only when it's different by at least 2 steps from the last accepted values.

However, this results in larger steps of 1.8%.

Looking at your formula, the voltage range going into the ADC is roughly about 0V-0.5V (assuming it can measure up to 100% fuel level), so you use only 1/10 of the range of the ADC. If you can map the input voltage to the full ADC range, you can get a resolution of 0.09%.
Either add an amplifier, or set the upper reference voltage of the ADC to about 0.5V (I don't know if this PIC allows it. Many allow to use voltages provided at two pins as upper/lower ADC range limit)

While you get finer steps with this, you'll also get more noise (fluctuations). But you now already got some ideas how to reduce this.

• Really helpful. Just to understand, should not voltage change by 4.88mV or 4.4mV for 1 step change in ADC rather than 1mV change in voltage? – mka May 17 '16 at 9:53
• No. The voltage range for a certain ADC value has a width of 4.88mV (or 4.4mV). But if the applied voltage is near the upper limit, 1mV more will be in the range of the next ADC value. – sweber May 17 '16 at 15:58
• Thank you very much. I was wondering what are the sources of noise that may cause adc readings to fluctuate. I have a simple divider Vdd->Rup(1.2k)->Rfuel(9.5-150)->ground. Vdd is taken from 7805 with 22uF decoupling at the output. – mka May 19 '16 at 5:37

To improve the accuracy of your measurement, you can use the following simple techniques:

• digital averaging: takes several measurement and display the average of them. The number of samples you can average will depend on the sample rate of your ADC and the frequency of the measurement you want.
• analog low pass filter

Also make sure the voltage at the ADC pin is not different when you measuring it with an external device, as they usually act as small capacitors, plus they are sometimes using filtering.