Input filtering for a microcontroller

Today, "on the bench", I connected the "board" with current transducer and voltage transducer, to the microcontroller.

I plugged inputs of the microcontroller into my military "universal battery charger".

I immediately had a disappointment by learning that the voltage reading was jumping all over the place. Further investigation revealed the following:

1) the input into voltage transducer was from a military "battery charger", which was a rectifier/transformer setup, fully unfiltered, looking like rectified sinewave

abs( sin(60 * 2*pi * t) )

2) If, instead of that, I fed input from a nice regulated power supply, the readings would be very stable.

Hence, my quite obvious conclusion is, since my 3 phase rectifier in the welder also delivers "wavy" DC, input needs to be somehow filtered so that a reading over a few cycles is obtained.

I suspect that it is a very simple matter, I should use a capacitor and a resistor. Impedance of the inputs of the microcontroller is well into megohms (30-50M, according to Comfile).

My question is how do I choose R and C so that I get a nice reading that is the exponential average of last, say, 5 cycles.

My feeling is that for 5 cycles, I should have RC = 5/50s, or RC =

1/10.

From that, I could choose something like C = 0.1 uF, R = 1 MOhm.

Is that right?

----input----R--------- input of uC | ===C | ____ gnd _______+______ gnd of uC

i
Reply to
Ignoramus19197
Loading thread data ...

For stable readings using a microcontroller, you will need to average multiple readings over a period of time. That is more accurate than using a heavy filter. If the ripple frequency is 50 or 60 Hz, or a multiple thereof, an average over 100 mSec is usually good. This "averages out" the ripple, which will be 10 or 12 half-cycles (30 or 36 for three phase). It is also a good idea to use a true-RMS computation, especially when measuring a short pulse. The RC filter you show above, with 100 mSec time constant, will not accurately show short pulses.

My Ortmaster is used in an application similar to welding. It reads short duration pulses accurately down to one or two cycles (16-40 mSec), and the software also has the ability to display, analyze, and store the waveforms for later recall. It uses true RMS computation that works as well for AC or DC, and any duration of current pulse.

In a similar product, for circuit breaker testing, an embedded Z180 microcomputer does the processing in a similar manner. For that, I had to write many routines in assembly language for speed, while the less time critical portions are now in "C". The original versions were entirely in assembly. For this product, with AC waveforms, we use a Rogowski (Air core) CT, which requires an integrator to derive the actual current waveform. The early predecessors of this type of equipment used a welding current monitor affectionately called a "Duffers", from the name of the manufacturer. They may still be around, and might be a good source of information.

Paul

formatting link

Reply to
Paul E. Schoen

Thank you. I did it in software early this morning, now I calculate

averageVoltage = 0.98 * averageVoltage + (1-0.98) * actualVoltage

and I display averageVoltage on the display. Seems to be pretty stable, for my frequency of polling, and yet it reacts to changes in voltage quickly enough. I will experiment a little more. Right now I use function tadin(), which averages 20 readings, to get actualVoltage, and I want to change it to adin, which does not do averaging, since I do my own averaging.

Very cool. Very nice how you do it. Here I am kind of limited with memory, and computing RMS requires an array. so I think that I will stick to exponential average for now.

Last time I programmed assembly, was about 13 years ago...

i
Reply to
Ignoramus15879

-- snip --

I like using something like

averageVoltage += (actualVoltage - averageVoltage) * 0.02;

It's a bit more obscure when you read the code, but you save a few operations and you don't have to track two numbers in your code. Furthermore, there's easy ways to make this even more efficient in integer arithmetic using shifts instead of multiplies.

square = actualVoltage * actualVoltage; meanSquare += (square - meanSquare) * 0.02; rootMeanSquare = sqrt(meanSquare);

Where's the array?

--

Tim Wescott
Wescott Design Services
http://www.wescottdesign.com

Posting from Google?  See http://cfaj.freeshell.org/google/

"Applied Control Theory for Embedded Systems" came out in April.
See details at http://www.wescottdesign.com/actfes/actfes.html
Reply to
Tim Wescott

0.98 is actually a named constant in my code (which I replaced with the actual number in my post for clarity), so it is defined only once.

You are right. It is not exactly mean square, it ie exponential, but it will work just fine, I think.

I will program this tonight. I will try to check if I have the sqrt function in my BASIC.

i
Reply to
Ignoramus15879

No it doesn't. It only requires two variables: one that sums the squares, and one that counts how many values have been summed. Any time you want RMS, do the division. Any time adding a sample would cause overflow, divide both values by 2.

Reply to
Clifford Heath

I don't understand the meansquare equation. I would do something like:

meansquare = (square + N*meansquare)/(1+N)

N is the number of samples that make up one time constant of the mean. The larger N is the smoother the RMS reading, but the slower the response to changes.

Reply to
John Popelish

I am doing essentially this same calculation in assembly code without using floating point math. Each time I take a sample (8 bits), I multiply it by itself (16 bits), and add it to a 40 bit accumulator (SumSquares). I also keep track of the number of samples in a 32 bit accumulator (nSamples). This has to be fast, as I am sampling 1200/sec in an ISR. When it's time to do an RMS calculation, I shift both quantities until SumSquares is 16 significant bits, and then I use a fast square root algorithm to get an 8 bit result.

Actually, my new software now uses floating point "C" routines for the final calculations, as they are done outside the ISR. My older versions of software were entirely in Z80 assembly language. I am displaying a continuous RMS reading every 200 mSec (which is an integral number of cycles at 50 Hz or 60 Hz), as well as a total RMS reading over the entire period of time the current was on. This is typically no more than 180 seconds for circuit breaker testing, but the 40 bit accumulator is good up to about 8 hours.

For smooth readings of line frequency AC, or rectified DC, it is important to set the sample rate to an integral multiple of the line frequency, and perform the calculation at an integral number of half-cycles. I chose 1200 for this application, but I previously used 600 with good results, and my Windows program for a similar application uses 2400. The faster the sampling rate, of course, the better will be the ability to see higher frequency components of the waveform.

If you are using a digital readout, the optimum display rate is about 3 to

5 per second, which is usually used on DMMs and DPMs. Faster updates result in an apparent jumble of digits.

Paul

formatting link

Reply to
Paul E. Schoen

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.