Skip to content
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

document calibration #107

Closed
hartytp opened this issue Dec 17, 2020 · 21 comments · Fixed by #448
Closed

document calibration #107

hartytp opened this issue Dec 17, 2020 · 21 comments · Fixed by #448
Labels
documentation Improvements or additions to documentation enhancement New feature or request

Comments

@hartytp
Copy link

hartytp commented Dec 17, 2020

The calibration script doesn't have enough documentation to be used as is. I think I can figure it out from the issues (see conversation from #104 (comment)) but a few sentences to describe the process would make life much easier.

@ryan-summers ryan-summers self-assigned this Dec 18, 2020
@hartytp
Copy link
Author

hartytp commented Dec 21, 2020

Note to self: the term "transforms" is not intuitively obvious to me. AFAICT it refers to the linear-in-dB mapping from input/output power in dBm (x) to detector reading in V (or LSB?) (y). We thus have y=ax+b.

Since the firmware does not expose the detector voltage to the user (wouldn't it be useful to expose this?), only the inferred powers, we need to begin by reading out the current values of the coefficients a and b, from which we can back out the detector voltage. Solving, we find that if input/output powers x0 and x1 are applied, resulting in the firmware reading out powers of p0 and p1, the new coefficients a_f and b_f are related to the old coefficients a_i and b_i by: a_f = a_i *(p0-p1)/(x0-x1) and similarly for the b coefficients (offsets).

@hartytp
Copy link
Author

hartytp commented Dec 21, 2020

AFACIT, the calibration tool doesn't currently do any of that maths for the user. If a new "transform" (consisting of a slope + offset in units of V/dBm and V respectively?) is not specified, it prints out the current coefficients, otherwise it writes new ones.

This is all sufficiently non-obvious that it needs proper documentation. However, it might be easier to make the tool itself a little more user-friendly (e.g. take in x0, P0 and x1, P1 instead).

We should also make recommendations for sensible values of x0 and x1 (and should ask TS/CTI to use those same values for consistency).

@hartytp
Copy link
Author

hartytp commented Dec 21, 2020

NB the expression I get for the slope looks non-equivalent to the one @jordens posted here but I may just be misunderstanding his terminology (or making a silly maths slip...) Either way, it will hopefully become obvious once I run the cal.

For completeness I have:

y0 = aP0 + b = a`x0+b`
y1 = aP1 + b = a`x1 + b`

aP0 + b - a`x0 = b = aP1 + b - a`x1
(aP0 + b) - (aP1 + b) = a`(x0-x1)
a` = a(P0-P1)/(x0-x1)

For the offset I get

y0 = aP0 + b = a`x0+b`
y1 = aP1 + b = a`x1 + b`

(aP0+b-b')/x0 = a' = (aP1+b-b')/x1
x1*(aP0+b-b') = x0*(aP1+b-b')
x1*(aP0+b) - x1b' = x0*(aP1+b)-x0*b'
a*(x0*P1 - x1*P0) + b*(x0-x1) = b'*(x0-x1)
a*(x0*P1 - x1*P0)/(x0-x1) + b = b'

@hartytp
Copy link
Author

hartytp commented Dec 21, 2020

The defaults seem to be:
Channel 7: InputPowerTransform slope = 42.857143, offset = -26.699999
Channel 0: OutputPowerTransform slope = 28.571428, offset = -5.799999
Channel 0: ReflectedPowerTransform slope = 42.857143, offset = -5.799999

Where did these come from? Were they calculated on the basis of nominal circuit values to give something sensible?

What's the recommended procedure for calibrating the reflected power. IIRC we're really not aiming for something accurate here so just a rough calibration for safety purposes. Are the default values expected to be good enough for that?

@hartytp
Copy link
Author

hartytp commented Dec 21, 2020

Let's have a go then...

input power is -20dBm (-18.9dBm on a synth at 100MHz, expect ~+20dBm output given the 40dB gain) gives: input_power:-1.0368036e1, output_power = 2.1114285e1. Measured output power is -9.35dBm + 30dBm = +20.65dBm (G=40.65dB)
input power is -10dBm (-8.9dBm synth) gives: input_power:1.207546e1,output_power:3.0285713e1. Measured output power is -0.11dBm + 30dBm = +29.9dBm (G=39.9dB)

Looks like the default for the output power is pretty sensible but the input is quite far off.

@hartytp
Copy link
Author

hartytp commented Dec 21, 2020

For ~1W output, the reflected power is coming out as reflected_power:1.5542858e1 (i.e. +15dBm) so ~-30dBc output. That's not obviously implausible...

Edit: this is just a sanity check on the default (uncalibrated) value being something sensible.

@hartytp
Copy link
Author

hartytp commented Dec 21, 2020

Okay, the equations I posted above give garbage, but the ones @jordens posted in that issue seem to give sensible results, so I guess I haven't understood how these transforms are intended to functions. Nonetheless, I think I can now get on with calibrating the device.

@hartytp
Copy link
Author

hartytp commented Dec 21, 2020

NB

  1. Don't try to calibrate the input detector with the interlock tripped since this seems to add a ~0.3dB error (presumably VSWR-related due to the reflective switch)
  2. The input detector settings on the channel I calibrated ended up being: Channel 0: InputPowerTransform slope = 19.09557361295228, offset = -27.276924682322218 compared with the default of Channel 0: InputPowerTransform slope = 42.857143, offset = -26.699999. Might be worth looking at the default value for the input detector slope.

@hartytp
Copy link
Author

hartytp commented Dec 21, 2020

Here is the hacky code I used to calculate the calibration data to save. NB I didn't bother with the reflected power yet. Hopefully the default values will be accurate enough for my purposes (the output detector looked pretty good without calibration on the one channel I looked at); next time I'm testing Booster I'll use a 3dB attenuator or so to create some VSWR to check.

# Input power
old_slope = 42.857143  # V/dB?
old_offset = -26.699999  # V?

x0 = -20  # dBm
x1 = -10  # dBm
p0 = -2.0046154e1
p1 = -9.753845e0

new_slope = old_slope*(x0 - x1)/(p0 - p1)
new_offset = (x0 + x1 - new_slope/old_slope*(p0 + p1 - 2*old_offset))/2
print("input power:", new_slope, new_offset)

# Output power
old_slope = 28.571428  # V/dB?
old_offset = -5.799999  # V?

x0 = +20.65  # dBm
x1 = +29.9  # dBm
p0 = 2.1114285e1
p1 = 3.0285713e1

new_slope = old_slope*(x0 - x1)/(p0 - p1)
new_offset = (x0 + x1 - new_slope/old_slope*(p0 + p1 - 2*old_offset))/2
print("output power:", new_slope, new_offset)

@hartytp
Copy link
Author

hartytp commented Dec 30, 2020

Channel 0: OutputPowerTransform slope = 28.571428, offset = -5.799999

From

// When operating at 100MHz, the power detectors specify the following output
// characteristics for -10 dBm to 10 dBm (the equation uses slightly different coefficients
// for different power levels and frequencies):
//
// dBm = V(Vout) / .035 V/dB - 35.6 dBm
//
// All of the power meters are preceded by attenuators which are incorporated in
// the offset.
output_power_transform: LinearTransformation::new(1.0 / 0.035, -35.6 + 19.8 + 10.0),
// The input power and reflected power detectors are then passed through an
// op-amp with gain 1.5x - this modifies the slope from 35mV/dB to 52.5mV/dB
reflected_power_transform: LinearTransformation::new(
1.0 / 1.5 / 0.035,
-35.6 + 19.8 + 10.0,
),
input_power_transform: LinearTransformation::new(1.0 / 1.5 / 0.035, -35.6 + 8.9),

So the expected transformation is: P_out[dBm] = 28.6dBm/V * V_adc - 5.8dB.

My calibration gave: P_out = 28.8dBm/V * V_adc -6.494859775380661dB. So, by way of example. if we actually have P_out=33dBm then V_adc = (33dBm + 6.5dB)/28.8dBm/V=1.37V. The nominal calibration would then give 33.4dBm so within 0.5dB. That feels well within spec for the various parts.

@hartytp
Copy link
Author

hartytp commented Dec 30, 2020

For the input, the nominal is P_in[dBm] = 42.857143 dBm/V * V_adc - 26.699999 dB

@ryan-summers is there an operator precedence issue here? We want 1/(1.5*0.035V/dB) = 19dB/V but we seem to be getting 42.86dB/V = 1.5/0.035V/dBm.

@hartytp
Copy link
Author

hartytp commented Dec 30, 2020

Nope, not that, just an out of date release...

input_power_transform: LinearTransformation::new(1.5 / 0.035, -35.6 + 8.9),

@ryan-summers please do flag if releases are way out of date before I spend time debugging issues....

This may also explain the issue I saw with the interlock thresholds.

@jordens
Copy link
Member

jordens commented Jan 4, 2021

Summary AFAICT: Setting and getting the transforms is documented as are the transforms themselves. Computing new calibrated transforms for the user or aiding them in choosing test values isn't.

@jordens jordens added documentation Improvements or additions to documentation enhancement New feature or request labels Jan 4, 2021
@hartytp
Copy link
Author

hartytp commented Jan 4, 2021

Summary AFAICT: Setting and getting the transforms is documented as are the transforms themselves

Where are the transforms documented? Do you mean the inline comments, or did I miss something?

Computing new calibrated transforms for the user or aiding them in choosing test values isn't.

Yep.

@jordens
Copy link
Member

jordens commented Jan 4, 2021

The help of booster_calibrate_power.py and the API in booster.py. We should add the actual transform expression power_dbm = slope*input_volt + offset to that help string.

Computing new calibrated transforms for the user or aiding them in choosing test values isn't.

Yep.

To be clear: I don't consider that critical. But as always PRs welcome.

@hartytp
Copy link
Author

hartytp commented Jan 4, 2021

To be clear: I don't consider that critical. But as always PRs welcome.

@hartytp hartytp closed this as completed Jan 4, 2021
@hartytp hartytp reopened this Jan 4, 2021
@ryan-summers
Copy link
Member

Nope, not that, just an out of date release...

input_power_transform: LinearTransformation::new(1.5 / 0.035, -35.6 + 8.9),

@ryan-summers please do flag if releases are way out of date before I spend time debugging issues....

Sorry for this - that was one of the few bugs that was patched after v0.1.0 was generated and has not yet made it into a new release. You can view the changelog from the current mainline to a release by clicking on the "X commits to develop since this release" under the Releases page: https://github.com/quartiq/booster/releases

Unfortunately, this change appears to be listed at the very bottom of the change set.

@hartytp
Copy link
Author

hartytp commented Jan 4, 2021

Don't worry about it. Rust makes building from source so easy that I should probably have just built my own binary rather than using the release anyway.

@HarryMakes
Copy link
Contributor

@hartytp Hi, I appreciate that you shared your notes on the calibration procedures.

I noted that you did not calibrate the reflected power transform. If my understanding is right, when we apply some high-power 50 ohm load plus a short cable at the output, in practice there should still be power reflected back to the transmitter, but the amount should be at minimal.

If we remove the load and cable, using the uncalibrated reflected power readings before and after unplugging the load, can we actually infer the calibrated reflected power with open-circuit load, without the need to probe the output at all? I am taking that forward_power = reflected_power + output_power with closed-circuit load, and forward_power = reflected_power with open-circuit load.

Or alternatively, can we still consider the calibration valid if we assume output_power in presence of the 50 ohm load (and probe) equals reflected_power in open-circuit? In that case, we can simply unplug everything from the RF output, and then take the uncalibrated reflected power readings (as x0, x1), and plug the target output power value (p0, `p1) in the equations to find the new slope and offset.

In any case, I get that the output has better not be probed without a high-power load.

@HarryMakes
Copy link
Contributor

No, sorry I made a wrong statement. The output_power value actually corresponds to the forward power (as the ADL5904 RF detector takes the RF signal from the "CPL F" pin of the SYDC-20-62HP+ coupler and reports its Vrms level).

So, when we probe the output with a dummy load and take the measurement as output_power, we have already assumed reflected_power = 0, and thus the forward power equals the measured output_power. When we disconnect everything from the output SMA, all the forward power is reflected, so we can use the output_power value as reflected_power and recalculate the reflected power transform. In the end, we should expect that, given open-circuit load, the calibrated output_power should be equal or close to the calibrated reflected_power.

If there's some flaw in my logic, I'm all ears. Thanks!

@hartytp
Copy link
Author

hartytp commented Nov 16, 2021

So, when we probe the output with a dummy load and take the measurement as output_power, we have already assumed reflected_power = 0, and thus the forward power equals the measured output_power. When we disconnect everything from the output SMA, all the forward power is reflected, so we can use the output_power value as reflected_power and recalculate the reflected power transform. In the end, we should expect that, given open-circuit load, the calibrated output_power should be equal or close to the calibrated reflected_power.

Roughly.

This is all from memory and I haven't played with Booster for a while so I might be wrong (others should feel free to comment), but IIRC...

  1. The detectors + couplers are actually pretty accurate even without calibration. In particular, the absolute uncalibrated accuracy is broadly comparable to other factors like frequency / temperature / power dependencies / loss in cabling / impact of VSWR / etc so, depending on what users want for their application, calibration may or may not actually make things better. As a result, I concluded that it's generally not worth doing any calibration at all; just use the numbers from the datasheet and it's good enough. Booster was never intended as a precision piece of T&M equipment, just to give some rough diagnostics and it does that fine without cal.
  2. You're assuming perfect directivity in the couplers. IIRC in practice they don't behave the way you've described. e.g. the measured output power varies with the VSWR. If you start running Booster into significantly mismatched loads, the power measurements become unreliable.
  3. The reflected power was mainly intended as a "nice to have" rather than a precise diagnostic. It's accurate enough to do things like get rough data out on S21 from a modulator, but I wouldn't trust it for more than that

@jordens jordens linked a pull request Oct 10, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants