Multi-variate equation solving within a range

Alright guys, bear with me, as this has a few different facets to it.

What I’m trying to do is design an automated impedance-line tuner using the Arduino platform - it’s the language and design system I learned on, and thus one of the most familiar to me.

Essentially, I’m building a large vacuum-tube-based RF amplifier and I want the input and output impedances to be automatically tuned to their proper values. If you’re not familiar with impedance matching, you can read some of what it entails on the Wikipedia page.

I’ll attempt to run through this as fast and as simple as I can, as I know we aren’t all RF engineers:

  1. The filters consist of a two variable capacitors and either a multi-tapped coil or a roller inductor in what’s known as a capacitor-input pi filter. Envision this as an arrangement where two capacitors bridge to ground, with an inductor in the signal path in between.

  2. The variable components will be driven by stepper motors.

  3. For any frequency f, each one of these components has a characteristic impedance depending on their capacitance or inductance for which by their serial-parallel nature will cause the overall source (input) impedance to be “matched” to the load (output) impedance.

These relationships are well-characterized by the individual equations for capacitor and inductor impedance, but it is a lot of work (very painstaking), and depending on the Q of the filter (essentially, how good the filter is at accepting frequencies in the criterion and rejecting those that aren’t), one tuning ratio and set of values will not be true for another frequency.

I’ll lay out the final part of this question in code blocks to help highlight:

frequency f, capacitance C, inductance L ,
given Zc = 1 / (2 * pi * f * C) and Zl = 2 * pi * f * L,

find C1, C2, and L so that:
Zo || Zc2 = (Zi || Zc1) + Zl,

provided C1, C2, and L exist within the range of their given component, for example:
10 < C1 < 115
11 < C2 < 90
0 < L < 10.5

Final couple of thoughts:

  • If I haven’t broken it down well enough, let me know and I’ll work y’all through it. Basically, how do I solve an equation for multiple values provided each value is cross-dependent

  • I know I could use for loops, but the issue with that is that the first thought coming to mind is brute-forcing it (testing all possibilities) and while I’m not opposed to that if need be, I’d prefer a solution with a bit of finesse.

If you’ve gotten to read this, thank you. I know it isn’t an easy question.

blasthash

Impedances are complex numbers, not real - you have to do all the arithmetic in complex numbers to design/characterise a linear filter. The non-ideal nature of real inductors can be encoded in the impedance as a real component for instance, so you automatically handle Q.

ZL = i w L

ZC = 1 / (i w C) = -i / (w C)

ZL for a non-ideal inductor = R + i w L

(where w is really omega, angular frequency in rad/s = 2 pi f)

(people often use j for i in electrical engineering to avoid clashing with i for current).

MarkT: Impedances are complex numbers, not real - you have to do all the arithmetic in complex numbers to design/characterise a linear filter. The non-ideal nature of real inductors can be encoded in the impedance as a real component for instance, so you automatically handle Q.

ZL = i w L

ZC = 1 / (i w C) = -i / (w C)

ZL for a non-ideal inductor = R + i w L

(where w is really omega, angular frequency in rad/s = 2 pi f)

(people often use j for i in electrical engineering to avoid clashing with i for current).

This I understand, and by all means, you're right and more accurate than my approximation which disregards the complex factors.

Either way, I'm still going to need to perform multi-variate operations here, regardless of which (ideal/non-ideal) component model is used.

I'll admit that my math hasn't held up well enough for us to discuss very well how effective that ideal approximation would be - I haven't looked at these equations in a good while, and now I see for good reason :P

I do understand that to better the approximation, one would also factor in inductor resistance - but I have next to no experience with complex number theory (which I also understand could open me up to a good amount of criticism should you choose), so I'd prefer to stay out of the realm of the imaginary unit, provided the 'real' approximation gives a close enough answer.

so I'd prefer to stay out of the realm of the imaginary unit, provided the 'real' approximation gives a close enough answer.

For impedance matching I think it is very difficult to avoid using complex numbers, or the equivalent thereof. The impedance of capacitors and inductors is almost entirely "imaginary" and when combined with resistances, only in certain circumstances can you approximate the combination using real numbers.

There is nothing scary about complex numbers if you remember the rules to combine them. It is just simple algebra. In the computer each complex number is represented by two real numbers anyway. Complex numbers are supported as a variable type in C and C++ but I have never bothered to check whether the Arduino environment supports them properly.

jremington:

so I'd prefer to stay out of the realm of the imaginary unit, provided the 'real' approximation gives a close enough answer.

For impedance matching I think it is very difficult to avoid using complex numbers, or the equivalent thereof. The impedance of capacitors and inductors is almost entirely "imaginary" and when combined with resistances, only in certain circumstances can you approximate the combination using real numbers.

There is nothing scary about complex numbers if you remember the rules to combine them. It is just simple algebra. In the computer each complex number is represented by two real numbers anyway. Complex numbers are supported as a variable type in C and C++ but I have never bothered to check whether the Arduino environment supports them properly.

I suppose.

From what I've worked with on a testbench, the approximation is able to achieve good SWRs - not phenomenal, and not into a reactive load such as an antenna - into a dummy (resistive) load. Probably just pure luck.

But since we're here, we might as well do it right. This amplifier I'm set to start working on will push 1.5kW off the plates, and that's not the range of power I feel like having angry at me.

How would I (ideally, assuming it supports them) declare and manipulate complexes? From a bit of looking into it, it's a class, which is a bit more hairy to handle than simple ints and stuff of the like.

I've worked with them before in algebra levels before - but as it's not "usual" math, per se and it defies normal notions of logic, imaginaries are the sorts of things my mind doesn't have a taste for. End point being, I can handle with them, just don't start grilling me on if I know why or how that number has significance. That level of theory I'll (hopefully) never get into!

At least in C, you just declare numbers to be complex and use a different set of functions with them. https://en.wikibooks.org/wiki/C_Programming/C_Reference/complex.h Here are some simple examples: http://stackoverflow.com/questions/6418807/how-to-work-with-complex-numbers-in-c

jremington:
At least in C, you just declare numbers to be complex and use a different set of functions with them.
C Programming/complex.h - Wikibooks, open books for an open world
Here are some simple examples:
http://stackoverflow.com/questions/6418807/how-to-work-with-complex-numbers-in-c

Okay, but now, how do I actually perform the operation?

If we don’t have an approach to solving it doesn’t matter how correct or incorrect our approximation is.

There are many ways of solving optimization problems, but the first step is to clearly define the equations that govern the system, the target function and the variables to be changed. You’ve got a good start on this, but for example:

find C1, C2, and L so that:
Zo || Zc2 = (Zi || Zc1) + Zl

is in general not possible. A more typical approach would be to find C1,C2 and L that minimizes the quantity T where:

T = (Zo || Zc2 - ((Zi || Zc1) + Zl))2

T is always a real number, whereas the impedances are almost always not.

One way to solve this is a “brute force” method: step through a reasonable selection of the possible values of the variables and find a set that produces the minimum value of the target function T above. Of course, there are far more sophisticated and/or faster approaches but most would be difficult to implement given the tiny memory space available in an Arduino. Your case includes constraints on the variable values (called constrained optimization), which makes it harder to use general methods .

Here are a couple of overviews on minimization algorithms:

http://www.numerical.rl.ac.uk/people/nimg/oumsc/lectures/paper.pdf?

By the way, did you know there are on-line calculators for design of impedance matching networks? This is very handy for checking the results of a program! Examples:
http://home.sandiego.edu/~ekim/e194rfs01/jwmatcher/matcher2.html
http://leleivre.com/rf_lcmatch.html

Finally, I found some lecture notes at http://www.ece.ucsb.edu/yuegroup/Teaching/ECE219Winter2013/ECE219.html, with all the relevant formulas for various matching networks. See the notes for Lecture 4.

Interestingly, if you are willing to make the assumption that your input (transmitter) and output (antenna) impedances are purely real, then your pi-network problem can be solved exactly by algebra. See Professor Yue’s pi-match example in Lecture 4, above link.

jremington:
There are many ways of solving optimization problems, but the first step is to clearly define the equations that govern the system, the target function and the variables to be changed. You’ve got a good start on this, but for example:

find C1, C2, and L so that:
Zo || Zc2 = (Zi || Zc1) + Zl

is in general not possible. A more typical approach would be to find C1,C2 and L that minimizes the quantity T where:

T = (Zo || Zc2 - ((Zi || Zc1) + Zl))2

T is always a real number, whereas the impedances are almost always not.

One way to solve this is a “brute force” method: step through a reasonable selection of the possible values of the variables and find a set that produces the minimum value of the target function T above. Of course, there are far more sophisticated and/or faster approaches but most would be difficult to implement given the tiny memory space available in an Arduino. Your case includes constraints on the variable values (called constrained optimization), which makes it harder to use general methods .

Here are a couple of overviews on minimization algorithms:
http://en.wikipedia.org/wiki/Mathematical_optimization
http://www.numerical.rl.ac.uk/people/nimg/oumsc/lectures/paper.pdf?

By the way, did you know there are on-line calculators for design of impedance matching networks? This is very handy for checking the results of a program! Examples:
Impedance Matching Network Designer
LC Impedance Matching Network Designer

Finally, I found some lecture notes at http://www.ece.ucsb.edu/yuegroup/Teaching/ECE219Winter2013/ECE219.html, with all the relevant formulas for various matching networks. See the notes for Lecture 4.

Interestingly, if you are willing to make the assumption that your input (transmitter) and output (antenna) impedances are purely real, then your pi-network problem can be solved exactly by algebra. See Professor Yue’s pi-match example in Lecture 4, above link.

Okay. That was a great find! I took awhile to review it, and that would work great for the application - as each are derived from separate formulas, I could find a solution without having to implement the optimization algorithms.

As this would be an HF amplifier, one could reduce the bandwidth to a few hundred kilohertz, which would help ‘fit’ the components better - that way, I wouldn’t have the tuning stages encounter an illegal combination that couldn’t exist.