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 google.com, 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 »