Google Ad

Video Blog #022 - Handheld Precision Digital Voltage Source

DISCLAIMER: This video is educational only, so if you decide to do the same yourself then you are on your own, I can't be held responsible for any problems/issues/damage/injury that may occur if you decide to follow this blog and try it yourself.


Having recently converted my EDC Programmable Voltage Source I got the volt bug and decided that it would be great to have a handheld unit covering the same output range resolution, or as close as I could get.

As I already have a homemade simple analogue voltage source (rough & ready!) the form factor I already had an idea, I set about designing a unit complete with the following outline spec.

- Graphics LCD, 128x64.
- Arduino powered.
- 4 d.p. positions with an extra 5th one thrown in for free!
- 12 button keypad. Absolutely no potentiometers, internally or externally.
- 18bit DAC with an accuracy/stability down in the tens of uV's.
- 1 or 2ppm/degC 5Vdc Vref, with an external heater to effectively restrict the effect of this value. LM399AH vref.
- Calibration via software (keypad & LCD).
- Battery powered, 2xPP3.
- Low power consumption power circuit for battery use.
- Hammond 1599EBK case.

Part 1 of the design & build:-


Part 2 of the design & build:-


Part 3: Final mods into production:-


Software upgrade (available on all new units soon) - Playback Mode:-


As featured on the EEVBlog Mailbag (29/09/15) - Skip to 24mins 06secs:-


Review by Martin Lorton (11th March 2016):-



User adjustable 0.05Vdc to 10Vdc range via keyboard interface and LCD.


The unit provides mainly 4 d.p. positions XX.XXXX, but there is a 5th d.p. the user can make use of, i.e. XX.XXXXX. This least significant d.p. is not guaranteed as this digit is the 10uV steps, however, the DAC is only capable of 38.146uV steps.......but it offers the user to at least get closer to the desired output voltage.


Output voltage display in large characters = This is the main display.
Output status display = 'OK' or 'FAIL'. The output voltage is monitored and if is not within +/- 100mV then the FAIL message is displayed, such as when the output is shorted to 0Vdc etc.
Battery voltage display = Series 9Vdc PP3's.
User Input display = As the user enters a new voltage it is displayed here.
Keyboard = 0 to 9 used for voltage input with * used for the D.P. Use * or # to increase/decrease current voltage in 10uV steps, hold down for 1mV steps.


The user can set up 5 voltages that can be played back over time. Each one of the 5 has a time in seconds associated with it. The playback can be looped.


Zero & Span multi setpoint calibration params. User adjustable against 0.050Vdc & 10Vdc.
Battery readout calibration.
Output vltage feedback calibration.
All calibration is saved to EEprom.


Front panel soft power button interfaces to the Arduino to facilitate power on /off.
To power up press and hold the power button till the LED turns on then release.
To power off press and release the power button, a power down message will be displayed.



2xPP3 (18Vdc total), typically 2xLithium-Ion rechargeable 600mAh ea.
3off LT1763 LDO regulators with micropower quiescent current, +3.3Vdc, +5.3Vdc & +11Vdc.
Power consumption: 40mA (after heater stabilizes).
Running time = Approx 14hrs contious operation from full batteries.

Atmel328P, 3.3vdc running at 8MHz.
Arduino bootloader = Pro Mini.

DAC9881, 18bit, SPI interface, single channel, low noise, voltage output, rail to rail, single power supply +2.7v to +5.5vdc.
Over 0-5vdc 262144 bits = 0.000019072 Vdc. Therefore, over the full 10vdc output range = 0.000038146 Vdc = 38.146uV resolution.


Short circuit protected - indefinite.
Output will drive 5K load dropping less than 10uV.

MAX6350 5vdc output (12Vdc supply), 1ppm/degC, 0.02% initial accuracy = 0.001Vdc (dialled out in Arduino software).
LM399AH Vref.

A 40.8degC, +/-1.5degC, 0.1degC resolution resolution heater modified to 32degC.
The Vref IC can be used in conjunction with this heater to reduce the effect the typical temperature coefficient the Voltage Reference has, thus increasing stability of the 5vdc vref to the DAC.
Available here.


LCD-AG-C128064CF-DIW, 128x64, ST7565R COG Type.
Note: This LCD supports LED backlighting, however, I have opted to not use it as it's an extra 20mA I'd rather not spend.


Arduino core (standard/unmodified).
Arduino libraries (standard/unmodified)
3rd party library: U8glib Monochrome Graphics Library. Compliant with the license and with permission from the author in writing (just to be sure) -
Note: Some people have asked about releasing the source. This is not a requirement under the Arduino license even for commercial products. Only if the core & libraries are modified, and in this case they are not.
Latest software version = V1.3 (March 2016) fixes minor Cal mode & Playback mode issues.


Through a combination of real-life testing and by-the-book specifications I have come up with the following overall specifications for the unit (subject to change/update):-

Output range = 0.05 (50mV) to 10Vdc
Maximum output load = 5mA (maintaining within approx. 10uV)
Accuracy = 0.001% (within 100uV & using a PLC filter of 1.0 or higher)
Stability = 0.0001Vdc variation max. 4d.p. mode.
Stability = 0.00004Vdc variation max. 5d.p. mode.
Temperature coefficient (output voltage) = <1 ppm/degC (tested over an 10.5degC variation). This isn't bad considering the LM399AH itself is 0.3 to 1ppm/degC and is down to using a high spec DAC, hi spec chopper op-amps and low TCR resistors in the design.


In order to test & record the temperature coefficient of the unit I used the following test gear:
- Keysight 34461A 6.5 digit multimeter.
- Temperature chamber (peltier heated/cooled), capable of +/- 12degC approx variation around ambient.
- Digital thermometer.

With a workshop ambient of 23.5degC I first ran the voltage source for 10 minutes and stabilized the output at 10.00000Vdc.
Then, with the temperature chamber pre-cooled to 13degC I put the voltage source inside (still hooked up to the Keysight) and recorded the variation in output voltage, per the graph below.

TEST No.1 (PDVS1):
Start voltage = 10.00000 Vdc
End voltage = 9.99993 Vdc
Recorded variation = 0.00007 Vdc = 70 uVdc
Start temperature = 23.5 degC
End temperature = 13 degC
Recorded variation = 10.5 degC
Test length = 30 mins

The resultant temperature coefficient calculated from the above is approx. 0.67 ppm/degC.

Total variation Vdc = (Initial voltage * (ppm/1000000)) * total temperature variation
thus re-arranged: ppm per degC = (total variation Vdc * 1000000) / (start voltage Vdc * total temperature variaton degC)
0.67 ppm/degC = (0.00007 * 1000000) / (10.00000 * 10.5)

TEST No.2 (PDVS2):
Start voltage = 10.00008 Vdc
End voltage = 9.99992 Vdc
Recorded variation = 0.00016 Vdc = 160 uVdc
Start temperature = 11.5 degC
End temperature = 40.0 degC
Recorded variation = 28.5 degC
Test length = 1 hr

The resultant temperature coefficient calculated from the above is approx. 0.56 ppm/degC.

Total variation Vdc = (Initial voltage * (ppm/1000000)) * total temperature variation
thus re-arranged: ppm per degC = (total variation Vdc * 1000000) / (start voltage Vdc * total temperature variaton degC)
0.56 ppm/degC = (0.00016 * 1000000) / (10.00008 * 28.5)


TEST No.3 (PDVS1 & PDVS2):
I tested both units together at the same time and with my HP 3458a DMM. I started at 20degC ambient and ramped the temp down to the lowest recorded, let it soak for an hour then ramped it up to the highest and let it soak again. The details below record the limits. Test duration - 4hrs.

PDVS1 Lowest temp voltage = 10.000058 Vdc
PDVS1 Highest temp voltage = 9.999947 Vdc
PDVS1 Recorded variation = 0.000111 Vdc = 111 uVdc
PDVS1 Start temperature = 11.0 degC
PDVS1 End temperature = 35.0 degC
PDVS1 Recorded variation = 24 degC
PDVS1 Test length = 4 hr
PDVS1 The resultant temperature coefficient calculated from the above is approx. 0.47 ppm/degC.

PDVS2 Lowest temp voltage = 10.000033 Vdc
PDVS2 Highest temp voltage = 9.999956 Vdc
PDVS2 Recorded variation = 0.000077 Vdc = 77 uVdc
PDVS2 Start temperature = 11.0 degC
PDVS2 End temperature = 35.0 degC
PDVS2 Recorded variation = 24 degC
PDVS2 Test length = 4 hr
PDVS2 The resultant temperature coefficient calculated from the above is approx. 0.32 ppm/degC.

One conclusion to draw from these very low tempco's is that the insulating nature of the units housing, the self-regulating LM399AH heater and the heat generated by the electronics has the affect of insulating the unit from external variable temperatures.
Note: The HP 3458a DCV was recalibrated every hour.

Note: Use my PPM calculator here also.




As an added test, I then turned off the temperature chamber cooling and opened the door and let the voltage source warm up to ambient 23.5degC again. As follows:





I also compared the accuracy and noise levels compared to two other commercial Voltage references/standards. A Chinese unit, and another made in the USA.

The Chinese unit is based on an AD584 ref IC and has a four way selectable output voltage, 2.5, 5, 7.5 & 10Vdc.
I selected 10Vdc and got 9.99847Vdc. The output isn't particularly accurate and takes some considerable time to 'warm up'.
You can see just before the half-way point on the graph below I changed over to my own Precision Voltage Source and punched in the same 9.99847Vdc output. You can see the difference in noise levels.
Note: PLC filter of Keysight 34461A set to 10.



Similarly, I tested against the unit built in the USA. It's based on an LT1021 ref IC a has a five way selectable output voltage which the user specifies at order. Mine has 0.5, 1, 2.5, 5 & 10Vdc.
I selected 10Vdc and after a short warm-up the output settled at 10.00007Vdc.
You can see in the graph below at just before the half-way point I swapped it out for my own Precision Voltage Source unit, set the output to 10.00000Vdc. You can clearly see the difference in noise levels as well as the accuracy of the unit. The centre line is set to 10.00000Vdc and with a 200uV voltage span on the graph.
Note: PLC filter of Keysight 34461A set to 10.



Here's another comparison between the USA unit (top photo below) and my unit (bottom photo below).
Common settings: Rigol DS2202, BW Limit=20M, Acquisition = Averaging 4 samples, Time Base 1mS, 500uV per division, probe ground tip used.

USA unit. Output measured directly across Vref output.



My unit. Output measured directly across banana sockets (on the outside, so no cheating!).



BATTERY TEST (upated 31/08/16):

With a 600mAh Lithium Ion battery I get around 14hrs continious use on the PDVS1.

I thought I'd test four different Lithium Ion batteries I picked up from Ebay, just to see if their capacity was as advertised.

900mAh (2 types), 780mAh & 600mAh.

I ran a controlled test, first charging all to capacity using the same charger, then performing a controlled constant current discharge of 0.2A until the batteries reached the recommended minimum of 6vdc.


Battery    Capacity   
  Test - Load 
  Test - Discharge to 6vdc 
  Test - Discharged Capacity    Theoretical (at 0.2A) Discharge Time 
No-name (green) 900mAh
0.2A 2hrs 20mins 466mAh 4.5hrs (900mAh)
Not good
LiteLong 780mAh
0.2A 2hrs 39mins  533mAh 3.9hrs (780mAh)
EBL 6F22 600mAh
0.2A 2hrs 40mins 534mAh 3.0hrs (600mAh)
Etinesan 900mAh 0.2A 3hrs 10mins 633mAh 4.5hrs (900mAh) Good



The DAC9881 is available in two versions, the difference being in the relative accuracy and differential non-lineararity, The difference in cost is significant. Therefore, I have designed a procedure whereby instead of calibrating the device with 2 setpoints, i.e. X1, Y1 & X2, Y2.........I am using 10 setpoints spaced 1Vdc apart from zero to 10Vdc. This should in theory improve things a little as I had noticed that with the 2 setpoint method the bottom and top ends can be set fine but anywhere at random in the middle can be off by 2 or 3 bits.
The new 10 setpoint method is easy and quick to use using the LCD and keypad and is semi-automated meaning that only 10 total values are adjusted, not 18.

There is also the facility for adjusting the Battery Voltage display and also the Feedback Voltage, both via a simple up/down control.
Feedback Voltage DOWN = press 5
Feedback Voltage UP = press 6
Battery Voltage DOWN = press 8
Battery Voltage UP = press 9


I have provided an FTDI header on the pcb, so you need to use a USB to FTDI adaptor (3.3Vdc). However, on top of that there is an additional issue which can cause newbie problems when uploading that is created by the fact I am using D0 and D1 for general I/O, and since these pins are also used by the FTDI interface uploading can fail due to port conflicts.
The reliable procedure for uploading is as follows:-

1. JP1 must be open on the pcb. Also, have the USB end of the FTDI adaptor already connected to your PC, but don't connect the FTDI header to the pcb yet.
2. With power OFF (batteries connected), insert the JP2 jumper. The unit will power up.
3. Connect the FTDI header to the pcb.
4. You can now freely upload via the Arduino IDE.
5. Once uploaded the pcb may not restart properly, so to do that simply disconnect the FTDI header and clear JP2 jumper. Power up normally (if it hasn't already at this stage).


D0 - FTDI header / PWR_MON power monitor DI
D1 - FTDI header /  HEATER control DO
D2 - COL1 keyboard DI
D3 - COL2 keyboard DI
D4 - COL3 keyboard DI
D5 - CS1B Lcd DO
D6 - RST Lcd DO
D7 - A0 Lcd DO
D8 - SCL Lcd DO
D9 - SI Lcd DO
D14 - ROW1 keyboard DO
D15 - ROW2 keyboard DO
D16 - ROW3 keyboard DO
D17 - ROW4 keyboard DO
D19 - SHDN power DO
A6 - OUT.V.FEEDB output voltage monitor AI
A7 - BATT battery voltage monitor AI

1. Arduino I/O completely full!
2. D14 to D19 are Arduino analogue pins (A0 to A5) configured (Atmel328P) as digital pins. 



Under review.


Under review.

PHOTOS (Early June 2015 - Prototype)

IMG 1442 IMG 1445 IMG 1438


PHOTOS (Mid June 2015 - Prototype)

A bit more work done on the software, including the display:
There are 4 readouts:
- The main output as currently set at the top.
- Feedback into the Arduino of the output voltage.
- The internal battery voltage.
- The data entry from the keypad.

The keypad has multiple functions:
0 - 9 = voltage entry.
* = Use this as the D.P. when entering a voltage.
# = Use this to abort when mid-way through an entry.
* = On it's own use this to decrease the current voltage by a least significant digit.
# = On it's own use this to increase the current voltage by a least significant digit.

IMG 1446


PHOTOS (Early July 2015 - Prototype)

2nd prototype PCB built and assembled into the housing (per the 2nd video). Currently awaiting the front cover.

IMG 1477 IMG 1495 IMG 1464 IMG 1498

fin1 con1 con2 con3

con4 con5 con6 con7

con8 con9 con10


PHOTOS (July 2015)

The 2nd build.

IMG 1534 IMG 1535 IMG 1541 IMG 1536

IMG 1537 IMG 1543


PHOTOS (November 2015)

Pre-production photos.

New version of pcb, this is the LM399AH version board that I'm going into production with.

LM399AHpcb tempco1 thumb pic1



Add comment

Security code