Vector measurements with the rtl-sdr, 4

31.07.2020 15:29

I'm developing a method for performing vector reflection measurements using a cheap, single channel software-defined radio receiver. To measure the phase of the reflected signal I need to receive two RF signals coherently, a reference and the actual measured signal. I'm using time multiplexing to do that since I'm restricted to only a single analog-to-digital converter. In my last post I've described a circuit I developed that performs the multiplexing in the analog domain. The demultiplexer as well as all other signal processing is done by software in the digital domain.

Time multiplex circuit board assembled and powered on.

I ordered the bare printed circuit boards from AISLER using their 2-layer/HAL surface finish process. This is the first time I've used their service. I was looking to have the boards made in Europe since I'm seeing large shipping delays recently due to COVID-19 (I'm still waiting for some components I ordered from overseas back in April). After looking at a few local PCB prototyping services, AISLER looked like by far the best bet. I got the boards in my mailbox in less than a week for a price that was comparable to ordering them from China.

Between the HAL and ENIG surface finishes offered I decided on HAL since it should have better performance at high frequencies. I also removed the soldermask from the top of the 50Ω coplanar waveguides in an attempt to further reduce the losses. I was pleasantly surprised that AISLER offers precise stackup specifications, including εr. That's something that I've often missed in similar services and it probably made my trace impedance calculations somewhat more accurate. However this wasn't manufactured as a controlled impedance board.

I assembled the boards manually using a hot air station. The boards had some leftovers from panelization breakaways right at the locations of the edge-mounted SMA connectors. I had to smooth the edges with some sandpaper to get the connectors to fit nicely. The QFN packages of the MMIC switches were also a bit tricky to solder, but I recently got a lot of experience soldering tiny AVRs at work so that wasn't too troublesome. The only thing I'm never completely sure with QFNs is how well the ground pad gets connected. The datasheet says that is important for good RF performance of the switch.

Multiplex board connected to a rtl-sdr and ERASynth Micro.

The big question of course is whether it works or not. For testing I've connected the board to my rtl-sdr receiver and the ERASynth Micro microwave synthesizer. I've used short, rigid male-to-male SMA adapters between the instruments to keep down the losses. I've also shorted the device-under-test in/out (DUT) ports with a short length of a coax cable. In this setup the expected 100 Hz 3-state multiplex pattern is visible on the rtl-sdr baseband. The board switches between an off state (no signal), the reference signal which is the input attenuated by 10 dB, and the signal that passes through the DUT (which in this case is the full input signal, minus any attenuation in the coax cable):

Plot of the multiplexed complex baseband signal.

So the basic multiplex functionality appears to be working, but is it any good? What are the losses and crosstalk in the switches and the PCB? Estimating the RF performance is where it gets a bit tricky. I've attempted to do that using the setup pictured above. To estimate the attenuation of the signal I've swept the input frequency and measured the received signal power at the rtl-sdr using rtl-power-fftw. I've performed the same measurement with the multiplex board locked into dut state and into ref state.

Measured signal power versus frequency relative to the thru measurement.

Since the rtl-sdr isn't a calibrated power meter I've also performed a third measurement where I directly connected the rtl-sdr to the signal generator using one of the rigid SMA adapters. This was the reference against which I compared the other two measurements. It's shown as 0 dB and the dotted black plot in the figure above. This way I subtracted any variability in the rtl-sdr sensitivity versus frequency. In all cases I manually locked the gain of the rtl-sdr to 14 dB.

Ideally, I would expect the blue dut plot to be near 0 dB. It should show only the loss in the PCB, switches (around 0.7 dB according to the datasheet) and the coax cable. Similarly, the ideal orange ref plot should be near constant -10 dB, because the board includes a 10 dB attenuator in that signal path.

As you can see, the reality is not nearly as perfect as the theory. The gain of both signal paths varies quite a lot with frequency. There seem to be one slowly varying component that's common to both paths (with minimums at around 600 MHz and 1600 MHz) and one that's only on the dut path (with periodic minimums every 250 MHz or so). This seems to suggest that there is more than one bad impedance match somewhere. It's not necessarily in the design of the board itself. I don't know how well ERASynth Micro is matched to 50Ω and I also don't have any specs for the rtl-sdr (I've been speculating on it's return loss before). I also don't have much confidence in the quality of SMA adapters and the coax cable I was using.

Measured signal power in off state compared to the noise floor.

Finally, this is the result of the crosstalk test I did. Here I'm comparing the signal power with the board in the off state (blue plot) with the receiver noise floor (dotted black plot). The measurement in the off state was done with the same setup as above. I've measured the receiver noise floor by terminating the rtl-sdr input with a 50Ω terminator. As you can see, both plots are basically identical, which shows that there's no significant leakage of the signal when the switches are turned off.

Plot of the estimated switch crosstalk.

A better way to show this result is by subtracting the noise floor from the off measurement in linear scale. This new plot now gives directly the isolation of the signal when the board is in the off state. 0 dB on the graph is again the input signal level, same as on other graphs.

Ideally, this plot would be at minus infinity. It is not because the two switches are not perfect (around 60 - 70 dB isolation per switch according to the datasheet) and some signal also probably leaks through the PCB and the space around it. When I was measuring this I also realized that the layout where I have the signal generator and the detector right next to each other might not have been the best choice to keep isolation high. Neither ERASynth Micro nor the rtl-sdr have metallized enclosures, so some signal might also leak out that way.

In any case, I think 50 dB isolation is more than good enough for my purpose. It goes down to 40 dB near 2 GHz, but that might be because rtl-sdr sensitivity is getting really bad in that range. This measurement is not very precise, since the crosstalk signal is below the noise floor of the receiver. It's unlikely that I will be using this board with bridges or directional couplers that would have directivity better than 40 dB. Hence isolation in the multiplex board shouldn't be the limiting factor in the accuracy of my measurements.

I would like to better understand where the unexpected variations in the signal path attenuation come from. Did I make an error in the board design or is it caused by cables and other equipment I'm using? I have some more experiments planned related to this. I also still need to take my signal processing code out of the simulation I wrote and use it on the data from the real hardware. In the end the only thing that matters is the quality of the final measurement result.

Posted by Tomaž | Categories: Analog | Comments »

My experience with Firefox containers

25.07.2020 19:17

For the past months I've been using the Firefox Multi-Account Containers (MAC) extension. This extension makes it possible to maintain several isolated browser states at a time. By a browser state I mean everything that websites store in the browser: cookies, local storage and so on. In practical terms that means logins on websites with "remember me" functionality, shopping baskets, advertisement network IDs and other similar things. You can setup the extension so that certain websites always open in a certain container. The Temporary Containers (TC) extension further builds upon MAC by dynamically creating and deleting containers as you browse in an attempt to keep the browser from accumulating long-term cookies.

Screenshot of the Firefox Multi-Account Containers extension.

I have a few reasons to use such a setup: First is that I commonly use company and personal accounts on websites. I want to keep these logins completely separate for convenience (no need to constantly log-out and log-in to change accounts). I've also once had an instance where a web shop silently merged accounts based on some hidden browser state. Even though that was most certainly unacceptable behavior on that web shop's end I would like to avoid another case where my personal projects end up on corporate order history.

The second reason is privacy and security. I think is harder to exploit weaknesses in browser's cross-site isolation, or do phishing attacks, if the default browser instance I'm using doesn't store authentication cookies for any important accounts. The fact that most websites see a fresh browser state without cookies also slightly raises the bar for tracking my browsing habits between different websites.

Cookies and Site Data preferences in Firefox.

I used to have Firefox set so that it cleared all cookies after every session. This took care of accumulating cookies, but meant that I needed to continuously re-login to every website. This wasn't such a inconvenience on my end. However recently more and more websites started treating new logins from a cookie-less browser as a security breach. At best I would constantly get mails about it, at worst I would get accounts blocked or thrown into a captcha-hell for unusual behavior.

A typical "sign-in from a new device detected" mail.

I would still prefer to have this setting enabled for default browsing, combined with a few permanent containers for websites that do this sort of unusual behavior detection. However MAC doesn't allow you to set this independently for each container. In theory, using TC fixes that problem. Opening up a website in a fresh temporary container that is used once and then deleted after closing the browser tab has the same effect as clearing cookies.

My foremost problem with containers is that in practical use they don't really contain the state between websites. It's trivial to make a mistake and use the wrong container. If I click a link and open it in a new tab, that tab will inherit the container of the original tab. The same also happens if you enter a new URL manually into the address bar. It's very easy, for example, to follow a link a coworker shared in a web chat and then spend an hour researching related websites. If I forget to explicitly open the link in "a new Temporary Container" that browsing will all happen in the permanent container that I would prefer to only be used for the web chat service. The tab titles get a colored underline that shows what container they are using, but it's easy to overlook that.

All it takes is one such mistake and the container is permanently polluted with cookies and logins from unrelated websites that I would not like to have in there. These will persist, since to retain the web chat login I have to set the browser to retain cookies indefinitely. Over time I found that all permanent containers tend to accumulate cookies and persisting logins for websites I frequent which defeats most of the benefits of using them.

There is the "Always Open This Site in..." option, but it works the other way I would want it to. You can define a list of websites that need to be opened in a certain container, but you can't say that a website outside this list needs to be opened outside of a container (or in a Temporary Container). The "Always Open This Site in..." also has the additional problem that it's annoying if I want to use a website in two containers (e.g. work and personal ones). In that case I have to constantly click through warnings such as this:

Firefox warning about assigned containers.

Again, the Temporary Containers extension attempts to address this. There is a group of preferences called "Isolation". In theory you can set this up so that a new temporary container is automatically opened up when you navigate away to a different website. It also takes effect when using the permanent containers.

It's possible that I don't understand exactly how this works, but I found any setting other than "Never" to not be useful in practice. The problem is with websites that use third-party logins (e.g. a website where you log in with your Google account, but is not hosted under, I'm guessing through a mechanism like OpenID). Isolation completely breaks this authentication flow since the log-in form then opens up in a new container and whatever authentication tokens it sets aren't visible in the original one.

Isolation preferences of the Temporary Containers extension.

Finally, both extensions are somewhat buggy in my experience. For example, I'm occasionally seeing tabs opened in no container at all even though I have Automatic Mode turned on in TC, which should automatically re-open any tab that's not in a container in a temporary one. I can't find a reliable way to reproduce this, but it seems to only happen with tabs that I open from a different application and might be related to this issue.

Cleaning old temporary containers often doesn't work reliably. Again, it's hard to say what exactly isn't working and if that's one of the known bugs or not. I often find that the browser has accumulated tens of temporary containers that I then need to clean up by hand. This is especially annoying since a recent update to MAC made container deletion unnecessarily tedious. It takes 4 mouse clicks to delete one container, so deleting a few tens is a quite a chore.

There is also a very annoying couple of bugs related to Firefox sync. MAC allows the container settings to be synchronized between all Firefox installations linked to the same Firefox account using Mozilla's servers. This is an incredibly useful feature to me since I commonly use multiple computers and often also multiple operating systems on each one. Needless to say, synchronizing browser settings manually is annoying.

Unfortunately, running MAC and TC with sync enabled runs the risk of permanently breaking the Firefox account. Because of the bugs I linked above it's very easy to accumulate so many temporary accounts that you exceeded the storage quota on the sync server. It seems that once that happens the sync server will not even let you delete the offending data that's stored there before erroring out. The result is that add-on sync will no longer work on that account and even cleaning up your local setup afterwards will not fix it.

Errors about insufficient storage in Firefox sync logs.

In conclusion, I'm not very happy with this setup (or the modern web in general, but I digress). Multi-Account Containers is certainly an improvement over a setup with multiple separate Firefox profiles that I was using previously. It does work well enough for keeping work and personal accounts separate. On the other hand, it doesn't seem to be very effective in isolating cookies and other state between browsing sessions. I'm not sure what exactly a better solution would be. I feel like I'm leaning more and more towards a setup where I would just use two completely separate browsers. One for heavy web apps that require a login, persistent local storage, Javascript and another one that's more aggressive at cleaning up after itself for everything else.

Posted by Tomaž | Categories: Code | Comments »

Vector measurements with the rtl-sdr, 3

12.07.2020 18:48

After doing some scalar reflection measurements using an rtl-sdr and an RF bridge I recently started exploring the possibility of capturing phase information as well using a similar setup. I came up with a relatively simple method that does most of the signal processing in software. I already validated that the method works well enough in simulation. All I need now to try it out in practice is a simple multiplex circuit board. I need that to coherently record two RF signals with rtl-sdr's single channel analog-to-digital converter.

At the time of my last post I already had most of the circuit sketched out on paper and the basic calculations done. I've spent the last couple of days finishing up the design and transferring it from paper into the computer. This is a 3D render of the current draft of the circuit board:

3D render of the time multiplex circuit board.

It's a two-layer design on a 1.6 mm FR-4 substrate. All RF and almost all the other tracks are routed on the top layer, leaving the bottom for a mostly uninterrupted ground plane. I'm not sure yet about the surface finish and solder mask. Signal connections are using edge-mounted SMA connectors.

I had to revise the schematic a few times when I was making the PCB layout. The 50 Ω coplanar waveguides can't overlap or change layers and I wanted to have the RF part of the circuit laid out as cleanly as possible. Fortunately, the input and output ports on the MMIC switches I'm using are interchangeable. This gave me enough flexibility to come up with a combination of ports where such a layout was possible. By a lucky coincidence the exact combination I ended up using also inverted the sense of one switch. This had an added benefit that I could omit an extra quad-NOR gate from the driver circuit.

The rest of the circuit is quite straightforward. I'm using a HEF4017 Johnson counter to drive the switches in the correct sequence. I ended up going with a three-state "off-ref-dut" switching cycle to aid the clock recovery like I mentioned in one of my earlier posts. There's a selector switch that allows the sequence to be driven by an internal oscillator, a manual button or an external clock coming into the fifth SMA connector on the bottom right of the board.

I've added the manual button to aid in testing. It will allow me to lock the RF circuit in a specific configuration and perform measurements on that specific signal path. Two LEDs show the currently selected path.

The internal oscillator is a simple 100 Hz astable multivibrator using a low-voltage variant of the classic 555 timer. Its frequency will be very inaccurate, but that shouldn't be a problem. The software needs to do full clock recovery anyway over several full switching cycles and the clock only needs to be roughly in the vicinity of 100 Hz and stable for around 10 cycles. If it later turns out that I've missed something and do need a better clock source I can still bring it in from an external source.

I probably need to go over the design once more time in case I missed something, but otherwise the PCB layout seems ready to be sent out to a prototyping fab. I getting curious. For the sub-2 GHz frequency range that the rtl-sdr and my current RF bridge can handle I think the hardware should work well enough. For the full 8 GHz rating of the switches I have some more doubts, mainly due to the 10 dB attenuator made from 0603 components and loses in the FR-4 substrate.

Posted by Tomaž | Categories: Analog | Comments »

Vector measurements with the rtl-sdr, 2

05.07.2020 10:34

In my last post I've talked about a setup for performing vector reflection measurements with the rtl-sdr. I've come up with an idea for a simple time multiplex hardware so that I could receive both the reference and the measured signal with rtl-sdr's single channel ADC. I did some simulations of the setup and I mentioned that I saw some ±5 degree phase errors. I didn't investigate the source of that error at the time.

After spending some more time thinking about it it turned out that the phase errors I've seen in simulations are due to switch cross-talk. It's quite obvious in retrospect. The measured and reference signals get mixed in the switches and this changes their phase a little. It's best to show this with a phasor diagram:

Phasor diagram of ideal signals.

These are the ideal signals. The reference Uref and the measured signal Udut that passed through the device under test. Udut has a different phase and amplitude compared to the reference and I want to measure that difference.

Phasor diagram of signals with cross-talk.

Due to switch cross-talk, what I'm actually measuring is U'ref and U'dut. U'ref is a sum of both the ideal reference and ideal measured signals, but the measured signal has been attenuated by k, which is the switch cross-talk in linear scale. Vice-versa for Udut. εref and εdut are the phase errors due to this addition.

\varepsilon = \varepsilon_{ref} + \varepsilon_{dut}

The combined phase error depends on the phase shift α in the signal caused by the device under test and the attenuation of the measured signal. The error is largest when α = 90° and the amplitude of the measured signal is smallest. Some geometry also shows that this maximum phase error ε in radians is, for small errors, roughly the same as the switch cross-talk (CT) minus the attenuation of the DUT (A, ratio between Uref and Udut) in linear scale:

\varepsilon \approx 10^{\frac{CT_{dB} - A_{dB}}{20}}\qquad\mathrm{[rad]}

I expect this error to be smaller in practice than what I had in this simulation. First reason is that I made an error and only accounted for one switch in the simulation. I reality there will be two switches and hence, at least in theory, double the attenuation on the unused signal path. The second is that I now plan to use Renesas F2933 switches, which have a much better rated isolation than the F2976 I've considered in my simulation.

Measurement phase error versus switch cross-talk.

Given the limited dynamic range of the rtl-sdr, -80 dB cross-talk or less should probably suffice for a reasonable accuracy over the entire measurable range. I also expect this is the kind of error that I can compensate for, at least to some degree, in software with short-open-load-through (SOLT) calibration. I have to lookup some of my old notes on the math behind that.

Talking about practice, I have the circuit schematic I want to make roughly drawn up on paper. I've decided on all the components I will use. The digital part for driving the switches will be low-voltage 3.3V CMOS logic, since that's compatible with F2933 inputs. For testing purposes I want to also be able to drive the switches from an external signal source and select the signal path manually. Next step is to draw the circuit in some EDA software and design the PCB layout.

Posted by Tomaž | Categories: Analog | Comments »

Vector measurements with the rtl-sdr

21.06.2020 11:41

Previously I was writing about some experiments with reflection measurements using an rtl-sdr receiver. I used the rtl-sdr as a simple power meter together with an RF bridge to measure VSWR. This was a scalar measurement. All the phase information from the signal was lost and with it also the angle information about the complex impedance of the load I was measuring. Since I was happy with how the method performed in that experiment I was wondering if I could adapt the setup to measure the phase information as well.

With a vector measurement I need a reference signal to compare the phase of the measured signal to. This is a problem, since the rtl-sdr only has one input and can only sample a single signal at a time. My idea was that perhaps I could multiplex the reference and the measured signal onto the single input. Both time and frequency multiplex seemed doable, but time multiplex seemed by far simpler to implement in hardware. Integrated microwave switches with usable characteristics, such as Renesas F2976, are reasonably cheap these days.

Previously I recorded a 2 second array of digital samples of the measured signal for each scalar measurement point. With the time multiplex setup, I could record similar 2 seconds of input, but that input would now contain both the reference and the measured signal. I could then de-multiplex and process it in software. The new setup would look something like the following. The device under test could again be a bridge, or something else:

Block diagram of the vector measurement setup.

The time multiplex board contains two SPDT switches. In one position, the switches direct the reference signal to the rtl-sdr. In the other position the signal passes through the device under test and then back to the rtl-sdr. The switch frequency I'm thinking about is somewhere around 100 Hz. A complex baseband signal recorded by the rtl-sdr would then look something like this:

Plot of the simulated complex baseband signal.

Most of the complexity in this setup would be in software. The software would need to find out which parts of the recording is the reference and which part is the measured signal. This is similar to clock recovery in a receiver. It would then compare the two signals and do some filtering. This is a rough block diagram of the processing pipeline:

Block diagram of the signal processing setup.

The reality is a bit more complicated though. Especially clock recovery seems tricky. My original intention was to use auto-correlation of the signal but it turned out much too slow. Right now I'm just using simple amplitude thresholding, which works as long as DUT is attenuating the signal enough compared to the reference. There's also some additional processing required to account for the fact that my delay is an integer number of samples, which introduces an additional random phase shift that needs to be accounted for.

So far I've only performed some proof-of-concept simulations of this setup using the performance of the rtl-sdr I've seen in my scalar measurements and the properties of the switches from the datasheet. It does seem feasible. Here are simulated vector measurements of three points on the complex plane. For example, these might be complex reflection coefficient measurements on the Smith chart. The gray dots show the true value and the blue dots show the simulated measurements:

Simulated vector measurements of three points on the complex plane.

There is some angle and amplitude error, but otherwise the principle seems to work fine. These are the histograms of the errors over a large number of simulated measurements of random points on the complex plane, where the measured signal was well above the receiver noise floor:

Histogram of the amplitude measurement errors.

Histogram of the angle measurement errors.

I'm not sure yet what part contributes the most to these errors. I'm simulating several hardware imperfections, such as switch cross-talk, frequency and phase inaccuracies and receiver noise. The most complicated part here is the clock recovery and I suspect that has the largest effect on the accuracy of the output. The problems with clock recovery actually made me think that having a four-state "off-dut-off-ref" cycle instead of a two-state "dut-ref" for the switches would be better since that would gave a much stronger pattern to match against. Another idea would be to lock the multiplex clock to the actual signal. ERASynth Micro does provide a 10 MHz reference clock out, but dividing it down to 100 Hz would need a huge divider.

Anyway, the simulations so far seem encouraging and I probably can't get much further on paper. I'm sure other factors I haven't thought of will become evident in practice. I plan to make the time multiplexing board in the future and try to do some actual experiments with such a setup.

Posted by Tomaž | Categories: Analog | Comments »

Resistor tolerance and bridge directivity

13.06.2020 14:20

Another short note related to the RF bridge I was writing about previously. The PCB has four resistors soldered on. Two pairs of 100 Ω in parallel. Each pair forms one of the two fixed impedances in the two branches of the bridge circuit. The two variable impedances in the bridge are the device under test (left) and the termination on the REF terminal (right). The black component on the bottom is the RF transformer of the balun circuit.

Four 100 Ω resistors on the RF bridge PCB.

My father pointed out the fact that these resistors don't look particularly high precision. The "101" marking (10 times 101 ohms) is typical of 5% tolerance resistors. 1% parts more often have "1001" or the EIA-96 character code. Unfortunately I can't simply measure them in circuit with a multimeter, because the balun forms a DC short circuit across them. I don't want to desolder them. Still, I was wondering how much variances in these resistors would affect the bridge directivity.

Following is the result of a Monte Carlo simulation showing three histograms for bridge directivity. Each was calculated for one possible tolerance class of the 4 resistors used. The assumption was that individual resistor values are uniformly distributed between their maximum tolerances. The effect of two parallel resistors on the final distribution was included. The peak on each histogram shows the value for directivity that is most likely for a bridge constructed out of such resistors.

Directivity histogram calculated using a Monte Carlo method.

Each tolerance class defines the lowest possible directivity (where the two resistors are most mismatched). On the high end the histogram isn't limited. In any tolerance class there exist some small possibility that the resistors end up being perfectly matched, however the more you move away from the average directivity the less likely that is, as the probability asymptotically approaches zero.

Cumulative distribution function of bridge directivity.

This is the same data shown as an estimate of the cumulative distribution function. The annotations on the graphs show the 90% point. For example, for 5% resistors, 90% of the bridges would have higher than 32.1 dB directivity. You gain approximately 20 dB in directivity each time you reduce the resistor tolerance by a factor of 10.

It's important to note that this was calculated using a low-frequency bridge model. In other words, none of the high-frequency effects that cause the real-life directivity to fall as you go towards higher frequencies are counted. Any effects of the balun circuit and the quality of the REF termination were ignored as well. So the directivity numbers here should be taken as the best possible low-frequency case.

Anyway, I thought this was interesting. Similar results apply to other devices that use a resistor bridge circuit as a directional coupler, such as the NanoVNA and its various variants. Also somewhat related and worth pointing out is this video by W0QE where he talks about resistor matching for calibration loads and how different SMT resistors behave at high frequencies.

Posted by Tomaž | Categories: Analog | Comments »

Experiments with the "Transverters Store" RF bridge

07.06.2020 17:54

The "Transverters Store" RF bridge, for a lack of a better name, is a low-cost bridge circuit that can be used to measure reflection loss or voltage standing wave ratio (VSWR) at radio frequencies. It claims to be usable from 0.1 MHz to 3 GHz. Basic design and operating principle of a similar device is described in "A Simple Wideband Return Loss Bridge Revisited", an article by Paul McMahon from 2005. In it he also gives measurements of its performance up to 500 MHz. The exact device I have seems to be very much related to Paul McMahon's design. It came from a web page called Transverters-Store and shipped from Ukraine. Very similar looking products with more or less exact copies of the PCB layout are available from various other sources. Since there's no product number or a clear name associated with it, most often people refer to these as simply "that cheap bridge from eBay".

The "Transverters Store" RF bridge.

In short, the bridge operates similarly to the typical resistor bridge networks, like the Wheatstone bridge. The network is composed of two 50 Ω resistors on the PCB itself (each made out of two parallel 100 Ω resistors), the reference load on the REF port and the device under test on the DUT port. The biggest difference is the addition of a balun circuit. This makes the detector output referenced to ground, instead of floating between the two bridge branches like in a low-frequency bridge. The balun is implemented here as a high-frequency transformer made out of a row of black ferrite beads and two lengths of coax.

The bridge can in principle be thought of as a directional coupler. The signal power on the OUT port only corresponds to the reflected power coming back in to the DUT port, but (ideally) not the forward power going out of that port to the device under test. Compared to a true directional coupler however the bridge can't be operated in the reverse. You can't measure forward power by connecting a signal source on the OUT port and a detector on the IN port.

Ideal bridge output versus return loss.

This is how the bridge would behave if everything was ideal. The vertical axis shows the power on the OUT port relative to the power on the IN port. The horizontal axis shows return loss of the device under test. Using directional coupler terminology, the bridge has a coupling factor of 16 dB if used with a 50 Ω detector. It's also interesting to see that if using such a detector on the OUT port, the output of the bridge is slightly non-linear in respect to return loss. The difference is small - an open circuit will measure around 1.5 dB too high and a short will measure around 1.5 dB too low. Considering other inaccuracies, this detail probably isn't significant in practice.

Below you can see the setup I used for the experiments. Signal source on the top left is an ERASynth Micro. The detector on top right is an Ezcap DVB-T dongle (using Elonics E4000 tuner) and rtl-power-fftw. Both the source and the detector are controlled from a PC through a USB connection. Above the bridge you can see the terminations I used in the experiments: A borrowed professional Narda Micro-Pad 30 dB attenuator (DC - 18 GHz) which I used as a terminator, a couple of home-made 50 Ω SMA terminators (using two parallel 100 Ω 0603 resistors in a SMA connector), a home-made short and a no-name terminator that has a through-hole metal-film 51 Ω resistor inside.

The setup for experiments with the RF bridge.

Using this setup I tried to measure the directivity of the bridge. Directivity is the measure of how well the bridge selects between the forward and reflected power. The higher directivity, the lower return loss and VSWR you can reliably measure with it. Anritsu has a good application note that describes how directivity affects measurement error. I measured directivity by measuring OUT port power twice: once with a short on the DUT port and once with my home-made terminator. Dividing these two values gave an estimate of bridge directivity. I performed two measurements: once with the Narda attenuator on the REF port and once with my home-made terminator using two 0603 SMT resistors.

There is an approximately 200 MHz wide gap in my measurements at around 1.1 GHz because the DVB-T receiver cannot tune on those frequencies.

Measured directivity of the RF bridge.

You can see that my two measurements differ somewhat. In both, the bridge shows good directivity up to around 1 GHz. Above that, it's below 20 dB which introduces a large error in measured VSWR as you'll see below. The DVB-T receiver I used also shows a decrease in sensitivity above 1 GHz, however I've repeated this measurement using different input power levels (from -10 dBm to -30 dBm on ERASynth micro) and they all show similar results, hence I believe the measured decrease in directivity is not due to the limited dynamic range of my measurement setup.

In general, I think the biggest source of errors during these experiments are the terminators I've used. The directivity measurement assumes that the bridge can be measured with perfect termination on both the DUT and REF ports. By testing various combinations of terminators I had at hand I've seen significant differences in output port power, which suggest they are all slightly imperfect in different ways.

My measurements of directivity compared to seller's.

This is how my measurements compare with the measurements published on the Transverters Store website. The blue and orange plots are same results as above, only rescaled. Red plot is the Transverters' result. Again, my results differ from theirs. Below 500 MHz mine show a bit better directivity. Above 500 MHz mine are worse. Both show a slow decrease and then a sharp fall at around 1 GHz. I'm not claiming their measurements are wrong. My setup is very much improvised and can't compare to professional equipment. It's also very likely that different devices differ due to manufacturing tolerances.

Measured VSWR of the cheap SMA terminator.

Finally, here's an example of a VSWR measurement using this setup. I've measured the bad attenuator I've mentioned in my previous blog post that's made using a standard through-hole resistor. Again, the blue and orange plots show measurements using the two different references on the REF port of the bridge. The shaded areas show the error interval of the VSWR measurement due to bridge directivity I measured earlier. The VSWR of the device under test can be anywhere inside the area.

Interestingly, the terminator itself doesn't seem that bad based on this measurement. Both of my measurements show that the upper bound of the VSWR is below 1.5 up to 1 GHz. Of course, it all depends on the application whether that is good enough. You can also see that above 1 GHz the error intervals increase dramatically due to low bridge directivity. The lower bounds do carry some information (e.g. the terminator can't have VSWR below 1.5 at 2 GHz), but the results aren't really useful for anything else that a rough qualitative estimate.

In the end, this seems to be useful method of measuring return loss and VSWR below 1 GHz. Using it at higher frequencies however doesn't look too promising. 3 GHz upper limit seems to me like a stretch at this point. The largest practical problem is finding a good 50 Ω load to use on the REF port, a problem which was also identified by others (see for example a comment by James Eagleson below his video here). Such precision loads are expensive to buy and seem hard to build at home.

I was also surprised how well using the DVB-T tuner as a power meter turned out in this case. I was first planning to use a real power meter with this setup, but the device I ordered seemingly got lost in the mail. I didn't see any indication that the dynamic range of the tuner was limiting the the accuracy of the measurement. Since all measurements here use only ratios of power, absolute calibration of the detector isn't necessary. With the rtl-sdr device you only need to make sure the automatic gain control is turned off.

Posted by Tomaž | Categories: Analog | Comments »

What's inside cheap SMA terminators

29.05.2020 14:16

I've recently ordered a bag of "YWBL-WH" 50 Ω SMA terminators off Amazon along with some other stuff. Considering they were about 3 EUR per piece and I was paying for shipment anyway, they seemed like a good deal. Unsurprisingly, they turned out less than stellar in practice.

50 Ω SMA terminators I bought off Amazon.

At the time when I bought them, the seller's page listed these specifications, claiming to be usable up to 6 GHz and 2 W of power dissipation. There's no real brand listed and identical-looking ones can be found from other sellers:

Specifications for 50 ohm SMA terminators.

Their DC resistances all measured very close to 51 Ω, which is good enough. However when I tried using them for some RF measurements around 1 GHz I got some unusual results. I thought the terminators could be to blame even though I don't currently have equipment to measure their return loss. If I had bothered to scroll down on that Amazon page, I might have seen a review from Dominique saying that they have only 14 dB return loss at 750 MHz and are hence useless at higher frequencies.

I suspected what's going on because I've seen this before in cheap BNC terminators sold for old Ethernet networks, but I still took one apart.

Cheap SMA terminator taken apart.

Indeed they simply have a standard through-hole axial resistor inside. The center SMA pin is soldered to the lead of the resistor, but ground lead was just pressed against the inside of the case. According to the resistor's color bands it's rated at 51 Ω, 5% tolerance and 100 ppm/K. I suspect it's a metal film resistor based on the blue casing and low thermal coefficient (if that's what the fifth color band stands for). It might be rated for 2 W, although judging by the size it looks more like 1/2 W to me. In any case, this kind of resistor is useless at RF frequencies because of its helical structure that acts like an inductor.

Again it turned out that cheaping out on lab tooling was just a waste of money.

Posted by Tomaž | Categories: Analog | Comments »

Simple method of measuring small capacitances.

22.05.2020 18:17

I stumbled upon this article on Analog Devices' website while looking for something else. It looks like instructions for a student lab session. What I found interesting about it is that it describes a way of measuring small capacitances (around 1 pF) with only a sine-wave generator and an oscilloscope. I don't remember seeing this method before and it seems useful in other situations as well, so I thought I might write a short note about it. I tried it out and indeed it gives reasonable results.

Breadboard capacitance measurement schematic.

Image by Analog Devices, Inc.

I won't go into details - see original article for a complete explanation and a step-by-step guide. In short, what you're doing is using a standard 10x oscilloscope probe and an unknown, small capacitance (Crow in the schematic above) as an AC voltage divider. From the attenuation of the divider and estimated values of other components it's possible to derive the unknown. Since the capacitance of the probe is usually only around 10 pF, this works reasonably well when the unknown is similarly small. The tricky part is calibrating this measurement, by estimating stray capacitances of wires and more accurately characterizing the resistance and capacitance of the probe. This is done by measuring both gain of the divider and its 3 dB corner frequency.

Note that the article is talking about using some kind of an instrument that has a network analyzer mode and can directly show a gain vs. frequency plot. This is not necessary and it's perfectly possible to do this measurement with a separate signal generator and a digital oscilloscope. For measuring capacitances of around 1 pF using a 10 pF/10 MΩ probe a signal generator capable of about 100 kHz sine-wave is sufficient. Determining when the amplitude of the signal displayed on the scope falls by 3 dB probably isn't very accurate, but for a rough measurement it seems to suffice.

The measurement depends on the probe having a DC resistance to ground as well as capacitance. I found that on my TDS 2002B scope you need to set the channel to DC coupled, otherwise there is no DC path to ground from the probe tip. It seems obvious in retrospect, but it did confuse me for a moment why I wasn't getting good results.

I also found that my measured signal was being overwhelmed by the 50 Hz mains noise. The solution was to use external synchronization on the oscilloscope and then use the averaging function. This cancels out the noise and gives much better measurements of the signal amplitude at the frequency that the signal generator is set to. You just need to be careful with the attenuator setting so that noise + signal amplitude still falls inside the scope's ADC range.

Posted by Tomaž | Categories: Analog | Comments »

Another SD card postmortem

16.05.2020 11:28

I was recently restoring a Raspberry Pi at work that was running a Raspbian system off a SanDisk Ultra 8 GB micro SD card. It was powered on continuously and managed to survive almost exactly 6 months since I last set it up. I don't know when this SD card first started showing problems, but when the problem became apparent I couldn't log in and Linux didn't even boot up anymore after a power cycle.

SanDisk Ultra 8 GB micro SD card.

I had a working backup of the system, however I was curious how well ddrescue would be able to recover the contents of the failed card. To my surprise, it did quite well, restoring 99.9% of the data after about 30 hours of run time. I've only ran the copy and trim phase (--no-scrape). Approximately 8 MB out of 8 GB of data remained unrecovered.

This was enough that fsck was able to recover the filesystem to a good enough state so that it could be mounted. Another interesting thing in the recovered data was the write statistic that is kept in ext4 superblock. The system only had one partition on the SD card:

$ dumpe2fs /dev/mapper/loop0p2 | grep Lifetime
dumpe2fs 1.43.4 (31-Jan-2017)
Lifetime writes:          823 GB

On one hand, 823 GB of writes after 6 months was more than I was expecting. The system was setup in a way to avoid a lot of writes to the SD card and had a network mount where most of the heavy work was supposed to be done. It did have a running Munin master though and I suspect that was where most of these writes came from.

On the other hand, 823 GB on a 8 GB card is only about 100 write cycles per cell, if the card is any good at doing wear leveling. That's awfully low.

In addition to a raw data file, ddrescue also creates a log of which parts of the device failed. Very likely a controller in the SD card itself is doing a lot of remapping. Hence a logical address visible from Linux has little to do with where the bits are physically stored in silicon. So regardless of what the log says, it's impossible to say whether errors are related to one failed physical area on a flash chip, or if they are individual bit errors spread out over the entire device. Still, I think it's interesting to look at this visualization:

Visualization of the ddrescue map file.

This image shows the distribution of unreadable sectors reported by ddrescue over the address space of the SD card. The address space has been sliced into 4 MB chunks (8192 blocks of 512 bytes). These slices are stacked horizontally, hence address 0 is on the bottom left and increases up and right in a saw-tooth fashion. The highest address is on the top right. Color shows the percentage of unreadable blocks in that region.

You can see that small errors are more or less randomly distributed over the entire address space. Keep in mind that summed up, unrecoverable blocks only cover 0.10% of the space, so this image exaggerates them. There are a few hot spots though and one 4 MB slice in particular at around 4.5 GB contains a lot of more errors than other regions. It's also interesting that some horizontal patterns can also be seen - the upper half of the image appears more error free than the bottom part. I've chosen 4 MB slices exactly because of that. While internal memory organization is a complete black box, it does appear that 4 MB blocks play some role in it.

Just for comparison, here is the same data plotted using a space-filling curve. The black area on the top-left is part of the graph not covered by the SD card address space (the curve covers 224 = 16777216 blocks of 512 bytes while the card only stores 15523840 blocks or 7948206080 bytes). This visualization better shows grouping of errors, but hides the fact that 4 MB chunks seem to play some role:

Visualization of the ddrescue map file using a Hilbert curve.

I quickly also looked into whether failures could be predicted by something like SMART. Even though it appears that some cards do support it, none I tried produced any useful data with smartctl. Interestingly, plugging the SanDisk Ultra into an external USB-connected reader on a laptop does say that the device has a SMART capability:

$ smartctl -d scsi -a /dev/sdb
smartctl 6.6 2016-05-31 r4324 [x86_64-linux-4.9.0-12-amd64] (local build)
Copyright (C) 2002-16, Bruce Allen, Christian Franke,

Vendor:               Generic
Product:              STORAGE DEVICE
Revision:             1206
Compliance:           SPC-4
User Capacity:        7 948 206 080 bytes [7,94 GB]
Logical block size:   512 bytes
scsiModePageOffset: response length too short, resp_len=4 offset=4 bd_len=0
Serial number:        000000001206
Device type:          disk
scsiModePageOffset: response length too short, resp_len=4 offset=4 bd_len=0
Local Time is:        Thu May 14 16:36:47 2020 CEST
SMART support is:     Available - device has SMART capability.
SMART support is:     Enabled
Temperature Warning:  Disabled or Not Supported

SMART Health Status: OK
Current Drive Temperature:     0 C
Drive Trip Temperature:        0 C

Error Counter logging not supported

scsiModePageOffset: response length too short, resp_len=4 offset=4 bd_len=0
Device does not support Self Test logging

However I suspect this response comes from the reader, not the SD card. Multiple cards I tried produced the same 1206 serial number. Both a new and a failed card had the "Health Status: OK" line, so that's misleading as well.

This is a second time I was replacing the SD card in this Raspberry Pi. The first time it lasted around a year and a half. It further justifies my opinion that SD cards just aren't suitable for unattended systems or those running continuously. In fact, I suggest avoiding them if at all possible. For example, newer Raspberry Pis support booting from USB-attached storage.

Update: For further reading on SD card internals, Peter mentions an interesting post in his comment below. The flashbench tool appears to be still available here. The Linaro flash survey seems to have been deleted from their Wiki. A copy is available from

Posted by Tomaž | Categories: Digital | Comments »