Saturday, January 9, 2016

Stemming the Tide: RC Time Delays with bc

This one was inspired by this post on debian-user:
I mentioned in my general blog that I feel kind of sad that this kind of information is getting harder to find:
Someday I'll expand on the idea of too much information being less information in my freedom isn't free blog blog

Today, I'm going to try to stem the tide a little bit, by talking about using tools that are should be available on everyone's computer or smart phone terminal to help solve a moderately simple electronics problem. 

One of the regular participants in the debian-user mailing list had a question about using an RC circuit. He has a DC powered milling machine that he needed to build a power supply for, and he wanted to build a switching power supply. 

Switching power supplies, without a slow-start circuit, draw enough power to throw your circuit breaker on start-up, so he needed to build a slow-start circuit. And he needed help with the physics and was asking for a tool to help do a units conversion.

The physics he needed are mostly explained on these pages on wikipedia:
That helped me refresh my memory, as well.

He didn't need the conversion as much as the formula for the delay characteristics, and he also needed a calculator that would work the formula for him in a loop so he could try different sizes of capacitors and resistors and get an idea of the power draw over time.

There are lots of calculators that let you punch in numbers, but when you have to repeat the same series of calculations lots of times, you tend to make mistakes. That's one of the reasons being able to run a loop is important.

When you think of a calculation loop, you tend to think of programming languages. Perl, Python, Ruby, FORTH, etc. But programming is a scary topic for many people. (Most people? I think it should be taught in the primary grades, myself.) 

If you know about the interactive modes of the above four languages, you know that they can be used like a programmable calculator. 

Perl is installed as a part of almost every Unix-like OS. But perl's use of dollar signs makes it feel arcane, and if you have heard of regular expressions, you may think the name of the language makes your head implode. 

FORTH's postfix notation may also make you hesitate.

Python and Ruby may need to be installed, and installing may be scary.

Maybe all of that tends to make you shy away from programming.

But there is a basic, easy-to-use, multi-precision calculator, bc, that is available in just about every workstation or server installation of various Unix and Unix-like OSses, including Linux and (I think) still on Mac OS X (but not Android!), and can even be installed on MSWindows. (But not so easily on Android! No-root-debian is a bit of an SD hog.)

Okay, so, enough with the sales pitch for bc. Let's see it in action on this problem.


I demonstrate some idealized circuits below. They are dangerous as shown for a variety of reasons. Electronics parts used incorrectly can burn, explode, cause serious damage, and cause permanent injury including blindness, lung damage, and death.

If you don't know how to build circuits like these correctly, you are very likely to hurt yourself and others badly. If you know how to build these circuits correctly, you should have no reason to build them.

And any rate, don't try to build them without proper supervision by people who know what they are doing.

If you really want to experiment with this stuff, find yourself a switching power supply kit from a reputable kit seller and build that, instead.

Switching power supplies are kind of like the bucket showers you use at camp. Fill it up and you can get a nice shower for a short time. As long as you keep it more than half-full, the stream from the shower is, well, not too bad.

Unfortunately, the bucket metaphor gets really laborious from there. Wikipedia to the rescue again, if you want to know more:
In the metaphor, we use a capacitor like a bucket:

But if you hook a capacitor across line voltage this way in your house, the capacitor suddenly draws a very huge current for a few milliseconds, 120 times a second.

That's dangerous! 

A few milliseconds every eight and a third milliseconds is not a short time, really. We'll see that better, below.  

[Update 20160111 part 2:
Not incidentally, most large capacitors are polarized. A polarized capacitor hooked as above across an AC house power source will definitely burn, and very probably explode. That is, I don't know of a polarized capacitor in production with a high enough reverse rating to withstand household AC power.

(Polarized capacitors must be hooked up correctly, positive and negative to the corresponding power wires. AC power is switching positive and negative 60 times a second, so there is no way to hook it up correctly without rectifying it first.)

[Updated to correctly describe the AC physics. Apologies to the first ten or so people who read this rant while I was forgetting to explicitly deal with the current reversals inherent in AC. JMR20160111]

If the power were DC, that current would quickly drop to a sort-of manageable current as the capacitor charges. [Update JMR20160111: In AC, as above, in the milliseconds after the capacitor is charged a little, it gets forcibly discharged, which is also potentially dangerous.]

If the capacitor is very large at all, it could pop the circuit breaker, cause brown-outs and spikes, and do other things that are not nice to your power circuit and devices plugged in on it [Update JMR20160111: ... assuming the capacitor is properly rated and can survive being hooked up like this]

If your house is not well isolated electrically from your neighbors' houses, they would have serious reason to complain, too. 

So you want a resistor in series with the capacitor. And let's rectify the house current, while we're at it, so we can keep the capacitor charged.

Now, ultimately, we'll have some other circuitry, a relay, or an SCR or something, to take that resistor out (effectively short across it) once the capacitor is charged. Otherwise, the device is not going to get enough power to run, because the resistor will be eating up the power, instead.

So, you want to know how big a resistor you need for a capacitor large enough to drive the device. 

Say you don't want to draw more than 500 Watts instantaneously. 120 volts AC will push 170 volt peaks out of an ideal rectifier, so we'll use 170 volts in the formula. At start, the capacitor will be a dead short, so the resistor is what you pick. Remember Ohm's law:
  • E = IR and P = IE
  • R = E/I because we want R
  • I = P/E so we can get rid of I
  • subsitute: R = E/(P/E) 
  • normalize: R = E(E/P) or E2/P
  • substituting the numbers: R = 1702/500
You don't really need a calculator for this, do you? (Heh.)

Well, okay, you don't want to rely only on doing it in your head. Get a shell and fire up bc. You might as well bring in the math library, too:

$ bc -l
A sixty ohm, 500 watt resistor will keep the house from catching on fire, and be friendly to the circuit breaker and all your appliances and your neighbors.

Double checking,
$ 170/60
2.833 instantaneous amps. That's about what to expect, given the numbers, but, that's a lot of current. Let's see. 500 watts is a samll to medium room heater. Even preferring the RMS power, 240 watts is still a lot of heat if the capacitor should ever fail shorted.

Which wouldn't protect the house from burning down in the worst case, after all.

So, instead of a 240 watt resistor, we actually want a resistive fuse able to handle about 500 watts for a fraction of a second, but burning out if it sustains more than 250 watts (2 amps) for more than several seconds.

But the mill then needs to be able to safely power down suddenly if we do it that way. So, probably, we'll actually use a high-power transistor here that senses the voltage on the capacitor and drops the impedance as the capacitor charges. But that's for a later step. Right now we want to know limits.

We want an idea how fast the capacitor will charge. That's where the ability to run loops in bc comes in handy:

You can do this in bc:

define vc(vs,t,r,c) {
  return vs * (1-e(-t/(r*c)));

scale = 5;
vs = 120;
r = 60;
c = .01;
for ( t=0.0; t<5.0; t += 0.1 ) {  
  vc = vc(vs,t,r,c );
  vr = vs - vc;
  a = vr / r;
  p = vr * a;
  print "t: ", t, "  vc:", vc, "  a: ", a, "  p: ", p,  "\n"

[Update JMR200160111:

Select between the lines in your browser, and paste with right-click into the terminal bc session you opened up for the simple calculations above. ("bc -l" if you didn't do that yet.) 

You may need to hit the return key after pasting the code in. 

It works in the version of bc in Debian. openbsd's bc wants variable names to be only one letter long:

define v(s,t,r,c) {
  return s * (1-e(-t/(r*c)));

scale = 5;
s = 120;
r = 60;
c = .01;
for ( t=0.0; t<5.0; t += 0.1 ) {  
  v = v(s,t,r,c );
  z = s - v;
  a = z / r;
  p = z * a;
  print "t: ", t, "  vc:", v, "  a: ", a, "  p: ", p,  "\n"


And the output looks like this:

t: 0  vc:0  a: 2.00000  p: 240.00000
t: .1  vc:18.42240  a: 1.69296  p: 171.96681
t: .2  vc:34.01640  a: 1.43306  p: 123.21965
t: .3  vc:47.21640  a: 1.21306  p: 88.29087
t: .4  vc:58.38960  a: 1.02684  p: 63.26402
t: .5  vc:67.84920  a: .86918  p: 45.32843
t: .6  vc:75.85560  a: .73574  p: 32.47880
t: .7  vc:82.63200  a: .62280  p: 23.27279
t: .8  vc:88.36920  a: .52718  p: 16.67512
t: .9  vc:93.22440  a: .44626  p: 11.94887
t: 1.0  vc:97.33560  a: .37774  p: 8.56125
t: 1.1  vc:100.81440  a: .31976  p: 6.13478
t: 1.2  vc:103.76040  a: .27066  p: 4.39541
t: 1.3  vc:106.25400  a: .22910  p: 3.14920
t: 1.4  vc:108.36360  a: .19394  p: 2.25676
t: 1.5  vc:110.15040  a: .16416  p: 1.61691
t: 1.6  vc:111.66240  a: .13896  p: 1.15859
t: 1.7  vc:112.94280  a: .11762  p: .83006
t: 1.8  vc:114.02640  a: .09956  p: .59473
t: 1.9  vc:114.94320  a: .08428  p: .42618
t: 2.0  vc:115.71960  a: .07134  p: .30536
t: 2.1  vc:116.37720  a: .06038  p: .21874
t: 2.2  vc:116.93280  a: .05112  p: .15679
t: 2.3  vc:117.40440  a: .04326  p: .11228
t: 2.4  vc:117.80280  a: .03662  p: .08046
t: 2.5  vc:118.14000  a: .03100  p: .05766
t: 2.6  vc:118.42560  a: .02624  p: .04131
t: 2.7  vc:118.66800  a: .02220  p: .02957
t: 2.8  vc:118.87200  a: .01880  p: .02120
t: 2.9  vc:119.04600  a: .01590  p: .01516
t: 3.0  vc:119.19240  a: .01346  p: .01087
t: 3.1  vc:119.31600  a: .01140  p: .00779
t: 3.2  vc:119.42160  a: .00964  p: .00557
t: 3.3  vc:119.51040  a: .00816  p: .00399
t: 3.4  vc:119.58600  a: .00690  p: .00285
t: 3.5  vc:119.64960  a: .00584  p: .00204
t: 3.6  vc:119.70360  a: .00494  p: .00146
t: 3.7  vc:119.74920  a: .00418  p: .00104
t: 3.8  vc:119.78760  a: .00354  p: .00075
t: 3.9  vc:119.82000  a: .00300  p: .00054
t: 4.0  vc:119.84760  a: .00254  p: .00038
t: 4.1  vc:119.87160  a: .00214  p: .00027
t: 4.2  vc:119.89080  a: .00182  p: .00019
t: 4.3  vc:119.90760  a: .00154  p: .00014
t: 4.4  vc:119.92200  a: .00130  p: .00010
t: 4.5  vc:119.93400  a: .00110  p: .00007
t: 4.6  vc:119.94480  a: .00092  p: .00005
t: 4.7  vc:119.95320  a: .00078  p: .00003
t: 4.8  vc:119.96040  a: .00066  p: .00002
t: 4.9  vc:119.96640  a: .00056  p: .00001

Which tells you that, for a 10,000 microfarad capacitor, you'll get close to full power after two seconds, and that power has dropped below a quarter watt by 2.1 seconds.

Not counting the load of the device.

See how useful bc is?

[Update JMR20160111:

I left out a few things last Saturday night.

First, let's get a look at the charge curve for a straight wire (zero ohm resistor) in the rectified DC circuit. Remember that bare wire has a very small amount of resistance. We'll use 10 milli-ohms, and we'll focus on the first ten milliseconds.

Keep your bc session open, or start it again ("bc -l") and paste the above code in again. Then try this (as in the gnu bc version that works on debian):

r = 0.01;
for ( t=0.0; t<0.0101; t += 0.001 ) {  
  vc = vc(vs,t,r,c );
  vr = vs - vc;
  a = vr / r;
  p = vr * a;
  print "t: ", t, "  vc:", vc, "  a: ", a, "  p: ", p,  "\n"

Or, for the version of bc in openbsd:

r = 0.01;
for ( t=0.0; t<0.0101; t += 0.001 ) {  
  v = v(s,t,r,c );
  z = s - v;
  a = z / r;
  p = z * a;
  print "t: ", t, "  vc:", v, "  a: ", a, "  p: ", p,  "\n"

Here's what you should see:
t: 0  vc:0  a: 12000.00000  p: 1440000.00000
t: .001  vc:119.99520  a: .48000  p: .00230
t: .002  vc:120.00000  a: 0  p: 0
t: .003  vc:120.00000  a: 0  p: 0
t: .004  vc:120.00000  a: 0  p: 0
t: .005  vc:120.00000  a: 0  p: 0
t: .006  vc:120.00000  a: 0  p: 0
t: .007  vc:120.00000  a: 0  p: 0
t: .008  vc:120.00000  a: 0  p: 0
t: .009  vc:120.00000  a: 0  p: 0
t: .010  vc:120.00000  a: 0  p: 0

12 kiloamps of instantaneous current!

1.44 megawatts of instantaneous power!

Fortunately, the resistance in the house wire will limit the current, so you wouldn't really draw that much. But it would try, and the circuit breaker would (hopefully) keep you from taking down the neighborhood grid. And you might be fumbling around in the circuit breaker box in the dark. Assuming you survive when the capacitor and rectifier probably explode and burn.

Now you have mathematical proof of why you don't want to build that circuit without the current limit resistor.

Do you wonder about the AC circuit? So do I, but I have a day job, so I'll save that for another rant. But it's not that hard. You just have to fix the loop so that it simulates the source voltage doing a sine curve from -170 to 170 peak-to-peak.

A few comments about real power supplies in recent electronic (especially after about the year 1997 or so):

The switch that removes the current-limiting resistor should be driven by a schottky diode circuit or some similar circuit that monitors the voltage across the capacitor, removing the current limit as the capacitor gains sufficient charge to drive the device at its rated voltage. Maybe I'll draw a model circuit for that when I have more time.

But, truth be told, we don't do it this way any more. We use a small microcontroller, itself powered by a very low power switching power supply, to control some sort of high-powered semiconductor switch (SCR or something similar) to act as the current-limiting resistor in the above circuit. Or we may use a  The microcontroller monitors the current draw with analog-to-digital inputs, for safety and soft startup.

It also monitors the voltage across the impedance device (SCR or whatever) directly, ramping the current-limiting impedance down smoothly as the power capacitor charges and the voltage across the impedance decreases.

I don't think I'm going to have time very soon to work up an example microcontroller-controlled switching power supply circuit, and the control logic for it, that which wouldn't be covered by current patents. (Stupid patents.)