Digital voltmeter with pic

Thread Starter

dhc7

Joined Jun 22, 2008
10
Hello all,

I've been searching around to find some hints to my project, but still I'm pretty confused. So any help would be great.

I'm going to make a digital voltmeter to measure my car's battery voltage. First I was going to make more complicated system that would read the OBD2 line and show some data on a lcd. Then I faced the truth that this thing would contain too much tricky problems to solve. Now I'm planning to make just a digital voltmeter and present the result on three 7-segment displays.

I'm going to use PIC, probably 16F870. I have some experience about ad conversion, but the biggest problems at this point are scaling the input voltage and handling the measured result in the sw. The result should be shown in three-digit form, for example 13.4 V.

Of course the battery voltage should be around 12...13 volts all the time. There should not be voltage like 7 volts, so being able to measure the total 12 V scale is somehow unnecessary and waste of resolution. So would it be better to reduce the measurement scale and put the focus on those few volts which are important? I mean measuring just around 10...14 volts and fix the low reference point of the conversion range somewhere else than 0 V? On the other hand, the 10-bit ad conversion is a little overkill anyway, because only about 30-40 different voltage steps are needed.

I think it doesn't make a sense to do the 10-bit conversion for showing the voltage only at 0.1 volt resolution. What should I do with the ad result? Roughly leave some least significant bits out of the process? I know about using a lookup table to get the numbers for the output, but how to make the result in a suitable form for that stage? And how to separate the decimal part of the result?

So much questions... Any suggestions? Thanks in advance.
 

bertus

Joined Apr 5, 2008
22,270
Hello,

The first step is to bring the voltage in the range of the adc (0 - 5 Volt).
This can be done with a voltage divider or subtracting a constant voltage.

Greetings,
Bertus
 

Thread Starter

dhc7

Joined Jun 22, 2008
10
Hello,

The first step is to bring the voltage in the range of the adc (0 - 5 Volt).
This can be done with a voltage divider or subtracting a constant voltage.

Greetings,
Bertus
That's true. But the problem is how to handle the result in the software easily. And would it be easier if the battery voltage is not scaled to the whole 0...12 volt range for the ad input, since the voltage will never be very low.
 

blocco a spirale

Joined Jun 18, 2008
1,546
What is the purpose of the meter and do you need 0.1V resolution? The only reason I ask is that unless you particularly want this to be a uC project and if the meter is only intended as an indicator of battery charge/charging then an analogue solution would be simpler.
 

Wendy

Joined Mar 24, 2008
23,415
Take a 9.1 V zener, put it in series with a grounded resistor, and measure the resistors voltage. The voltage will be Vmeasured = Vbattery - 9.1V, which puts it in the scale you want. If your battery voltage drops below 9V you have other problems.
 

SgtWookie

Joined Jul 17, 2007
22,230
That would not work as-is, because the PIC uC would get fried due to the voltage measured being over range.

However, if combined with Bill Marsdens' idea of using a Zener and a resistor were used on the front end, it could be made to function for this project.

But instead of a 9.1v Zener, a 10v Zener would need to be used. A charging system might generate 14.5v right after the engine starts to charge a badly depleted battery.

A 1N4740A Zener is 1W 10V, or 100mA current flowing through it. So to get in the Zener's middle range, put 50mA through it. 14.5v-10v= 4.5v, so we need a resistor that limits current to 50mA across 4.5v.
Since R = E/I, and E=4.5 and I=0.05A, R=90 Ohms. Nearest standard E24 value is 91 Ohms. Power dissipated in the resistor is 225mW, so a 1/2W resistor will work just fine. I wouldn't leave it connected for long without the engine running though.

It will exhibit non-linearity at the lower end due to the decreasing current through the Zener.

Might be less complicated to use an LM3914 linear dot-bar LED driver.
 

Thread Starter

dhc7

Joined Jun 22, 2008
10
What is the purpose of the meter and do you need 0.1V resolution? The only reason I ask is that unless you particularly want this to be a uC project and if the meter is only intended as an indicator of battery charge/charging then an analogue solution would be simpler.
That resolution is not a must, but I thought that would be just fine. One volt resolution is too rough, and I don't find it reasonable to show two decimal digits either.

And it's about fun and hobby, not very serious need why I'm doing this. If I just needed a voltmeter, I'd go to a shop and buy one. I want to make one instead.

And yes, I've tried Google with this.
 

Thread Starter

dhc7

Joined Jun 22, 2008
10
However, if combined with Bill Marsdens' idea of using a Zener and a resistor were used on the front end, it could be made to function for this project.
That zener idea is not bad at all, I'm just a little bit worried about the accuracy and also the non-linearity thing with zeners.

I was planning to simply use resistors and make the scaling by voltage division. Of course there will be some error because of thermal coefficient, but I think that is not a huge problem. And the measuring line has to be protected against transients with some zener.

The most difficult part now is how to deal with the ad conversion result and how to make it show up on the 7-segments. But I think I'm getting an idea with that, I'm just not sure if it will work... :)
 

blocco a spirale

Joined Jun 18, 2008
1,546
Sorry, I didn't mean to sound abrupt.

I completely understand building circuits for the experience of learning and creating. I'd never reproduce someone elses design because I find no interest in that approach.

Sometimes it isn't clear what the motives are for building somnething. It might be simply to fulfil a requirement, in which case the simplest and easiest solution might be the best, or it might be more of a learning exercise where the journey is at least as important as the final destination.
 

Thread Starter

dhc7

Joined Jun 22, 2008
10
Sorry, I didn't mean to sound abrupt.

I completely understand building circuits for the experience of learning and creating. I'd never reproduce someone elses design because I find no interest in that approach.

Sometimes it isn't clear what the motives are for building somnething. It might be simply to fulfil a requirement, in which case the simplest and easiest solution might be the best, or it might be more of a learning exercise where the journey is at least as important as the final destination.
That's ok, no problem at all. I understood your point. But like I told before, in this project it is about making this thing with a microcontroller as I find it useful and also interesting here. I also want to get some experience of making ad conversions, using lookup table and driving 7-segments. So this is more like getting some exercise than just getting a working voltmeter.

Of course it is helpful and a good idea to suggest an easier option, if someone is just having trouble with getting some result no matter how. So I did not think you're abrupt.
 

blocco a spirale

Joined Jun 18, 2008
1,546
Ok, so you've decided on 0.1V resolution. Set the A-D ref volt to 5V and construct a voltage divider on the A-D input with a mid-point voltage of 5V when 25.5V is applied at the top-end e.g 15k fixed resistor at the top, 10k multi-turn pot at the bottom and take the output off the wiper. (you can refine this but just as an example)

I believe the PIC has a 10-bit A-D converter so RRF the result to give an 8-bit result. You now have a 0-25.5V voltmeter with a 0.1V resolution and a direct relationship between the value returned by the A-D and the input voltage i.e. 125 = 12.5V, 147 = 14.7V ....
 
Last edited:

Thread Starter

dhc7

Joined Jun 22, 2008
10
Ok, so you've decided on 0.1V resolution. Set the A-D ref volt to 5V and construct a voltage divider on the A-D input with a mid-point voltage of 5V when 25.5V is applied at the top-end.

I believe the PIC has a 10-bit A-D converter so RRF the result to give an 8-bit result. You now have a 0-25.5V voltmeter with a 0.1V resolution and a direct relationship between the value returned by the A-D and the input voltage i.e. 125 = 12.5V, 147 = 14.7V ....
That sounds good. Yes, it is 10-bit converter, and the result is in two registers. That is good idea to make the scaling so that there is a clear relationship. I was thinking something like that, but didn't somehow catch the idea. However, this solution makes the lookup table pretty long (256 words) which may be a problem. But your suggestion is good anyway.

I've also thought shifting the result register or doing some calculations to separate the three different numbers from the result. Then there should be a lookup table just for the numbers 0...9 and they would be presented separately one by one.

I found the same kind of problem here:
http://www.eng-tips.com/viewthread.cfm?qid=120880&page=5
 

blocco a spirale

Joined Jun 18, 2008
1,546
You won't need a look-up table if you do it this way, there is nothing to convert.

For splitting out the hundreds, tens & units into separate registers - you can do this using subtraction and testing the carry flag.

Declare 2 RAM Variables for 100s and 10s and clear them to zero. Start by subtracting 100 from the result and testing the carry flag, if the carry flag is clear increment the 100s register, keep doing this until the flag is set indicating their are no more 100s to subtract. Do the same for the 10s and whatever is leftover are the units.

You can then use a look-up table to convert the three binarys to 7-segment.
 
Last edited:

blocco a spirale

Joined Jun 18, 2008
1,546
That's correct, use the subtraction method in my previous post to split the A-D conversion result into 3 separate registers (hundreds, tens, units) then use a look-up table to convert each number (which will be in the 0-9 range) in each register to its 7-segment pattern and then send it to the output port.

I'm assuming a 7-segment led display. May need to be multiplexed, I don't know how many output ports your PIC has.
 

Thread Starter

dhc7

Joined Jun 22, 2008
10
That's correct, use the subtraction method in my previous post to split the A-D conversion result into 3 separate registers (hundreds, tens, units) then use a look-up table to convert each number (which will be in the 0-9 range) in each register to its 7-segment pattern and then send it to the output port.

I'm assuming a 7-segment led display. May need to be multiplexed, I don't know how many output ports your PIC has.
There are enough outputs (3 ports) in 16F870 for controlling each display separately, but I'm going to multiplex them anyway. The circuit will be a little bit simpler, and somehow it feels better way to do it.

Your idea seems to be very nice and I think I will try it. Thanks a lot.
 

blocco a spirale

Joined Jun 18, 2008
1,546
This is a nice little project and you can always expand it by adding things like minimum/maximum voltage logging using the internal eeprom, which would give a good indication of battery and charging system condition. Or, high/low volt alarms or auto power shut-off for auxiliary devices such as cool-boxes etc. or what about incorporating a thermometer function as well?
 

Thread Starter

dhc7

Joined Jun 22, 2008
10
Typically these microcontroller projects tend to expand as new ideas come up... :D

I plan to make some extra features in this meter, for example min/max logging or may be some alerting if the voltage drops too much etc. The display could start blinking when the voltage goes below 12 volts or something like that.
 
Top