-
-
Notifications
You must be signed in to change notification settings - Fork 217
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
0.4% of Acquistions Contain Inverted Points #280
Comments
Thank you very much for this excellent and thorough report! I have to admit that this is not something I have noticed before. But I mostly do short tests of new features/bugfixes with my LibreVNA and do not actually use it for longer measurements most of the time. 0.4% might just be infrequent enough to slip through my tests while obviously still much too frequent to be acceptable. At first I was very confused by this, but looking at your results a bit more, I have a theory now: The 2.LO outputs may "sometimes" have a phase difference of 180° between them. If that is indeed the case, it puts the following constraints on the inverted points:
Based on the example data you provided, this seems to be true. I'll try to come up with a hardware experiment to verify this theory. I very much hope that it is solvable in software and not just a hardware limitation of the Si5351C. With Christmas and New Year's Eve coming up, it might take me a bit longer than usual, but I'll let you know as soon as I have more info on this. |
A few questions: (1) Does the reference channel share an LO output with one of the main channels? And is the reference already divided out of these measurements? If so, seems like it would hide the problem on one channel. (2) What is the exact measuring sequence? For example, another VNA I have does a sweep driving stimulus on port 1 to measure S11 and S21 for all points, then it does a second sweep driving stimulus on port 2 to pick up S12 and S22. Within each frequency, it leaves RF at a constant phase while varying the phase of LO to each of 0, 90, 180 and 270 degrees. It combines these four sub-measurements to subtract out any DC offsets. I connected this VNA to the scope and noticed that it switches the stimulus back and forth between the ports as it sweeps. Does it also measure at four phase offsets? (3) I noticed that *RST sets the start frequency to 0. (3a) What does this VNA do with a frequency of zero -- does that actually work? The version of EagleCAD I have is a pay version, but too old to be able to open the schematics, so I can't check for blocking capacitors. (3b) Could you make pdf versions of the schematics available? (3c) Is the default start frequency 0 or 1MHz? Is *RST consistent with power-on state? Another observation: if I start the sweep at 0 instead of 1 MHz (which also shifts all but the last frequency point down a bit), the inversion problem seems to happen much less frequently, more like 0.005%, but it also affects lower frequencies when it does happen. This suggests something specific to certain frequency values. |
I'll change the order of your questions because I think this will help me with some later answers:
They are already available here: https://github.com/jankae/LibreVNA/blob/master/Hardware/Schematic.pdf
The "default" default start frequency is 1 MHz. Take this with a grain of salt, because there is not one default power-on state. Depending on the preferences, several options are available:
I say the default is 1 MHz because a LibreVNA-GUI that is running for the first time on a computer, will have its preferences set to load some default settings and these default settings have the start frequency set to 1 MHz.
Since there is no fixed power-on state, it can be consistent with that but does not have to be. *RST always sets the maximum span as advertised by the VNA. The LibreVNA-GUI is intended to be used with different devices (although there really is only the one LibreVNA at the moment) and does not impose any limits on the frequency range itself. Instead, the USB protocol includes a "DeviceInfo" packet, which tells the GUI what the connected device is capable of. The LibreVNA has the start frequency in that packet set to 0, so that will be set after sending the *RST command.
No, it does not. You will actually see an error message in the device log if you start all the way from 0 Hz: But what if someone wants to measure something just below that? The performance will be worse but maybe still useful and I do not want to prevent anyone from going a bit lower if that helps. So I did not set a hard limit in the software. You can go as low as you want and the VNA will do its best to still measure something. Of course this will work less and less the lower you go. The DC coupling caps reduce the output signal level, the mixers do not work that well anymore,... At a certain point (way above 0 Hz) you will not get anything useful at all.
This is also what I have observed on a different VNA. But I never really understood the reasoning behind it. At faster sweep speeds, the settling time of the PLLs actually take up a significant amount of the overall sweep time. And if you drive the stimulus at one port first for the whole sweep and then at the other port again, you are sweeping the whole frequency range twice. If you switch between the ports for each frequency point, the stimulus PLL only has to settle to each point once. I am sure there is a reason why a lot (all?) VNAs do it differently than the LibreVNA, but I am not aware of any disadvantages with my approach so far.
I am not sure what the hardware architecture of that VNA looks like but this sounds unlike anything I am familiar with. Is it doing a direct conversion all the way to DC? If so, how are different IF bandwidths implemented? I'll combine my answer to this with the next question:
This will be a long one. The LibreVNA uses 3 down-conversions per channel, although only two are obvious on the schematic. Down-conversion 1: The incoming signal (or internal signal for the reference receiver) is mixed with the 1st LO (1.LO). This LO moves with the stimulus frequency at always sits 62 MHz above that. The 1.LO is generated by another MAX2871 PLL which has two differential outputs. These differential outputs are used as single-ended outputs instead. RFOUTA_P goes to port 1, RFOUTA_N to the reference, RFOUTB_P to port 2. RFOUTB_N is not used and terminated directly at the PLL. Down-conversion 2: The incoming signal is sitting at a fixed frequency (62 MHz), which means that the 2nd LO (2.LO) can also stay at a constant frequency. Three outputs of the Si5351C IC are used for that and set to generate 61.75 MHz. I need this second down-conversion in this hardware architecture because 62 MHz is still too high to sample it directly with the ADCs and the 1.LO PLL can not go below 23.5 MHz (meaning it can not generate an LO low enough to directly convert the input signal to something the ADC can use, at least not for stimulus frequencies <23 MHz). After the 2nd down-conversion the IF signal sits at a constant 250 kHz and this is low enough to be sampled by the ADC. The ADC is sampled by the FPGA with 800 kHz. But we do not need some 250 kHz signal, we need the phase and amplitude of that signal. Everything from this point on happens in the digital domain. The LibreVNA returns raw receiver values to the GUI (real and imaginary parts for each receiver). The GUI assembles these to complex receiver values and then of course divides the receiver values from port 1 and port 2 by the value from the reference receiver. This is how you end up with S-parameters. At least that is the simplified view of things. In particular, the PLLs for the stimulus signal and 1.LO (both MAX2871s) are of interest. Every PLL has a limited frequency resolution determined by the bits in the fractional divider. The MAX2871 only has a 12 bit fractional divider. This means it simply can not generate certain frequencies. It can get close but not necessarily close enough. This results in a shift of the IF frequency at certain frequencies (when either the stimulus or 1.LO PLL deviates from the desired frequency). If this shift in frequency is large compared to the IF bandwidth, the VNA actually filters it out - it does not see anything anymore. This is obviously bad. There is a solution to mitigate this though: the firmware can calculate the actual output frequency of the PLLs and check if the deviation is too much. It can then shift the 2.LO (which has much better frequency resolution) to compensate accordingly and bring the sampled IF back to 250 kHz. This feature is enabled by the "suppress invalid peaks" checkbox in the preferences. And here is what I suspect causes this issue: when the 2.LO is switched to a different frequency, it is very important that all 3 outputs are still in phase. Any phase difference here will show up at the output as well. To fully understand it, you would need to read the Si5351C datasheet, but I am basically setting the internal output dividers for the new frequency and lose phase synchronization during that process because I can only configure them one after the other. To regain phase synchronization, I perform a PLL reset (of the internal Si5351C PLL) afterwards. I figured out experimentally that this works to align the phases again, I do not think the datasheet is very clear what actually happens during the reset.
This very much matches my theory: If you start from 0 instead of 1 MHz, all the points in the sweep will have slightly different frequencies as well. This means the MAX2871 PLLs will have problems with different frequency points and thus the 2.LO frequency is also switched at different frequencies. I think it boils down to two questions:
|
If I'm following correctly, if the "suppress peaks" option is disabled then 2.LO would be left alone during the sweep and not reconfigured? It sounds like it'd be worth re-trying the original experiment with that option disabled to help test the theory. |
Yep, that should get rid of inverted S parameters if my theory is correct. It would of course also result in pretty much random spikes in all S parameters at the frequencies where the IF is then outside of the IF bandwidth. |
Some progress: And then the test against the scripts provided here. I ran them first with the standard 1.6.1 firmware and did get several bad points: And the same test again with the firmware modifications. Well, there still are some bad points (5 compared to the >14000 before). But a lot less than before, none at 180° anymore and with wildly different magnitudes instead: The code changes in the firmware were actually rather small but I am hesitant to push that to the repo just yet. Changing something so deep in the frequency generation could have unintended side effects I have not considered so far and I would like to test this better (which I will likely not get done in the remainder of this year). |
I also saw some phases all over the place in just one experiment. This was one of the cases where the start frequency was set to zero. Edit: note that the frequency points with strange phases weren't at the low frequencies though: they ranged from 312MHz to 6GHz. |
It took a bit more work than expected but I tested the firmware change a bit more and fixed some unexpected FPGA issues (which potentially could result in the occasional wrong value but I could not reproduce this reliably). The latest commit includes the reworked 2.LO generation and should not exhibit phase reversal anymore. |
LibreVNA Version
LibreVNA Version (64 bit): 1.6.1-472594272
OS: Fedora Linux 38 (Workstation Edition)
CPU Arch: x86_64
Steps to reproduce
Example 1
DUT is an SMA tee with 25 ohm shunt resistor on the tap connected to both VNA ports through 12 inch lengths of RG316. Ignoring delays and imperfections within the tee, the S-parameters of the DUT are:
-0.5 0.5
0.5 -0.5
The following steps were run on Linux. These should be portable to any POSIX environment -- signal catching part, redirect and sort would likely need changes if run on native Windows. Note that the measure-time-series.py script creates 501 output files: 000.out, 001.out, 002.out, ... 500.out. Each file corresponds to a frequency point. Frequency range is 1 MHz to 6 GHz with 501 points. No calibration is loaded.
The find-inverted-results.py script works by averaging each frequency point across all acquisitions (saved as mean.s2p and mean.npd). Then it makes a second pass over all the files and flags outliers.
Output columns in bad-results are:
Scripts are here:
scripts.zip
Some Example Bad Entries
Example 2
This example is the same as above except that the DUT is now a short standard on VNA port 1 and an open standard on VNA port 2, both attached via 12 inches of RG316. No calibration is loaded.
Here, S12 and S21 are theoretically zero, but yet we can still see the same pattern of errors. I used the ?-mark on entries close to zero that nevertheless appear to be inverted.
In both examples, I chose three adjacent bad entries that had all three examples: S11 bad, S22 bad, both bad. Interestingly, the three frequency points also happen to be the same between the two examples.
The inverted frequency points within an acquisition sometimes appear alone, but more often appear in runs.
The most popular run length was 1 followed in order by 98, 95, 6, and 96. Only these five different run lengths appear in this 170,000-acquisition long time series. Here are some example runs:
Note that frequency span was 1 MHz to 6 GHz, but ALL of the bad entries appear above 3.5 GHz.
Spacing in time of bad acquisitions appear random:
But are quite uniform when viewed cumulatively:
A KS test done on the inter-arrival times could not reject the null hypothesis that the intervals are distributed according to an exponential distribution (e.g. from a Poisson process).
Expected behavior
Expected result is that repeated measurements of the same DUT should yield similar amplitudes and phases.
Extra information & Setup and Calibration files
No calibration is loaded.
The text was updated successfully, but these errors were encountered: