August 11, 2018:
Revised: v1.0

Peak Reading 3-digit LED Digital Voltmeter Module

This is a simple 3-digit LED voltmeter which measures and displays the input voltage continuously as well as the highest input voltage it has measured since it turned on (i.e. Peak-hold).
3-digit DVM module


A regular task for many of us is mowing the lawn. I use an electric mower which runs from a 12V lead acid battery. It's similar to the battery used in cars and rated at around 40AH. I usually put the battery on my charger once every two or three weeks.I only have a small lawn.

When I went to connect up the battery charger recently, it made a loud popping sound and abruptly died. No smoke, no flash, just sound effects. An hour or so later, after a little work on the bench, I had repaired the charger. The charger used an op-amp, one half of the pair of op-amps contained in a standard LM358 dual op-amp IC, to control the charger. For some reason, the chip had simply self-destructed.  The blown part was not made by any recognised manufacturer, there were no other problems to be found, and after I swapped it out for a standard Texas instruments part, the charger came back to life.

old charger

Figure 1:
My charger looked similar to this one It has 4 LEDs to indicate the output current but the accuracy of that current display is questionable.

As I traced out the charger's circuit during the repair, I recalled it didn't automatically stop charging once the battery was fully charged. It wasn't  a big problem, but in the process of repairing it, I added a few extra parts to the spare op-amp in the LM358 op-amp package circuitry to fix that problem. But no good deed goes unpunished, as they say. I then had to use several multimeters to measure the charging voltage and the battery terminal voltage to set the ‘end of charge’ cutoff point correctly on the charger. Since I didn't have a digital voltmeter with a “min/max” measurement function, I was forced to repeatedly check on the charger and the various multimeters I had connected to it so I could set the end-point correctly.

I headed off to the Internet to see if i could buy a little meter that could do this, but I found they were surprisingly expensive. So, partly inspired by the ultra-cheap three-digit digital voltmeter modules available from many Chinese sources (all of which also lack any peak reading function, incidentally), I decided to make my own compact DVM with a peak reading function.

I wanted an equally simple compact digital voltmeter that I could add to my charger so I could see:

Design Issues

Depending on the state of the lead acid battery, my battery charger produces anything from about 11V (if the battery is completely discharged) to almost 15V. That means the battery terminal voltage I wanted to measure would range from, say, 10V to 16V. A three digit LED display would be cheap, easy to read in my garage, and give a measurement resolution of 0.1V which seemed ideal to me.  To allow for extremes, I decided my peak reading voltmeter should display values from 0 to 25V.

In order to minimize the number of parts in the voltmeter, I wanted to dispense with the current limiting resistors normally used with LED displays. This is perfectly acceptable if some care is taken over the design, as I will explain.
An important factor when using this approach is the selection of the supply rail for the required microcontroller. Since I mostly use Atmel’s ATtiny and ATmega family
, the microcontroller supply rail can range from 1.8V to 5V. Most of the cheaper microcontrollers, however, will only operate down to 2.7V so I only considered using standard 3.3V and 5V regulators which i had in my parts bin.

If the three digit seven segment LED display is driven directly from the processor, one digit at a time, one port pin will source the current for each display's LED segment while a second port pin will sink that same current. Figure 2 shows the general arrangement.
LED without series resistor

Figure 2:
Driving an LED (or any segment of a 7-segment LED display) without a resistor requires two port pins on the microprocessor, and some thought..

A typical LED (or any segment in a seven segment LED display) needs between 1.6V (for a cheap red LED) to 3.4V (for a blue LED) at a current of 1mA (high efficiency) to 20mA (older LEDs). Green, yellow and high efficiency red LEDs typically require about 2.5V to operate and just a few milliamps to operate well. In the absence of a current limiting resistor, in theory any LED display could be used except for blue with a 3.3V regulated rail, and all colours with a 5V rail. So why use a resistor?

Resistors are added to provide current limiting.  Without a resistor, and with a 5V supply rail, the microprocessor will attempt to pass too much current, usually more than the rating of the chip. Adding the resistor prevents that. But there is another approach.

The Atmel data sheet specified the performance of each output pin. Excluding the Reset pin, if the chip is powered from 3.3V, when any port pin set to a logic High, it can output 3.3V (with no load) but the voltage on that pin falls to about 2.5V if it has to output 20mA into the port's load. If the pin is set to output a logic Low, 
the pin will 'sink' current. With a 3.3V regulated supply, the voltage at that port pin will sit around 0.1V while passing a current of 5mA, or as much as 0.5V at 20mA.

Looking at Figure 2 again, in the absence of the usual current limiting resistor, the current will rise as high as it can until the arrangement reaches a balance between the voltage drop of the 'High' output pin, the LED forward voltage, and the voltage drop of the 'Low' output pin. Assuming a 2.5V LED and a maximum Low output voltage of 0.5V, the maximum current the output pin set to High can source will be that for an output voltage of 3.0V (i.e. 2.5+0.5) or about 5mA. But at that current, the Low pin will only drop 0.1V. The source current will then rise, say to 10mA, and the 'Low' output voltage drop will increase to about 0.2V, The High pin will then sit at 2.7V (0.2+2.5) when sourcing about 10mA. At this point, the two pins and the LED arrangement will be in balance – they cannot do otherwise - and the LED will be brightly illuminated with a constant current of 10mA. The LED is perfectly safe because it sees a constant current, and the output ports are similarly OK. Except...

There remains one problem. In a 7-segment LED display, eight segments are connected to either a common anode or common cathode connection. This common connection must be driven by one microprocessor output pin. The result of this in practice, then, is that the balance I just described is actually set up between the number of driven LED segments and the maximum current possible from the pin connected to the common cathode or common anode.

It is therefore possible to potentially and destructively overdrive this common pin. To avoid this problem while still allowing the LEDs to be driven at reasonable currents, the displays are run at a reduced duty cycle. In this design, each display is turned on for just 20% of the time. With a peak per-segment current of about 10mA, average current per display with all 7 segments connected and running averages about 15mA, well within the maximum rating of the port pins. Add the processor current (with an 8MHz internal RC clock) of several milliamps, and the entire meter draws no more than 20mA. All without the need for limiting resistors.

Recall, this is the situation with a 3.3V regulator. If the design uses a 5V regulator, the LEDs must be operated at a much lower duty cycle, usually about 5%. Blue and white LED displays can then be used along with some of the brighter high efficiency red, green, yellow and orange displays, many of which require about 3.5V to operate. In this design, I used an older low efficiency red LED display and tested some new high efficiency red displays. Both worked fine with a 3.3V regulator. I actually used a 
low voltage drop regulator which allows the meter to operate with power supplies as low as 3.5V.

Circuit Description

The simple schematic is shown in Figure 3.  Without a cluster of resistors for the LED display, the design is very simple. A 10:1 resistor voltage divider is used to drop the external voltage down to a suitable level for the microcontroller. It uses standard 1k, 10k and 100k resistors for simplicity. The meter’s voltage reference is taken directly from the 3.3V regulator rail.

peak reading voltmeter schematic
Figure 3: Schematic of the peak reading voltmeter - Shows optional programming connector (J4)

Every pin is used on the low cost 14-pin ATtiny44 that I used. That keeps the design as compact as possible (An ATtiny24 or ATtiny84 can also be used), Since this means the Reset pin is used to drive one of the segments, this led to another couple of problems, one affecting the development process, the other the meter’s operation.

Firstly, the RST pin only works as an output if the RSTDISBL fuse is programmed for this mode. However, once this is done, it is necessary to use a more complex high voltage programmer for software development.
The second problem impacts the meter’s operation. The RST pin cannot sink as much current as the other pins. For this reason, it is only used here to drive the decimal point to ensure the otherwise slightly lower segment brightness is not noticable during operation. That also led to a slightly more complex PCB layout. Incidentally, common cathode displays cannot be used with this arrangement due to the limited ‘logic high’ output voltage delivered by the Reset pin. It must be a coomon anode display.

Since the processor’s Reset pin functionality must be disabled using the processor’s programmable fuses, this MUST be done AFTER the chip’s flash memory is programmed with the software. Once the pin is disabled, the chip cannot be reprogrammed except with a specialized high voltage programmer.

The prototype included the programming connector, and allowance has been made to fit it to the PCB for those wanting to program the chip. This connector is not required once the chip is programmed so may be omitted if the it is programmed elsewhere or removed once programming is completed. If the chip is programmed on the board, it must be disconnected from the regulator during the process. I found my USBasp programmers did not like the 3.3V regulator being left in circuit. Adding the on-board link fixed that problem. It's bridged on the board with a blob of solder.

I used a low voltage drop Taiwan Silicon TS2950CT-33 TO-92 regulator but a more commonly available LM78L33 regulator will work almost as well. It will just require a slightly higher input suppy voltage to allow for the higher drop required across the 78L33 regulator. In my charger, after several hours with a typical 13.8V battery charging voltage, the regulator is only very slightly warm, perhaps about 25 – 30C in my cold garage. (Note: Using a 5V regulator will require changes in the software)


I originally built my meter using a scrap of prototype board about the size of a postage stamp. It took only an hour or so to wire everything up. It’s quite small. I linked the DVM input to the regulator input for simplicity, but it can be kept separate if required, especially if you wish to measure voltages below the processor’s supply rail.

After building the prototype, I wondered how small I could make it. Just for fun, I designed a PCB to suit the low cost SMD version of the ATtiny44 processor. It turned out to be remarkably similar in size to those cheap Chinese made digital voltmeters, the ones that originally inspired my peak reading version.

On a whim, I checked to see how much it would cost to have the boards made in the depths of China, and it turned out to be so inexpensive that I immediately placed an order for the minimum quantity of 10 boards. The board layout suits the pin spacing for 0.4” high common anode displays but 0.36” displays (and probably 0.56” displays) will fit if their leads are bent slightly.

PCB topside with parts - No display
Figure 4: Topside view of the assembled PCB with programming connector before mounting the display. This was my first prototype and shows the regulator mounted on the display-side. It's better mounted on the other side, as shown in the second one I built in the next photo (below).

PCB with display - top view

Figure 5: Module  with
0.36” common anode display fitted and programming connector removed. Note the location of the two leaded components - the bypass capacitor and the regulator

Comparison with Chinese made modules
Interestingly, when I added up the cost for my SMD version, it worked out to be nearly the same as that of the Chinese modules. All of the components I used were sourced from Ebay or Aliexpress except for the PCB, ten of which came delivered from ALLPCB for under $US6.00, or 60 cents each.

By the way, ALLPCB did a great job. They were very fast, and I plan to use them again. No, I didn't get paid to say that, nor will I get a discount from a future order. It's just an honest report of what I found.

Figure 6: The top two modules in this photo are my peak reading voltmeters while the one at the bottom of the picture is a Chinese-made standard voltmeter (without any peak reading feature!)

Anyway, here’s how the costs worked out (Mid-2017 prices):
Table 1: Prices paid for the PCB SMD version

At the same time, standard Chinese LED voltmeter modules were selling for $US3.00 each. I think it’s amazing that I can build a small number of my modules so competitively.


As usual, I wrote the software using Bascom, the Basic language compiler software for the AVR family. It took a couple of hours during a warm summer afternoon while I retreated indoors from the worst of the sun’s heat. The Bascom source code and the ready-to-program HEX file are available for download below. Feel free to modify the software to suit your own requirements.

The fuse settings are described in the source code.


As noted earlier, program the flash memory of the processor with the HEX file first. Then program the fuses. Other pages on my website describe the process in detail.


When the peak reading voltmeter is powered up, the meter initially displays a sequence of three letters ("PVt" which I used to indicate ‘Peak Volts’), for about 1 second per character. It then starts the measurement cycle.

Each cycle first displays the current voltage reading prefaced by “Vc-“ on the display, and then the meter shows the peak voltage. This is prefaced by “VP-“ on the display. The cycle then repeats. The peak voltage is the highest voltage the meter sees, this value being retained/updated until the processor powers down.

A typical display cycle on my meter is displayed as follows, each line taking about 1 second:


i.e. The current battery voltage is 13.2V and the peak voltage measured so far is 13.4V.


To charge my lead-acid battery, the minimum charging voltage required is 13.8 volts dc (2.25V/cell). This voltage will be enough to fully charge or maintain the battery on a trickle charge, but charging will take a very long time. To fully charge the battery in a reasonable time, the charger’s voltage should be 14.2 V. It should not rise any higher since at higher voltages, batteries tend to produce hydrogen and other gases.

Once charging stops and the charger is disconnected, the battery voltage should fall to anywhere between 12.6 - 13.8 volts depending on the health of the battery. I have been using my meter for a number of months, and it’s already proven to be very useful. It routinely confirms when the end-point peak charging voltage of 14.2V has been reached. With the charger subsequently automatically disconnected, the battery voltage is then typically about 12.8V, or just over the desired 2.1V/cell. My meter reports both the peak voltage reached during the charging cycle and the current battery voltage.

I hope you find equally useful applications for the meter.


Software: This ZIP file includes the Bascom-AVR source code and the HEX file for direct programming of the ATtiny44

PCB Layout: This ZIP file contains the Layout6 file.

Want to go back to the main page? Click here to return directly.