Keyboard Shortcuts
Likes
Search
Test framework for ATU-10 code
I've been reading through some of the messaging for the ATU project and reading the code. Concern for reliable tuning is often expressed. I gave some thoughts on how to test this and I came up with the following test code. Likely it still needs work, but it seems a good starting off point.
I started by looking at the python smith charts with its LC basic complex impedance simulation. I took that code and put it into a C module and then combined it with tuning algorithm from the ATU-10. I also added a way to view the results from many test points. It starts by finding the ideal impedances for a logrithmatic distribution of points from 5 to 500 ohms and -500j to +500j. It then runs the tuning algorithm on all of those points, while tuning the resulting complex impedance is calculated through simulation to determine the SWR and thats fed back into the tuning algorithm. Finally a basic user interface lets you walk through the results. It lets you change the scaling of the 0-9 results, switch frequencies and view ideal vs. differences from tuned and ideal impedances. Currently the code runs on a Mac, it should be easy enough to modify it to run on other platforms. |
¿ªÔÆÌåÓýYep, the doesn¡¯t show the tune algorithm the frequency. It only interfaces with the algorithm by presenting the current SWR, and the tune algorithm feeds back using the relay command. Power is ignored in this section as I assume I¡¯ve got enough power for a good tune signal. The file tune.c is simply the tune portion of the original main.c, I just removed everything else for clarity. My impdeance.c file implements stubs for testing the functions called in the tune algorithm. But it never touches frequency (except to simulate the resulting hardware behind the scenes).void?delay_ms(int?ms) { } void?get_SWR() { ? ? SWR = (int)(100.0?* SWRexact +?0.5); ? ??if?(SWR >?999) ? ? ? ? SWR =?999; } void?Relay_set(char?l,?char?c,?char?i) { ? ??if?(i)?// TODO - which side should the C be on the LC?, guessing for now, probably doesn't matter ? ? ? ? SWRexact = calcSWR(ZhpLsu(freqs[tuneFreqInx], tuneImp, inductors[l], capacitors[c ^?0x7f])); ? ??else ? ? ? ? SWRexact = calcSWR(ZhpLsd(freqs[tuneFreqInx], tuneImp, inductors[l], capacitors[c ^?0x7f])); ? ? SWR = (int)(100.0?* SWRexact +?0.5); ? ? tuneCount++; } I precalculate this all up front and provide a basic UI to view the data. I¡¯m also hoping to come up with performance metrics of the form 98% of the time it will tune within .2 SWR of the best possible tune. BTW - The use of E3 stepped components is ideal for any hill climbing algorithm as you will never have parasitics and component tolerance cause local minima and a early termination of a match. But it does mean that your step size in real terms is somewhat variable. This is one of the issues I was hoping to study using this test methodology.
|
This updated impedance.c (attached) fixes the bad test results showing up in the original code. It shows which test points give a worse impedance result than possible. It also shows how a count of how many 'tunes' it took to get the final result. To switch between 'differences', 'ideal-swr' and 'count-to-tune', press g or G to step through the options. Need to move this to github.
With test code like this it should be possible to optimize the tune algorithm. A few things I noticed as possible issues are:
|
Hi, Tom
Yes, practically E3 row works much better and provides higher max value. Unfortunatelly I dont have any MAC and I dont know how to use your code. Would be better you wrote it using Python, but probably? is? exist some solution how to run the code on Windows.
|
I checked in another update into github here:?
It has two copies of your tune algorithm, one in a file called tune1.c another called tune2.c. To allow this to link I had to add static keyword to most of the functions after tune. The re-use of the tune name was fixed with a rename provided a #define. This allows comparing the performance change between your original code and any modifications or improvements. You can still compare to a best tune as well.? I can port the PC if you'd like as well, just let me know your development environment an I'll try to make it happen. Here is a screenshot of the UI: ?1.82 MHz ? ? Tuned1 - Best
? ? ?-500 ? ? ?-50 ? ? ? 0 ? ? ? ? +50 ? ? ? +500
? 5 ?+++++++++++810000000022223433++0+6+++++++ ? ?- =< 0.0 - ? ?0.0% ? ?0.0%
? 6 ?++++++++5+3300000000000001331++1+8+++++++ ? ?0 = ?0.0 + ? 31.4% ? 31.4%
? 8 ?++++++++2+8202000000011111130692+9+++++++ ? ?1 = ?0.1 + ? 11.8% ? 43.2%
?10 ?+++++++6++50000000000001000334759++++++++ ? ?2 = ?0.2 + ? ?7.3% ? 50.5%
?13 ?+++++++27+30000000001001110211457++++++++ ? ?3 = ?0.3 + ? ?3.8% ? 54.4%
?16 ?++++++++3111000000000111000101265+9++++++ ? ?4 = ?0.4 + ? ?4.4% ? 58.8%
?20 ?+++++++7110300000000000000100015386++++++ ? ?5 = ?0.5 + ? ?4.6% ? 63.4%
?25 ?+++++++41100000000001010001000042548+++++ ? ?6 = ?0.6 + ? ?2.1% ? 65.5%
?32 ?++++++712101000000000000000000122344+++++ ? ?7 = ?0.7 + ? ?1.6% ? 67.1%
?40 ?++++6+361001010000000111000001102142+++++ ? ?8 = ?0.8 + ? ?4.2% ? 71.3%
?50 ?+++++8140000101000010111102100003041+++++ ? ?9 = ?0.9 + ? ?3.4% ? 74.7%
?63 ?+++++6120100000110101100000100001030+++++ ? ?+ = ?1.0 + ? 25.3% ?100.0%
?79 ?++++935111001000000000000000000542207++++
100 ?++9+715100010000000000000000000009847++++
126 ?++4+411200100000000000000000000122++++6++
158 ?+93+3152110000000000022222000111125++26++
199 ?+6283053221001122222222222222222256++36+6
251 ?+41854326555555555555555555555000012+57+4
315 ?831+7433+21111999999999999999999223467833
397 ?731+87655444444444444444444+++++++5722222
500 ?63101999888888888888888888888888110000111
f)frequency+, F)frequency-, g)raph+, G)raph-, s)cale+, S)cale-, n)egate
The top line has the frequency for the results and the graph selected. To the right is a legend describing what the numbers and +/- correspond to values. A histogram to the right of that and a cumulative histogram help gauge algorithm performance. The bottom like has a key of available keystroke commands. All of the data is precalcuated, so although simple, the UI is very interactive. |
Hi, Tom
I can install MinGW 64 or VS2019 on your choice, I am not a C programmer on Windows, prefer Python. I still don't understand how to recognize those numbers but I wanna do it. I guess the algorithm in ATU-10 works perfect but if there's a possibility to improve it, why not ? I have made a battery of no inductive resistors, switching 25,25,50,50,100,200,200 oHm, so I can set up resistance from 12.5 to 200 OHM and check the tuner on it. Practically, matching of resistive load much more difficult then mixed reactance. You can use this to create more efficient test bench. You told before, heard about bad experience with ATU 10 working, it's connected with bad Chinese manufacturing. Old burned or stacked relays, not soldered relays pins, randomly soldered capacitors, not RF grade capacitors dielectric, bad cloned amidon cores with high loss. This makes a tuner particularly or totally non worked. |
The screenshot may look like garbage if viewed in some proportional fonts. Looks OK for me on my browser
Basically anything with a 0 is within 0.1 of the ideal SWR match possible. Tuned using your tuner algorithm minus the best possible match available. The legend on the right shows this but in a very abbreviated manner - = ? ? ? SWR difference < 0 0 = ? ? ?SWR difference >= 0 and < 0.1 1 = ? ? ?SWR difference >= 0.1 and < 0.2 etc + = ? ? ? SWR difference >= 1.0 The numbers are a little harder to interpret than pretty graphics. But it is workable once you get use to it. Similar how they did it all the way up to the 1970s.? I'm working on adding a way to view a particular tune attempt to see what is happening when a less than ideal tune happens. You'll be able to select a single tune attempt and it will show a big scrollable array of L,C space with the SWRs for all the points. Also you will be able to see where the tune algorithm actually looked when trying to tune. This will answer the question I have, is there a single climbable hill for best SWR or is the search surface more complex. |
Finished the test code and checked it in at?
I'd tried to port it to Visual Studio, no complex data time so I tried to roll my own. Way too slow. So I ported it to MinGW (gcc). It took minimal changes. The github project has a reasonable writeup, but likely I'd forgotten something. Let me know if you have any questions or needed improvements. |
I think I've discovered a tuning bug. For some of my test points, a relay_set of -128 will occur. During the fine tuning, a char overflows at the start of a for loop in the code below.
My current checkin on github has assert's that will trigger at this point. static void sharp_ind(void){
? ?int SWR_mem;
? ?char step, ind_mem;
? ?ind_mem = ind;
? ?step = ind / 10;
? ?if(step==0) step = 1;
? ?get_SWR();
? ?SWR_mem = SWR;
? ?ind += step;
? ?Relay_set(ind, cap, SW);
? ?Delay_ms(5);
? ?get_SWR();
? ?if(SWR<=SWR_mem){
? ? ? SWR_mem = SWR;
? ? ? ind_mem = ind;
? ? ? for(ind+=step; ind<=(127-step); ind+=step){
? ? ? ? ?Relay_set(ind, cap, SW); |
Seems to lock up in coarse_cap when I tried to run it. On a different subject of improving the algorithm in general, by looking at the LC maps at the different test points and where your tuning algorithms actually tunes?to?during its tuning, it is kind of clear that at times you are playing the children's game of Battleship. The one where you try to guess where they hid the battleship in a grid and all you know is hit or miss. For your tuning algorithm, for some complex impedances, the 'hills of low SWR' are small and are in a giant plain of 9.99SWR and the best you can do is guess where to look till you find the hill. Other times the hills are large and easy to find. I'm thinking?I should write a search of the best LC locations to look in order of most to least probable to make the searches quicker and more reliable. Creating a list of 100 LC points most likely to hit a hill, from there you can use the gradient to search the hill to the top. The thought is they might follow a pattern. An actual list might not be needed. Thoughts? On Sun, Jan 21, 2024 at 9:18?PM David Fainitski <rolin791@...> wrote: Hi, Tom |
Just checked in an update that adds a mode that I'm calling 'battleship' to find a close to optimal search pattern to begin the hill climbing.?
I think the search pattern suggested is a little more chaotic than a planned one. Because it tries to get the best first match, it tends to make holes for the next few matches in the search space. My idea is to tweak it to make the first 20 or so searches be along the near zero C line, with a wider spread of L's, for both LC and CL configurations. From there, the search should be effective at finding holes to fill. Worked out to 65 tries to get all the test points to work. |
When I ran your algorithm, I found a number of times where it just didn¡¯t tune. Most of those were where it missed finding any hills in a wide plains of 9.99 SWRs. ?Please excuse the geographical analogy, but I find it helpful.? When I browsed around using the test framework, for some test points of frequency and complex impedance, the hills were quite large, other times they were fairly small. That¡¯s why I added the feature to try to find the best points to search for a hill in the plains.? I¡¯ll admit the search might not be perfect, there might be some stacking of the values due to the math of the regular complex impedances and the frequencies having common fundamentals. So these test values might not entirely reflect reality ? Any luck in getting my code to run? A little experience with it might be more instructive than I can easily explain.? |
Still a little rough, but here is a prototype (also checked into github) for a new tuning algorithm using the optimized starting points. There's still some bugs that need to be knocked out and the tables need to be simplified and/or optimized.
Should be a little clearer what I have in mind. Notice how it tries the list of guesses before starting the hill climbing algorithm. The hill climbing is simplified as well. |