Getting weird readings via analog inputs

I'm trying to use my arduino as a low battery shutoff system. Aside from reading the battery voltage itself, everything else works flawlessly.

I'm using a 4x voltage divider. I'm using a switching step down regulator but I made the filtering to spec according to the data sheet.

The problem is, the full battery is 13v and the empty battery is 11.9v. That's a small range to read from. (1.1v between full and empty)

So, is there either a fairly easy to use IC for reading voltages with decent accuracy, or could I possibly use a differential amp to subtract 11v out of the initial reading before sending it into the analog input so I can use nearly all 1024 steps of ADC?

Using a 2:1 voltage regulator (20K:10K ect) will give you 4.33V at full and 3.97V at empty. On the ADC that's 887 at full and 813 at empty. Your resolution will be about 15mV. How much resolution do you need?

John_S:
Using a 2:1 voltage regulator (20K:10K ect) will give you 4.33V at full and 3.97V at empty. On the ADC that's 887 at full and 813 at empty. Your resolution will be about 15mV. How much resolution do you need?

That would only yield me 74 steps out of the 1024 total steps. I feel if I scaled the output with a differential amp, I could utilize the whole scale.

Right now I'm using 3.3v as the AREF, and 4:1 divider. That's 923 empty, 1008 full. That's 85 steps. Still not even 1% per step. Sucks.

I'm thinking using amps to subract 11v, then scale it to fill the 5v range would be my best option.

Have you tried mapping ?

// Use with 10K, 4.7k voltage divider adjust as needed

#define battPin 2 // battery read pin

void setup()
{
Serial.begin( 9600 ); // Start interface
}

void battMon( )
{
int battLevel = analogRead( BATT_PIN );

valBatt = map( battLevel, 923, 1008, 0, 100 );

Serial.print( "Batt = ");
Serial.print( battLevel, DEC );
Serial.print( " " );
Serial.print( "valBatt = " );
Serial.println( valBatt, DEC );
}

I got this from somewhere I can't remember, when I was making a voltmeter.. It worked fairly well from what I remember. Of course the analog pin is not protected very well this way. Also remember there is no loop in the above, use it as a reference.

It worked fairly well from what I remember.

No it does not, at least not in this context, all it does is play with the numbers.

To the OP, yes a differential amplifier is probably the best way to get full resolution. The other alternative is an amplifier with a DC offset. Shifting your voltage down to a range of 1.1V you can then use the internal 1.1V reference and get full scale over the range you are interested in.

The down side is you will probably need a +/- 15V supply on the op amps and some protection for the analogue input for when the op amp is outside the 0 to 5V range.

No Mike a LMC6022 will work quite nicely for that purpose
Here is the data sheet. Inputs include ground outputs will swing rail to rail, Ibias is low and it is a high gain device.
http://www.datasheetcatalog.org/datasheets2/34/347316_1.pdf
An Lm358 would require a +/- 18 V supply to go to +/15V out. The LMC6022 will do it with a +15V supply.

Doc

Use 11 V zener in series with resistor to ground. Read voltage across a resistor.

Use 11 V zener in series with resistor to ground.

Nice :slight_smile:

The only problem there is the tempco and accuracy of the Zener it can be 10% on a "C" version part but yes, it would work well. The only other drawback might be that for stable operation the Zener should disparate about 20% of it's rated power dissipation... to keep it warm and stable. National Semi used to make a temperature compensated Zener... LMXX?, I just cannot remember any more and the books were long ago lost. I remember it because it had a heater that stabilized the case temp... one version came with a thermal insulator. I still am of the opinion that the easiest method would be to use an opamp as an analog level shifter and the second amp as a gain block for scaling the output to whatever range was needed for your supervisory measurement and control...

Doc