stardance has been extended another month! the new deadline is october 31 :)

You are browsing as a guest. Sign up (or log in) to start making projects!

LM399 Voltage Standard

Hardware
  • 9 Devlogs
  • 15 Total hours

10V Precision Voltage Standard based on LM399. Can be used to calibrate other equipment. The reference is designed to be extremely stable and precise. It should hold the 10.00000V with minimal drift. LM399 is a burried zener reference, paired with extremely low drift and precise LT1001 op-amp. For setting the course gain it uses extremely precise Vishay z-foil resistors. It has a binary trim network for fine adjustments. All these parts come together to form this precise metrology instrument, rivaling professional voltage standards like ones in multimeters: HP 34401A, Keysight 34461A, Fluke 8845A and Keithley 2000.

Open comments for this post

1h 49m 48s logged

Devlog #09

I implemented some cool things, so let’s look at them.

printf

I got tired of the old way of sending data via USB (via snprintf and CDC_Transmit_FS) so I made my own USB_printf. It works almost like a regular printf. By almost I mean it does not work with floats, but that’s limited by the environment. If I ran it on linux or windows (just the formatting part) it would work fine, but on STM32 it’s a little different.
The function is just a wrapper for the old way, but with added timeout. It also checks whether any device is connected to usb, but it’s kinda weird. This way the function does not block the rest of the program when host is not connected.
Here’s how it looks:

uint8_t USB_printf(const char* fmt, ...);

So really nothing special, looks just like regular printf

Saving uptime data

Now via WriteHourStats I am able to write data about total uptime to eeprom. Inside the implementation I used something that I rarely use: union. Many people never even heard of it. Union makes all the inner properties share the same address. Example from the source code:

union HourBuffer {        
    uint8_t b8[2];        
    uint16_t b16;    
}  buffer;

No matter what I try to access, whether its b8[0] or b16 I get the same value. Well, not exactly. By accessing b8[0] i get lower part of b16, its the same as doing b16 & 0xff. Here I am writing data so I need to set b16 to a certain value. This also meant that it sets b8[0] and b[1]. This does not impact performance nor does it increase memory usage. The union is still just 16 bits. It can be done simpler but it is more readable and I wanted to use a union :) All it does is that it avoids weird pointer casting or shifting the value.

Next Steps

Now I’ll focus either on saving calibration data, that I started a little, or do something with the adc, like measuring temperature of the reference section, heater current and voltage on both +15V rails.

0
0
16
Open comments for this post

1h 30m 17s logged

Devlog #08

Overview

It’s really coming together. I added support for devices that use I2C: TMP102 temperature sensor and M24C64 EEPROM.

TMP102

I created a function in TMP102.c that reads the current temperature. It communicates with the IC using I2C.

M24C64

I created a basic library in M24Cxx.c that can read and write data to the IC. It’s fully configurable and easy to use.

0
0
22
Open comments for this post

1h 34m 26s logged

Devlog #07

Overview

I managed to get a basic program running on the STM32. It is my first time using such an MCU on a custom PCB, but it was quite easy. Also I am still learning the platform, everything is quite different from arduino. I like it though.

USB

It was the hardest part, and I spent most of my time on it. Besides issues with my code (that was expected since it’s my first project with USB on STM32) I had problems with my hardware. I spent quite a bit of time on it and solution was simple. I just had to connect it to my PC… Well, guess things work better when they’re actually connected, don’t they? Anyway, it works now. It logs it’s uptime every seconds.

LED

Also the RGB LED is red when the device is heating up and green when it’s ready to be used. Simple yet useful. I’ll have to adjust the heat up time to 15 minutes, but for development time it’s fine as is.

0
0
23
Open comments for this post

4h 5m 19s logged

Devlog #06

Overview

I finished soldering the PCB!
It looks awesome. I quickly tested some parts of it and it seems to be working.

Soldering

Most of it was easy to solder but some components weren’t easy at all. The 3V3 regulator was very annoying because of its small footprint. The same goes for I2C temperature sensor. I barely soldered them. That being said, I would still do the same in my next PCB. (I once used a 4-pad BGA sensor. At least I learned to not use those😅 )

Problems with MCU

I encountered an issue with the circuit: reset line had no pullup and capacitor. This was a big problem since it could lead to power cycling. Fortunately I fixed it by using some copper wire and some passives. It isn’t the most pretty solution but it works. I still can’t believe I forgot to add those components. At least it’s fixed now.

As for the analog part, everything seems to be just fine, still requires calibration though.

Now I should focus on the software part of the project.

0
0
21
$130 S Tier

Extremely awesome project! Make sure to organize all of your KiCad files into one folder!!
Approved!

$165 S Tier

Hey, this looks like a cool project, but the cost of components seems very high for the quality and complexity of the project. I'm also curious, why do you need a super high precision voltage reference? What do you plan to use it for? I ask because I'm actually curious. What I'll say to do right now is work on making this thing as polished as you can, and see where you can optimize cost. Go beyond slapping these components on a pcb.

Open comments for this post

2h 37m 59s logged

Devlog #05

The design step is finished!

I fully designed the PCB. The precision section is separated from the rest, PSU is far away and everything looks nice.

Digital section

I added an STM32, it tracks uptime, manages calibration data, measures temperature, measures heater current and all 15V rails. It can be connection to a PCB via USB.

Silkscreen

I left a few text fields on the silkscreen in order to write down initial LM399 voltage and other stuff: temperature during calibration, date and Serial Number.

0
0
5
Open comments for this post

45m 8s logged

Devlog #04

— PCB —

I added shielding for the precision section. All that’s left to do here is to route power, but I will do that after I route the PSU.

— PSU —

I added a 3.3V regulator for an STM32. It will use 1 16V transformer and make: 15V for reference, 15V for heater, 5V and 3.3V.

— MCU —

I am planning to add an STM32G431. To it I’ll connect and EEPROM that would store some calibration data, like date and drift.

0
0
3
Open comments for this post

1h 7m 20s logged

Devlog #03

I have mostly finished reference. I’ll tell you a few interesting things about it.

— Schematic —

Not much changed. I simply added footprints. But the thing I have to point out is the added filter. I decided to go with 50ohm resistor, 10uF aluminum cap and 100nF MLCC cap.

— Stackup —

I went with a 4-layer board. That allowed me to have a dedicated ground plane on second layer. It will improve the performance.

— Layout —

I tried to keep everything together, so all the parts will have similar temperature. Also the reference part will be on opposite side of the board compared to PSU.

That would be all. It looks like I will soon finish this project, but that will take me just a little more time.

0
0
3
Open comments for this post

24m 1s logged

Devlog #02

— Power Supply —

I made schematic for power supply.
To make 15V for the zener, I decided to go with LT3045 and 7018 for a pre-regulator. 7818 will help with noise and ripple. Also LT3045 cannot handle input voltage so 7818 steps it down first, then it is regulated to 15V.

— Transformers —

I decided to go with 2 DP-241-4-20 20V transformers. The datasheet states that it has low capacitive coupling, which is crucial for such precision standard. Higher capacitance between windings means higher common mode currents, that could potentially make measurement inaccurate. This specific type of transformer has been tested by Marco Reps in his Extreme Isolation video, with quite good result. This transformer has lower leakage that Fluke 732A. which is much better than any standard based on LM399.
It is a 20V transformer, so after rectification there will no more than 28V - voltage drop on rectifiers without a load. That’s why pre-regulator is necessary, otherwise it would fry the main LDO.
Also I used low leakage diodes as the rectifier.
The heater supply isn’t too interesting - just a 7815.
I am wondering whether I should switch to 16V transformers or not. I am not concerned about ref supply, since it draws very little current. What may be a problem is the heater supply, but i will have to do some more calculations.

0
0
3
Open comments for this post

41m 38s logged

Devlog #01

I am making a precision 10V Standard based on LM399.

— Reference schematic —

I managed to make a schematic for the reference, gain stage and calibration resistors. The output can be calibrated by soldering required jumpers that connect trim resistors.
I want to achieve sub 5ppm stability, so the resistors for the gain stage must be precise and stable.

— Power supply —

Now I should focus on power supply. The heater will be powered from a separate source. Another important thing about building the PSU is isolation. It has to be isolated from mains quite well so leakage currents will not mess up the measurements. Capacitance between transformer windings is a problem.

0
0
7

Delete project?

Are you sure you want to permanently delete this project? This action cannot be undone.

All devlogs, followers, and associated data will be removed.

Followers

Loading…