How to get maximum ADC resolution out of an input difference of 1.4V

I've got a project in mind that will detect what kind of charge is left in an 18V battery. For simplicity lets say the battery is at 18V when fully charged and 13V when there is about 10% charge remaining. This is the main range I'm concerned with.

By putting together a voltage divider I can get a max of 5V into the ADC on the Arduino when the battery is at 18V. When the battery is at 13V, however, the divided voltage is at about 3.6V. Ideally I'd want 13V at the battery to measure 0V at the ADC so I can take advantage of the full 1024 bits of resolution on the ADC.

Can anyone point me to a circuit or give me some ideas on how to accomplish this? I've done tons of microcontroller-based projects but not much "true" electrical engineering other than simple voltage dividing and using voltage regulators with a couple caps to bring voltages down to the Arduino's range.

In my mind I want to "subtract" 13V from the battery reading at all times so that I get between 0V and 5V at the ADC. Is this where Op Amps come into play?

Better to measure a voltage with the more stable internal 1.1volt Aref.

When you use Arduino's A/D, you realistically have 250 values spread over 5volt (18-13).
That's 0.02volt/step.
With a bit of oversampling, you could have a reasonably stable "two decimal places" readout.

If that's not enough, you have to add an opamp to convert 13-18volt to 0-1.1volt.

It might be easier to use this Adafruit board.
Voltage and current with 12-bit resolution.

ADS1115 16 bit of resolution with a programmable gain amplifier built in.

Are u aware of the Map() function…??

it does what u need also…

V_range = map(Batt_V, 18V, 13V, 5V, 0V);

Yes, but map() can’t increase the resolution.

This is definitely a good chance to learn about opamps. For basic DC stuff like this, the calculations are actually very easy.

In my mind I want to "subtract" 13V from the battery reading at all times so that I get between 0V and 5V at the ADC. Is this where Op Amps come into play?

You can do that with a [u]summing amplifier[/u].

Note that op amps usually require positive and negative power supplies (especially if you want the output go to linearly down to 0V).

And summing amplifiers are inverters, so in an application like this (where the voltage is positive and the Arduino requires a positive voltage) you generally need to follow the summing amp with another inverting stage.

Since you can adjust the gain of the summing amp (even the relative gain of each input) your negative voltage doesn't have to be -13V.

You also might want to use a 2nd ADC input for a lower resolution "direct" voltage divider reading in case the voltage falls below 13V.

...As a practical matter, it might make more sense to use an external 12 or 16 bit ADC instead of an analog op-amp front-end.

Something like this will use the full bandwidth of the ADC. 10% charge will read 0, 100% charge will be 5V and read 1023. 13V Zener (DigiKey)

The zener subtracts 13V from the battery voltage. 18V battery should give around 5V at A0, 13V battery should give around 0V at A0. The 10K series resistor to A0 adds protection for up to 28V at the battery.

Zener voltage varies with current and temp.

True. This zener is quite good though, low leakage and 2% tolerance. Depends on what the OP needs ... high precision, high accuracy or both. Should get full 10-bit precision and overall about 5% accuracy.

u will need a high precision voltage reference device–
which means u will need a power source high enuff to supply it… it being in the neighborhood of 12.5v…
then just a simple inverting op-amp circuit…
then in software, according to how much time u have… over-sample if u can, and throw out the worst high/worst low cases and average the remaining ‘group’… sample 100 times if u have that much time…