This will be a description of my process to build a new Dynamic Load.
Below is the latest version of the prototype.
I already have a Dynamic Load, described here (https://www.paulvdiyblogs.net/2015/08/dynamic-dc-power-load.html). This instrument served me well while testing Power Supplies. It is a rather simple analog Constant Current mode Dynamic Load, but also has a pulsed output possibility and an offset capability so you can set the minimum and maximum current while pulsing.
For the new Dynamic Load, I wanted to add more modes like Constant Voltage, Constant Power (wattage), Constant Resistance and a Battery Discharge option. This will mean that it will have to be a digitally controlled instrument.
There are many designs that accomplish this already, but I could only find one that implemented an AC input, next to the usual DC input. The AC capability is useful for applying a load to non-DC inputs, like an AC sine-wave coming from transformers so you can profile them, and also other waveforms like triangle or pulsed like PWM signals.
The first challenge:
The first challenge is to see if I can combine a DC input with an AC input.
Adding an AC input goes hand-in-hand with a True RMS measurement capability which is an additional challenge for me. To top this off, I also want to use the new Raspberry Pi Pico board. It has a lot of interesting features and also has a dual core. This may be required to calculate the True RMS voltages if I decide to do that in software. Dedicated chips that can do that are pretty expensive.
I have not decided on a set of specifications yet. My initial requirements for the design phase will be if I can get up to 400VAC at say 1A. A lower voltage could be 60-80V at 3A and 30V at 5A. I don't need a larger current sink, this should do for my own use.
The unit should have a "pulsed" mode to test transients, and as I mentioned above, a battery discharge feature. I'm not interested to build a PC controlled unit, that's beyond my capabilities, but I could possibly create an interface that is compatible with existing PC-controlled software applications.
The user interface itself will be very simple. I envision a rotary encoder for the settings and menus, with maybe only one toggle switch or push-button to turn the load to the DUT on and off. I will try to use the rotary encoder push button to enter values and select menus. No key-pad! The display will most likely be a small 128x128 OLED display, most likely in color because the price difference between color and monochrome is very small these days.
The enclosure should be a small as possible, because the available real-estate in my lab is very mimimal.
So there you have it.
Standing on the shoulders of others
I have been collecting various designs from others and looked at the way they did things. Several stand out, like the multi-part Youtube series from John Sculley:
https://www.youtube.com/playlist?list=PLUMG8JNssPPzbr4LydbTcBrhoPlemu5Dt
Then the contributions from Jay_Diddy_B on the EEVBLOG.
https://www.eevblog.com/forum/projects/dynamic-electronic-load-project/
I also studied the tear-down and schematics of the Array 37XX Dynamic loads done by another frequent user Kerry Wong, that can be found here:
http://www.kerrywong.com/2018/11/05/teardown-of-an-array-3711a-300w-dc-electronic-load/
Here is another one:
https://www.instructables.com/Arduino-Programmable-Constant-Current-Power-Resist/
As I mentioned earlier, I could only find one DIY design that features a true AC/DC capability. That project from Rainer Schuster can be found here:
https://www.elektormagazine.com/labs/electronic-load-for-dc-and-ac (there are two versions of diagrams available, you really have to search for the latest one)
Here is a Youtube video of the instrument with an elaborate explanation of the AC mode of operation and background theory.
https://www.youtube.com/watch?v=YXUa-xOSNLE
My Humble Beginnings.
To start with the project, I build a mimimal load circuit, with just one Opamp and one MOSFET. This allows me to study the parameters, and add more functionality as I go.
Here is the schematic diagram I'm working from:
And here are pictures of the hardware contraption:
The power connections to the MOSFET need to be as short as possible, so I mounted the current shunt, the anti-oscillation capacitor and the rectifier bridge right on the MOSFET or close to it.
The rest of the parts are not that critical.
I used my precision DC Lab supply (1mV/mA resolution) to act as a DUT, and I set channel 1 to supply 10V at 2A. Channel 2 was used to supply the reference voltage going to the positive input of the Opamp. I used a second supply for the +/- 12V rails for the Opamp.
My DMM was used to measure the Gate voltage (VGS) while adjusting the CH2 reference voltage.
Because I use a 0.1 Ohm current shunt, the relationship between the reference voltage, supplied by the Lab supply was 10mV in to get a 100mA load current. I used my LAB supply display to verify the supplied current. Setting the reference voltage to 0V produced a current of 2mA. That tolerance value can be adjusted in the final circuit with the Opamp nulling. Increasing the reference voltage with 10mV increments showed the current to stay in-step all the way up to 2A, which I set as the maximum for this test setup.
I then used my Function Generator to supply a DC pulse instead of the reference voltage. I selected 100Hz as the frequency, a duty cycle of 30% on and set the pulse with an offset of 10mV and a maximum voltage of 40mV. This resulted in a current fluctuating between 100mA and 500mA. I used my DSO to look at the Gate of the MOSFET to see the effect, and also the Source. I then increased the frequency to 1 KHz and all was well. With this contraption, it makes no sense to go further to see the maximum. I also increased the maximum pulse voltage to get a current switching from 100mA to 1.5A without issues.
I also profiled the VGS to IDS relationship, to see how much of a rail I need for the Opamp. It turns out that the MOSFET is off at a VGS of 3.08V and needs 4V to let a current of 2A through. Some more measurements are in the schematic. This means that I probably only need about 8V for the Opamp, and I also only need -1 or -2V for the negative supply to really turn the MOSFET off under all conditions, mostly when I pulse it.
What the effects of the minimum rail voltages will be with non-DC loads I don't know yet, that's something I will be able to test soon, becaus I need the analog multiplier (AD633) to do that. The multiplier is needed to "marry" the DUT waveform with the Gate voltage to make the current follow the voltage waveform in step.
Selecting the final rail values depends on the rest of the design.
Initially, I used the NPN/PNP Gate driver circuit that was in the original schematic, but decided to take it out for now. It's not needed at this moment. The MOSFET I use has a Ciss of 5690pF vs 4200pF for the SPW32N50C3 in the original design that can handle 560V at 32A. The one I use was tested in our Curve Tracer project. It is a 600V 52A device where the SOA diagram shows it can still handle 1A at 400V at a Tc of 25 and Tj of 150 degrees. If I use two in parallel, I should be able to get 400V at 1A. We'll see.
I also have two IXOS IXTH 80N075L2 lineair MOSFETS ordered, they only go to 75V and I should be able to get 4A at 50V out of one. I've never used a linair MOSFET so this is a learning experience.
The part's arrived, and I wanted to add the AD633 multiplier to my bread board. I ordered the SMD version so I soldered it on a carrier and used Rainer's original schematic to wire it up. Seemed simple enough, but when I tried it, it didn't work. There was a 25mA current flowing in the negative supply, oops!
After trying a few things I took it out of circuit and built a little test circuit just to test the AD633. No dice, I was afraid that I could have blown the part by statics, something that's very rare for me. After a while tinkering some more I decided to study the specifications some more, and then it dawned on me. The pin-out for the PDIP-8 version, that Rainer used, is very different from the SOIC-8 that I have! I don't remember to have ever encountered such a difference in pin-out between packages.
I probably blew the part by forcing -12V into the output amplifier (pin 5), which is a real bummer, because these things are not cheap. Analog Devices calls them "modestly priced packages", but with pricing close to $20, that's not modest enough for me.
I studied discrete multipliers to see if I could use them as an alternative. Unfortunately, I couldn't get LTspice to get a decent and reliable output out of a few different circuits, so I gave up on that idea and ordered a new AD633. This time from a supplier that has the PDIP version, so I can more easily use it on my breadboard, and use a socket on the final PCB layout. It will take a few days to get here.
Unfortunately, the chip that arrived does not work either. The output does not follow the inputs and is always at a fix level of about 5V, even with grounded inputs. Building the Fig 13 circuit in the datasheet shows no frequency doubling and only distorted waveforms. This chip came from a reputable supplier and I reported the issue to them. I also ordered a third chip from a supplier in France that will get here in 1-2 weeks.
Update: The supplier was so kind to send me a replacement chip, hopefully this time it's functional. The other one I ordered is in the mail. This is becoming an expensive chip for me...
I got the replacement AD633 and it seems to work in my test setup. Finally! More on this later.
I got the other chip from France, ordered from Ebay today and checked it out...not working at all! This was almost to be expected, I've reported it and asked for a refund and eventually I got my money back.
Using the good AD633JN chip, I expanded the earlier test circuit to include it.
The analog multiplier is fed with the DUT voltage at the X1 input, and the Y1 input is connected to the V-ref supply. The DUT supply is reduced 10x by a resistor divider and the X1 input is also protected by a 10V Zener. In order to get a lineair relation between the V-ref and the DUT current, I found that I needed to use a trimmer to calibrate the 1:1 relationship. Note that because of the divide by 10 operation of the AD633 multiplier, the V-ref now needs to be 10x larger, so now 100mV results in a 100mA DUT current.
Another trimmer is used to calibrate the DUT current to zero with no V-ref input. This needs to be calibrated first, and then the DUT voltage trimmer.
At this moment, I'm still using a DC lab supply for the DUT. The DC supply voltage is adjusted such that I have 10.00V at the Source of the MOSFET, compensating for the voltage drop over the bridge. This allows me to calibrate the X1 input to 1.00V resulting in a lineair V-ref to DUT current at 10V. By using the Lab supply, I can also monitor the DUT current.
Note:
Because of the input multiplication of the AD633, raising the DUT voltage to 20V also doubles the DUT current because W=(X1*Y1)/10. The microcontroller therefore needs to monitor the DUT voltage, and adjust the V-ref level accordingly to keep the current constant (CC). This is a major departure from the normal DC load functionality for a CC mode, because the voltage should be independ of the set current. (hence CC).
Using a sinewave as the input
I used a center-tapped 12VAC transformer as a DUT supply. My mains has 50 Hz. Let me show you what I'm seeing.
Here is the AC signal from the transformer. Note that it's not a perfect sinewave, but for a transformer, this is quite normal. I'm also introducing the Vrms voltages on the DSO. The transformer delivers 13.37Vrms according to the DSO, but my DMM's measure 12VAC. I trust them more. The DSO has a much lower precision.
After quite some time experimenting, I found that there is quite a descrepancy between what the DSO reports, compared to my trusted but old Fluke 67 TRUE RMS DMM, and my 6 1/2 digit Siglent SDM3065X, which is still within calibration. So take the Vrms figures reported by the DSO with a grain of salt. Read on for a clarification and solution why this is so.
For the next screen shot, CH1 is measuring the voltage accross the current shunt of 0.1 Ohm with a Vref setting of 500mV. With a DC signal as the DUT voltage, this resulted in a current of 500mA. Here we show 57.6Vrms over a 0.1 Ohm resistor, so this should represent 576mA rms. Keep in mind though that there is also the Vrms input voltage multiplier in play here.
The bridge rectifies both halves of the sinewave, resulting in the "flipped" negative side into a positive voltage. That's perfectly normal, but I'm showing it here in detail so it is clear for everybody.
As we see, the current closely follows the voltage, which is what we want and it shows that the AD633 is doing it's job.
Note that the CH2 calculated Vrms value is representing the voltage at the DC side of the bridge, minus the voltage drops over the bridge diodes. This will also be the voltage we will eventuelly measure and display.
Now back to the calculated Vrms value for the voltage accross the shunt. In the DC mode, we saw that with a Vref of 500mV, and a 10VDC input, we calibrated the system to deliver a 500mA DUT current.
With a sinewave, the DSO calculates a Vrms of 56.7mV over the 0.1 Ohm shunt so that should represent an rms current (Arms) of 567mA. This is not with a 10VDC input voltage but with an AC of 12.26Vrms.
However, keep in mind that the AD633 does not deal with rms values! One input of the chip gets a DC signal (Vref) and the other input is getting values that are represented by the CH1 yellow waveform we see on the DSO, so peak-to-peak values of a double rectified sinewave and they get multiplied together by the chip to drive the MOSFET.
Like the AD633, we would need to make calculations all along the current waveform to see if they are indeed correct.
I tried a few methods to calibrate the Vref input levels 1:1 to the current outputs. I did not really succeeed because the linearity is not that precise. Here is what I mean:
Unlike precise and stable DC signals, I'm afraid that with AC waveforms, the instrument will never be precise. This seems to be a function of the crest factor (how pure is the sinewave) and how much is the voltage deviating with higher currents, which will influence the multiplication. Also the multiplication itself is not perfect and not 100% lineair.
Using a triangle as the input
To test another kind of waveform, a triangle, I used the DUT supply from my Curve Tracer (described in another blog post). Applying 30Vp-p and using a Vref of 500mV produced the following display:
The current waveform is nicely following the voltage, with some abberations at the null transition.
A triangle with 30Vpp and a calculated Vrms of 16.22V results in a shunt voltage value of 80mVrms or 800mArms and 162mVp-p or 1,62Ap-p. The crest factor is 1.732, so if we divide 800mArms by the crest factor, we get 461.9mA. Reasonably close but again, this is not good enough for a precision instrument.
Profiling a transformer
One of the applications I had in mind of the AC/DC load, was to profile transformers. I once took a transformer out of a printer, but it had no markings. I ended-up using power resistors to figure out where the serious voltage droop level was and used those numbers.
The transformer I used for the first measurement is a center tapped 12-0-12VAC transformer, rated at 2A. To check that, I connected one of the 12VAC windings to the dynamic load and turned-up the current until the transformer could no longer output 12VAC, and the voltage dropped off rapidly. I used one DMM to measure the transformer AC output, and looked at the DSO for more clues.
The DSO reported 14.29Vrms for the transformer output, while the Fluke 76 showed 14.68VAC. That's close enough for the DSO.
The good news was that I could turn up the Vref voltage to 2.2V = 2.2A before the AC voltage dropped below 12V. The Fluke reported that happening with a current of 1.98A. This seems to prove the value of this instrument.
This is what the DSO shows:.
I guess this begs the question how good we can make this particular measurement without using the DMM's, and use the Arduino and ADC's to measure and report the RMS voltages and current.
That task will be addressed next...
Preliminary conclusion
My original plan was to build one instrument that could measure CC, CV, CW, CR and have a battery discharge option, both for AC and DC inputs.
After making the above measurements and analyzing them, I came to the conclusion that this is too much to ask for. The mere fact that we need a multiplier in the circuit for AC signals, defeats the "constant" elements of all the measurement. In my world, a Constand Current (CC) means that whatever the input voltage is, the current is kept constant, in real-time. That is not really possible with this circuit, because the microcontroller contineously needs to measure the input voltage and re-calculate the current setting to keep the set current value. This would require a tight PID loop which will really task the Nano with all the other tasks. In any case, I would call this a pseudo CC. The same is true for Constant Voltage, Constant Resistance and Constant Power.
This is a significant deviation from the "traditional" method that uses the microcontroller to setup the measurement and display the results, while the dynamic load circuit itself does it's job "unattended" and in real-time.
So my conclusion at this moment is that it will be really hard to marry AC and DC input values with the same hardware. Everything will have to be under tight real-time control by the CPU.
So what are the options?
1. Build a simple AC/DC load
You can build a simpel instrument for AC and DC signals only that is probably limited to a pseudo real-time CC mode with limited measurement precision. As we've seen already, it can be used to profile transformers and the likes. To keep it simpel, there will be no real CC load, just a load you set regardless of the voltage. This will have limited precision, but will function as a load.
2. Build a full fledged DC load with high precision
This is a dedicated DC only instrument that can be fitted with all the required modes and that can have a very high precision. This has been done many times already by others and is less of a challenge for me.
3. Build a combined AC/DC load with CC, CV, CR, CP
If you want to have real (true) CC, CV, CR and CP modes, this will be a compromise due to the loss of precision, unless this can be fixed somehow in software. It also needs a very fast and tight control of the current while taking the DUT voltage changes into account. I'm expecting that will be beyond the capabilities of an Arduino Nano. I have experimented with PID loops before and I'm not very good at the tuning part. Overall, I'm not sure if I can do all that and so I'm not too keen on taking on that development.
Having said all that, I need to rethink my goals and for now I will continue with the development of the combined AC/DC signal input, but first try the capabilities of software RMS measurements first and see how far I can get.
This is a good time to start with the voltage and current monitoring by the Nano.
I added the ADC components to the schematic.
I found two libraries for the ADC I tried, but settled on the Adafruit version.
I also figured out why I blew the ADS1115 chip. The prototype that I put together had the -12V and the GND rails on the top side of the breadboard, and when I wanted to ground one of the ADC inputs, I must have touched the -12V rail, blowing the input protection diodes and then taking the rest of the chip with it.
Overall, the prototype was getting unwieldy by now and with so many connections I was having problems. Now that most of the circuits were sorted out, I soldered everything on a proto-board, using sockets for the chips.
I also put together a small and rough test sketch together for the Nano such that I can now display the DUT voltage and the DUT current on the OLED display. Right now I only display DC voltages and currents.
This is as far as I got today, I'm pretty happy with the results.
Now that I'm satisfied with this setup and sketch, I'll turn my attention to converting the measurements to RMS. I expect that will be a challenge (it was!). I've got a pretty good idea now how to convert a voltage to RMS (not!), but need to pick a method out of the several that I found, and then see if I can implement it on the Nano.
Unfortunately, I ran into an issue that stopped me from going forward. Have a look below at the topic called: "Calculating the RMS value of a waveform" for details and a solution.
So with the RMS calculation topic more or less solved and underderstood, I can now start to use it with the prototype hardware. First of all, I needed to eliminate the AD1115 out of the circuit and preplace it with the on-board Nano ADC's.
After a lot of struggles, see the RMS and ADC topics below, the prototype hardware is now working with the on-board ADC's from the Nano, and are producing results for the DUT voltages and the voltage across the shunt.
What I knew, but initially did not factor in yet, was the drop and change of the AC voltage before and after the bridge. Sounds simple, but isn't. This drop is not just caused by the bridge diode drops alone. As an example, using my 12VAC transformer, my DMM shows 14.48Vrms before the bridge, and 6.26Vrms after it. My DSO agrees with both values. BTW, in the DC mode, the DMM shows 11.70V after the bridge.
I need to measure the DUT voltage after the bridge, but show the value from before the bridge. Rainer used an Opamp to create this factor (using a 0.15 divider and then 3.26 gain) and software to further tweak it. Keep in mind that he also used a different RMS calculation without determining the "AC level". I used my DMM to calculate the conversion factor and added that to the script for now. It's OK but the compensation is not very lineair with higher input voltages.
What I did find however, is that the measurements fluctuate and are certainly not useful at all with 3 decimal digits. Two are more than enough and give me room to display the rms suffix. I first need to add Opamp buffers for the two ADC inputs to reduce the noise and take care of the Nano capacity switching at the front of the Mux.
Obviously, with the RMS setup I have now, I can't measure DC levels anymore.
It's also becoming clear to me that I don't need a very precise DAC anymore. I think I can manage by using the Nano's PWM feature and create a poor-mans DAC. I'll try that soon.
Latest schematics:
The sliding switch on the left edge is the AC/DC mode switch.
Now I don't need to connect the Nano to my PC to make it run.
A heads-up for a potential risk
Let me add a word of caution at this stage of the design.
When you are going to connect the Dynamic Load circuitry to a real DUT, especially one with higher voltages, and also connect a USB cable between the Arduino Nano and your PC, you run a big risk!
The GND of the Dynamic Load circuit will be connected to the DUT GND or one side of the AC connections, and through the USB cable, also to your PC. Depending on what your DUT is, and what the ground potential is, it is entirely possible to blow-up your PC or as a minimum the USB interface if it's earth ground connected.
I strongly recommend you to use an optically isolated USB connector interface in-between the Arduino Nano and your PC.
Don't risk it, use an optically isolated adapter, they are a lot les expensive than a new PC. Here is one from Adafruit, it sells for $35 but you can get less expensive ones as well. Amazon sells one for $15. I got myself an even cheaper one from Aliexpress because the USB transfer speed is less important for this application.
Understanding the reported values
Input attenuation circuit
At a post below, towards the end, I discussed the way I intend to do the input attenuation.
Here I have added the schematic with the 400V/100V input attenuation and the selection jumper and that's what I now have in the prototype as well.
Here is the latest version of the prototype:
Compared to the earlier picture above, in the top left is the carrier with the LTC1966, above it is the TO-92 -5V regulator. In the same row, to the right of the blue trimmer is the Opamp used for the protection of the LTC1966 input signal. Top right has the jumpers for the h/w or s/w RMS calculation setting, and the jumper for the input attenuator that now selects between 400V and 100V.
On the display you see the measured RMS voltage, calculated so it's reflecting the input to the bridge, and the resulting DUT current. The last line in white shows that the mode is AC and the current setting by the rotary switch is set to 200mA.
Next step is to spend some more time making measurements...
I'm taking a break from this project
At this moment, I'm taking a break from this project and I have put further developments on hold for now. It's working OK, and it was a great learning experience, but I'm not satisfied with the results.
I arrived at a pretty complex and rather expensive contraption for what it does but it does not deliver on my initial expectations. There are simply too many "fudge" factors needed to make it produce reasonably close measurement values, and they are not even very precise to boot. I'll try to work with it for a while and make some more measurements.
Maybe I can find a better method, maybe this is the maximum that can be achieved. If so, I'm very dissapointed, but time will tell.
Stay tuned, I may be back with more...
All code and other information about the project can be found here:
https://github.com/paulvee/AC_DC-Load
In the following sections, I will select certain sub-projects and describe them. Eventually they could or will hopefully be used in the final project.
The Micro Controller
Rainer used an 8-bit MEGA32-P as the controller. It has a 10-bit ADC function that Rainer used to measure the DUT voltage, and he used a 12-bit MCP4921 DAC to generate the voltages to drive the MOSFET.
The 16-bit dual core Pico I plan to use is the "H" model and has three 12-bit ADC's that can be used. It does not have a DAC function. You could use two PWM outputs combined to serve as a pretty good 16-bit DAC, (the GPSDO project uses that to drive the OCXO - described in a post) but I'm going to use the same SPI based MCP4921 DAC.
Rainer used seven 7-segment displays driven by a MAX7219 controller. The display I'm initially planning to use is an RGB 128x128 OLED display based on the SSD1351. It has an SPI interface.
Unfortunately for me, Rainer used Basic as the programming language for the MEGA. I am familiar with Basic as a language, but have never used it for embedded controllers other than for a few small PICAXE projects. I have more experience with Arduino "C++" and Python for the RPi. I will initially plan to use MicroPython for the Pico, which is also new for me, so this is going to be a bit of a challenge.
First of all, I will need to create my own "programming environment" for the Pico, and get familiar with that, so this will take some time.
Setting up the Arduino IDE for the Pico was fairly easy, and I got the Blinking LED running without too many issues. However, after trying for a few hours, I could not get the SSD1531 OLED display working without compiling errors. In any case, afyter a lot more searching, it seems that the SSD1531 library is not yet supported by the Pico environment using the Arduino IDE.
The next step was to install the Thonny IDE and start to use that environment. I saw that Adafruit is supposed to have the SSD1351 supported with MicroPython/CircuitPython. Installing Thonny was easy, and again I got the Blinking LED program running quickly. Unfortunately, I was having difficulties installing the libraries for the SSD1351. I used the Adafruit set of libraries, but in their attempt to be all for everybody, they make it way too complicated. I might be wrong, but I came to the conclusion that their SSD1351 support does not run on the Pico.
After many hours trying and searching the internet, I found very few displays supported by the Pico, and not the one I have or one I want to use. I also learned that the Pico ADC has some issues.
For this project, I decided that I will not use the Pico and CircuitPython and will switch to an Arduino Nano and C++. If I find that I'm running out of room and need more power, I can use the same code on a faster 16-bit ESP32. The Nano only has a 10-bit ADC, which effectively is really an 8-bit ADC and also the 12-bit ADC on the ESP32 has some issues so I'm going to use the dual 12-bit ADS1115. (or so I thought...)
Decoding a Rotary Encoder
The OLED display
Several years ago, I already started on a sketch to use the OLED display to see how I could use it. I wanted to experiment with the code to select and change values, by stepping through the digits and changing them. I also wanted to get a rough idea on how to use the display and the encoder as the user interface.
A picture of the resulting code (an earlier version) on the display gives you an idea what of I have in mind for the user interface for this project:
Short clicking the rotary encoder switch button will cycle through the digits one by one left to right and then right to left on the Amp line. Rotating the encoder will cycle through the values of a digit. At this moment, only 0-9, it does not yet overflow to the next or previous digit. Stepping through the digits will change the color to red of the digit you can change. The sketch recognizes short, double, long and very long button presses, which is how I plan to switch to and through the menu system.
At this moment, a double click will toggle between the input/edit mode and the display mode. In that case the selected values will be send to the DAC and the display will start to show the actually measured values. You can still cycle through the digits and adjust the values so you can change the settings on the fly, at least that is what I envision. How well this works will need to be tested with the real hardware supplying values.
I anticipate to always measure the DUT voltage, but the second line will show a measurement of whatever value the system is in like current in the CC and CV modes, Wattage in the CW mode, Ohms in the CR mode and the capacity/time in the Battery discharge mode.
Curently, the sketch uses a two interupt software method to decode the rotary switch that does not need any capacitors or resistors to debounce. For the moment that works really well, but I may need an interrupt for something else in which case I can no longer use this method.
The four single pixel dots in the four corners of the OLED display are there to show me the boundaries of the active pixels during testing and positioning of the text. (it's hard to see where the active pixels are)
Calculating the RMS value of a waveform
I spent several days on and off writing a script to calculate the RMS equivalent voltage of a sinewave signal. The process is rather straightforward. You need to sample the waveform enough times to get a full cycle covered with enough samples, or better yet, get two cycles covered. To simplify the rather extensive theoretical formula, the sampling needs to happen at the same time interval. That's easy with a Nano, using one of the timers to create an interrupt during which you take an ADC measurment. When you have enough samples, you then apply the mathematical stuff, en presto, you have an RMS value of the waveform. Sounds simple...
It was very gratifying to see that the Vrms calculation of my DSO agreed with that of my sketch. Unfortunately, the two true RMS DMM's that I used to verify the result, did not agree at all. It took me several days and quite some time to study this issue and search for an explanation, to no avail. I could not figure it out. I was obviously missing something, but what?
I even used Excel to recreate the waveform from the ADC samples to see how well the script worked.
Everything seemed to be working as intended.
Frustrated, I posted a question on the Arduino forum, and asked for help. The answers put me on the right track to zoom into the root cause of the issue. And I found it. Have a look here:
https://forum.arduino.cc/t/rms-calculation-does-not-agree-with-dmms/1032069/7
A good theory can be found here:
https://masteringelectronicsdesign.com/how-to-derive-the-rms-value-of-a-sine-wave-with-a-dc-offset/
So I now modified my sketch to take the offset issue (make the input signal AC coupled) into effect, by using a library that I found earlier but could not get to agree with my measurements. They were wrong, of course, so when I tried the library with my new found knowledge, it worked flawlessly. I then modified the example script to use interrupts. I put this script and the DSO screenshots for various inputs on the Github.
Here is an example of a double rectified sinewave, which will be the input from the bridge.
The screenshot shows the signal generated by my AWG. Its a 2Vpp signal of 50Hz, which is supposedly acting like the result of the bridge being fed with a 50Hz mains sinewave, becoming 100Hz.
Note that I have to use AC coupling for this input channel, to make the DSO RMS calculations (shown here as Per.Vrms) the same way a DMM does, so they correspond. This allowed me to finally compare the results with the script.
The blue trace shows the sampling of the waveform, there are 40 of them, to really cover the waveform well, and eliminate drift of the calculations.
The Vrms output of the script is virtually the same as the Per.Vrms calculation of the DSO, and is also is very close to my 6.5 digit DMM. I verified the operation of the script with a sinewave, triangle, block (a simple and good test) and the above signal, and the results are very good and accurate.
One caveat of the obtaining the "AC" value by the offset calculation is that it takes about 6 cycles from the start to get a good RMS result.
Onother caveat is that the RMS calculation method for the AC waveform also renders the calculation of DC inputs useless, they will always be zero volt. I'll save that challenge for later.
Using the ADC1115 with the RMS conversion
Unfortunately, I found more limitations for my prototype setup.
After modifying the scipt I used above for the RMS conversions and use the ADC1115 instead of the on-board ADC, I found that I can't read the ADC1115 within an interupt service routine. This is because the I2C interface, that is using the Wire library, hangs the Nano in the ISR. The Wire interface itself uses interrupts. I found a different Wire library that does not use interrupts, so potentially I could use that, and also use direct register programming to communicate with the ADS1115, and not use a library, but either way, the serial interface will most likely slow it down too much.
The RMS conversion formula relies on the precise timing between the samples, so I want to continue to use the Timer. The only way use the timer interrupts is then to only set a flag in the ISR, and act upon that in the main loop, which is what I tried. Unfortunately, while modifying the RMS sketch to use the ADS1115 in that fashion, I found to my dismay that the fastest I can read and process the AD1115 sampling in the main loop is about 20ms.
That realization started a few hours of trying and investigating this issue. Here are two screenshots of my findings. The first one was made with a script that is only the toggling an output pin within a for-loop, nothing else. That needs about 7us and is normally the fastest the Nano can run. The next screenshot is with only the ADC read cycle added, and is shown in relation to a 50Hz signal. This time it needs about 20ms.
That's nowhere near fast enough to realiably sample a 50Hz input signal. As a minimum, I need 1ms samples. Bummer! I tried two other ADC1115 libraries, the fastest one I found uses the TinyWire library and that produced 8ms cycles. I did not know about that limitation, this is a rude awakening...
This seems to indicate that I can't use I2C-based chips, due to the slow serial interface, for the sampling of analog signals with an Arduino Nano. I don't know if SPI is any better, I'm assuming it will be the same so I'm not even going to try.
I could change the processor and see if I can get higher speeds, which must be possible, but for the sake of KISS I'm sticking with the Nano for now.
Using the Nano ADC with the RMS conversion
The only method I know of that can handle the ADC sampling fast enough is to use the on-board ADC from the Nano itself. That only has a 10-bit resolution, but from what I've seen so far with the RMS conversion and precision (or lack thereof), that's actually not a limitation at all. So, I can go back to the RMS test program and start use that with the prototype hardware.
I modified the script again and I'm back in business...
This is with 40 samples, as you can see, it covers two 50 Hz cycles and that also reduces the drift caused by the rms calculations. With drift I mean that the resulting RMS value slowly drifts up and down in a sine shape around the center value.
I'm using a square wave here because the RMS calculation is simple to verify, it will be exactly 50% of the Vp of the input signal.
The next challenge is to process two ADC inputs and convert them both to RMS. The current library cannot handle that.
Designing a poor man's DAC
Because we really don't need the precision a real DAC can deliver, we can get by with a poor man's version, using a PWM signal and a digital filter.
To make the filter more effective, we need to increase the base frequency from the Nano that is normally 488Hz. When you program the registers, you can increase the frequency to 3.906Hz.
This makes the filter values smaller and the resulting DC voltage cleaner. The filter can be seen in the latest schematic diagram. Note that normally you would use a buffer to avoid loading the filter, but because the filter goes straight to the high impedance AD633 Y1-input, it is not needed.
I'm using the rotary switch to drive the PWM output, and limited that to 255 settings. With a 5V maximum of the PWM output, this translates to 20mA per step in the DC mode. In the AC mode, we need to adjust the value to RMS, and I did that by dividing the 20 mA steps by 1.4141 resulting in 17mA-rms per step.
I'm displaying this value on the OLED display to you can see what current level you are setting, and let the display also show the actual results.
Automatic AC/DC mode switch
Hardware True RMS to DC solution
There are two devices that are used a lot, the ADC736 and the LTC1966. The latter is more modern and less expensive. It uses the delta Sigma conversion method.
This is from Digikey: Explanation of True RMS to DC convertors
I want to try the LTC part and ordered three. I also created a little test board that will allow me to play around with it. Using a breadboard is a recipe for disaster because the inputs are low voltage and sensitive. I already lost too many chips for this project by mistakes using breadboards.
Here is the schematic that I put together. There are PCB boards available on the internet, but they are either pricey or not as flexible.
It took a while to get things back on track after my vacation, especially getting over the 7 hr jet-lag. I built the test circuit for the RMS convertor and made a number of measurements using the different modes of the chip.
Here are some of the results.
I'm using the single-ended input that is AC coupled to the chip. I used my FG to output a sine-wave signal in 100mV steps all the way up to 1V.
The input/output linearity with a 5V single supply:
This is quite dissapointing because the specification lists a 0,02% linearity. I also noticed a 2mV offset with no input.
When I switched to a +/-5V dual supply, things got better. The offset dropped to 0.5mV and the linearity improved remarkedly:
I wonder why this single vs dual supply effect is not listed in the data sheet, nor in the various posts that I found using this chip?
One of the difficulties I had with the software RMS calculation for the full-wave rectified signal was that I could not figure out a reliable factor. So I tested the RMS to DC conversion by setting my Function Generator to output a full-wave rectified signal and try it with various input voltages. The theoretical factor should be 1.11. That's now much closer.
I can use that factor now to work out what the AC input voltage is, by measuring the full wave rectified signal on the other end of the bridge and than multiply this with the 1.11 (or the actually measured 1.14) factor.
The maximum input signal for the LTC1966 is 1 Vrms so I need to find or design an automatic ranging/attenuation circuit with probably two or even more ranges, to keep the accuracy high.
Another decision I need to make is if I want to use the RMS-2-DC convertor chip only for the voltage measurement, and keep the software calculation for the current as is, or use two chips.
I modified the prototype and added the LTC1966 circuits. I also added a jumper to change the input voltage attenuation to accomodate the maximum input of the LTC1966, which is 1V.
I then modified the software to use the resulting RMS value of 0..1V DC. It's on the Github.
To convert the True RMS DC value back to the AC input, I used the input attenuation factor, the double rectified factor, multiply that with 2 to get back to a full wave, and then add the bridge diode losses.
Now the acid test for the linearity of the input signal:
Applying one tap of the transformer, I measure an input of 14.5 VAC with the DMM and I get an output that fluctuates between 14.0 and 14.7. When I use both transformer taps in series, I measure 28.97 VAC on the DMM, and I get an output 28.89 to 29.5V. That's good enough for now.
I now have an almost perfect tracking of the input voltage. Right now I'm continuing to use the software RMS calculation for the DUT current because that seems to work fine.
Below are the latest schematics.
I added two jumper configurations (top right) that let me switch-in the True RMS chip circuit, and also change the input attenuation from /10 to /60 to accomodate the maximum input voltage of 1V input for the chip.
Above is the almost text-book and simple circuit for the chip. I put the tiny CMS8 chip on a DIL carrier so I can use the normal dip-8 configuration with a socket on my prototype. I'll post a picture later.
Clamping the input signal
The LTC1966 has a maximum input of 1 Vpeak. It needs an input voltage attenuator to get the input value to within that maximum input range. Because we could have high AC input values, and the chip is not particularly inexpensive, it really can use some protection.
In "normal" cases, like for an Opamp inputs, you would use diodes to clamp the input to the rails. This will limit the input to the rails plus the diode drop. An adequate protection in most cases.
However, the LTC1966 needs a clamp for a 1V signal, not the rails. In our case, it cannot get below ground so we only need to deal with the positive input voltages. It took me a while to figure out how to do that. I initially used a few diodes in series to clamp the input signal, but the clamping was not "hard" enough. I did not have a Zener diode or a voltage reference for 1V, so I used an Opamp circuit to create an active clamping function that can be easily adjusted.
Here is the LTspice circuit I ended-up with:
Instead of a sine-wave for the simulation, I used a triangle waveform, because it is easier to see where the clamping starts. A sine-wave will get a distorted top, so a little more difficult to see. I'm now working on the premise that my first range will be for 0..30VAC, so that's what the input divider R1/R2 is for. 30V in results in 1V out.
R7/R6 is the voltage reference for the Opamp. It is set such that this voltage plus the voltage drop over D4 is just over 1V, the clamping level I want. When the Vin signal is getting byond 1V, the Opamp will start to draw current through D4 away from the R1/R2 voltage divider, in effect clamping the signal. A more logical point to connect D4 to seems to be the other side of C1. LTspice showed some weird side-effects so I kept it where is it.
Below is the effect with an input voltage of 35V, which is just clipping the input signal at 1V:
The signal is nicely clamped at 1V, protecting the LTC1966. R3 will limit the current going to the input pin so will protect the internal ESD protection diodes and so the chip will survive. I'm showing 1K here, but in my circuit I'm using a 10K to be safe.
Here is the result with a 50V input signal:
It's easy to tune the maximum voltage by changing the R7/R8 reference voltage for the clamping Opamp.
The next step is to design an (automatic?) input attenuator like an auto-ranging multi-meter so I can also input much higher voltages and measure them without causing problems, I hope...
Input attenuator
To make it easy on myself, I put the automatic attenuation feature on the back-burner. After thinking about it some more, I think I can get by with only two input ranges. I will always know what range I'm going to need, so I'll just start with a jumper selection while I'm testing this out.
After doing some calculations, I decided to create a maximum 400VAC input range and also a 100VAC range. This will cover most of my needs. I want to have 1V full scale in either range as the input to the LTC1966.
I also want to have a high enough impedance to limit the current flowing into the input. The maximum voltage is already protected by the limiter circuit above.
The resulting input divider now consists of a 1 Meg source resistor, with a 3K3 parallel to a 10K to ground for the 400V input range. The 3K3 and 10K in parallel result in a 2K5 value. This drops the 400V down to 1V. By switching the 3K3 out of circuit in the 100V input range, the 1M and the 10K also provides a 1V maximum input signal.
The default should be that the 3K3 is always in circuit at power-up to create a 400V maximum safe input situation. I will use a jumper on my test setup initially, but later use a MOSFET to activate the resistor, and make it the default when powering the instrument. The software can remove it for the 100V range.
Using the 400V setting with a rather low 10V input level will still result in a 22 mV input value to the LTC1966, which is comfortably above the minimum of 5mV the device needs to function properly.
Maybe I don't even need the 100V range. More testing will help me decide if that makes sense and if I have enough of a resolution and precision.
More info will follow...
If you like what you see, please support me by buying me a coffee: https://www.buymeacoffee.com/M9ouLVXBdw
6 comments:
Hi Paul. I am also investigating this topic and has found the following website. This guy also has an extensive video series about his project. I think he has got a very usable project. Wesite: http://www.scullcom.uk/design-build-an-electronic-dc-load-part-1/
Yes I know, this is the John Scully I referenced in my blog at the top. I'm a big fan, and actually build a few of his designs. Unfortunately, in my opinion and that of others, he kind of botched the design with the many kludges to get rid of offsets.
Ok ... was not aware of it. Will appreciate if you will keep me in the loop with your efforts. I need a unit that can test the output off a Electric scooter's charger with the following specs: O/p = 67.2V and charging current is 2-3 Amps. Here is another one ... https://www.instructables.com/Arduino-Programmable-Constant-Current-Power-Resist/
The MOSFET you're using is a BEAST, I like that a lot but the new generation of MOSFETs are designed for switching applications, here's the hint in the datasheet; "provide superior switching performance".
Take a look at IXYS linear MOSFETs.
You're investing so much on this project, reduce the shunt value to 10mΩ. this way you can pull over 20A from DUT!
Thank you Hamed. As I mentioned in my post, the MOSFET I'm using is a left-over from my Curve Tracer project. I also have an IXYS linear MOSFET that I still need to try. I have no need to draw more Amps, but that's certainly possible. At the moment, this project is on hold, waiting for a need, or actually, more inspiration.
I was aware of the article, but thank you anyway.
Post a Comment