Termination Insensitive Amplifier (TIA)

I recently put together a PCB for a termination insensitive amplifier, based on the original article by Wes Hayward, W7ZOI, and Bob Kopski, K3NHI.

The general idea is to provide an amplifier that has an input impedance (usually presenting a 50Ω impedance) which does not depend upon the output load, and an output impedance that does not depend on the amplifier input, all while providing around 15 dB of gain. These can be a good choice to use between your mixer and IF stage to reduce reflections caused by impedance mismatches.

The original design was intended for bi-directional use, but these boards are intended as a single path, with the intention of using them as a pair when bi-directionality is required.

You can find my PCB here.

The KiCad files and LTSpice can be found on my github page.

Maytag MVW5430MW top load washing machine with F9E1 long drain fault

I have a 3 month old Maytag MVW5430MW top load washing machine that failed to drain and would stop at the “wash” setting. I ran the diagnostics mode on it and found it had a F9E1 long drain fault.

The following table demonstrates how to read this diagnostics code:

The first set of LEDs that flash will be the F Code, followed by the second flash being the E code. Add the numbers together per the values in the table. For example, an F9 will be the 1st LED (F), the 2nd LED (8) and the 5th LED (1).

These newer (>2022) Maytag machines can enter diagnostics to read these codes, using the following procedure (from the related tech sheet):

Since this was a drain issue, the first thing I checked was that the hoses did not have any blockages. I then removed the pump to verify that the impeller was not clogged with debris (I read some reports online of of beach sand and dirt causing the pump to seize).
Both were clear. I then verified the pump was electrically working by checking the resistance. I first disconnected the power to the washer and then disconnected the pump connector. I then used my multimeter to check the resistance across the pump’s terminals. A working pump should be around 20 ohms, which mine was.

At this point it was apparent that the issue was not related to an actual clog or a pump failure but instead related to the control board or harness.
I checked the continuity between the pump connector and the connector that attaches to the control board for both the black/white wire and teal wire to verify the wires didn’t have a break.

The control board can be accessed from the back, by taking off the metal panel and removing the two screws on each end that hold the control board in:

Pump connector:

Control Board Connector:

I had no continuity on the black/white wire, so I went searching through the wiring harness and sure enough, the issue turned out to be a broken wire where the two wires branch off to the pump:

This appears to be a common problem with these units, so if you have verified the pump to be good, then I would verify the pump has a good connection to the control board.

If you need to reset or run a calibration on one of these units, this video explains the sequence.

A low pass filter for 40m

I’m currently finishing a 20w amplifier from EI9GQ’s book “Building a Transceiver” to pair with the “Simple SSB” 40 meter transceiver I recently completed.

The amplifier was mostly complete but I still needed a low pass filter for it. I had a look at the filter design suggested in Eamon’s book, but I didn’t have all the capacitor values or toroid types recommended. I therefore decided to use LT Spice to tweak the values to see if I could get by with what was in the junk box.

What I came up with was the following:

I then went on to building the filter, using what I had specified in LT Spice. I paralleled two 430pf capacitors for both C2 and C3 and used three T68-2 toroids with 16 turns each to give the approximate inductance.

I then soldered on some temporary SMA connections and hooked up the NanoVNA.

This looked pretty good to me, with attenuation at the second harmonic being down around -50dB and a cutoff frequency at around 8MHz.

Creating a Debian mirror for Raspberry Pi using Aptly

Having a local mirror of Debian provides you more control over how and when your devices are updated. It can also be useful in situations where devices may not have access to public mirrors. In this post we will describe a method to create a local Debian mirror that can be used for Raspberry Pi devices.

Aptly

Aptly is a tool for managing Debian package repositories and mirrors.

There are several steps to setup a mirror using Aptly. These consist of the following:

  1. Import keys for signature verification
  2. Create the local mirrors
  3. Perform updates to fetch the packages from the origin mirror
  4. Create snapshots
  5. Create a GPG key for signing
  6. Publish the snapshot(s) to an endpoint
Import public keys for verifying signatures:
sudo apt install debian-archive-keyring

gpg --no-default-keyring --keyring /usr/share/keyrings/debian-archive-keyring.gpg --export | gpg --no-default-keyring --keyring trustedkeys.gpg --import

gpg --no-default-keyring --keyring trustedkeys.gpg --keyserver keyserver.ubuntu.com --recv-keys 0E98404D386FA1D9 6ED0E7B82643E131 82B129927FA3303E

Note: Some Debian keys were not available and were sourced from the Ubuntu key server instead, as seen in the last line above.

Creating the mirrors

At the time of writing, the current Raspberry Pi sources.list and raspi.list for “bullseye” reference the following repos:

/etc/sources.d

  • deb http://deb.debian.org/debian bullseye main contrib non-free
  • deb http://security.debian.org/debian-security bullseye-security main contrib non-free
  • deb http://deb.debian.org/debian bullseye-updates main contrib non-free

/etc/sources.list.d/raspi.list

  • deb http://archive.raspberrypi.org/debian/ bullseye main

We therefore need to replicate this within our own repository.

The following demonstrates the commands to create the mirrors using Aptly:

bullseye-main

aptly mirror create -architectures="arm64" --keyring=trustedkeys.gpg bullseye-main http://deb.debian.org/debian bullseye main contrib non-free

bullseye-security

aptly mirror create -architectures="arm64" --keyring=trustedkeys.gpg bullseye-security http://security.debian.org/debian-security bullseye-security updates/main updates/contrib updates/non-free

Note: there is a known Aptly issue that requires the use of “updates/main” “updates/contrib” “updates/non-free” instead of the usual “main”, “contrib”, “non-free” naming of components when creating the “bullseye-security” mirror.

bullseye-updates

aptly mirror create -architectures="arm64" --keyring=trustedkeys.gpg bullseye-security http://security.debian.org/debian-security bullseye-security updates/main updates/contrib updates/non-free

rasp-bullseye-main:

aptly mirror create -architectures="arm64" --keyring=trustedkeys.gpg rasp-bullseye-main http://archive.raspberrypi.org/debian/ bullseye main
Updating the mirrors:

Updating will download the files from the origin and can take some time to complete. I recommend using screen session for updating to allow the downloads to continue if you are disconnected.

aptly mirror update bullseye-main

aptly mirror update bullseye-security

aptly mirror update bullseye-updates

aptly mirror update rasp-bullseye-main
Creating a snapshot:

Snapshots reflect a instance of the repository at a certain point in time and should be postfixed with a timestamp:

aptly snapshot create bullseye-main-20231221 from mirror bullseye-main 

aptly snapshot create bullseye-security-20231221 from mirror bullseye-security

aptly snapshot create bullseye-updates-20231221 from mirror bullseye-updates

aptly snapshot create rasp-bullseye-main-20231221 from mirror rasp-bullseye-main
Merging the snapshots in preparation for publishing:

Snapshots can be published individually or merged into a single final snapshot. A single snapshot can have the advantage that you only need to add a single URL to the client’s sources.list file. But be aware however that it can also cause security warnings because apt thinks the security updates repository is missing, since it is not specified explicitly in the sources.list.

The following will take the individual snapshots and combine them into a single final snapshot that can be used for publishing:

aptly snapshot merge -latest bullseye-final-20231221 bullseye-main-20231221 bullseye-security-20231221 bullseye-updates-20231221 rasp-bullseye-main-20231221
Key generation:

A signing key pair must be created before publishing. The public key is provided to the client (often in the public web root directory) and is used by apt to verify package signatures.

This can be done with the following:

gpg --gen-key

Export the public key to be later provided to the client:

gpg2 --export --armor > signing.pub
Publishing:

Publishing will write all files to ~/.aptly/public, with the expectation to then serve them via a web server:

aptly publish snapshot -distribution=bullseye bullseye-final-20231221

Once publishing is finished, you will be provided with a URL in the output that can be used to update the client device’s sources.list file:

ie. deb http://<example.com>/mirror bullseye main

Re-publishing:

Republishing a new snapshot (with updates from the remote repository) requires updating the local mirror, creating a new snapshot, merging and then performing a aptly publish switch instead of an aptly publish snapshot.

Example of performing a publish switch is below:

aptly publish switch bullseye bullseye-final-20231221
Hosting

Once published, a new directory will be created: ~/.aptly/public. You can then use a web server such as NGINX to serve this directory and make it available to client devices.

Client Device Setup

To setup a new device to use the mirror, the following steps must be taken:

  1. Download and import the signing key (in this example, from the public web server’s root directory)
  2. Comment or remove existing sources.list and raspi.list entries for the existing Debian and Raspberry Pi repositories and replace them with a reference to the new mirror URL or mirror list file.
  3. Update apt against the new mirror and upgrade the existing packages
Fetching and installing the public signing key:

First make sure you have placed the signing.pub from above in the ~/.aptly/public directory to be served by your web server.

We then need to run the following from the client device to fetch the new key.

Note: since the deprecation of apt-key add, the following command is instead recommended to download the key from the mirror public root and install into the local system’s /usr/share/keyrings folder, where it can be used by apt:

wget -O - -q https://<example.com>/mirror/signing.key | sudo gpg --dearmor -o /usr/share/keyrings/mirror-keyring.gpg

Of course, replace the above example URL with your mirrror’s URL.

Updating the sources.list files:

As mentioned above the current Raspberry Pi /etc/apt/sources.list and /etc/apt/sources.list.d/raspi.list for “bullseye” reference the following repos which will need to be removed or commented out, like so:

sources.list

# deb http://deb.debian.org/debian bullseye main contrib non-free
# deb http://security.debian.org/debian-security bullseye-security main contrib non-free
# deb http://deb.debian.org/debian bullseye-updates main contrib non-free

raspi.list

# deb http://archive.raspberrypi.org/debian/ bullseye main

Now, add a new entry to the sources.list or create a new file in /etc/sources.list.d/ that contains a reference to the new mirror:

echo "deb [signed-by=/usr/share/keyrings/mirror-keyring.gpg] https://<example.com>/mirror bullseye main" | sudo tee /etc/apt/sources.list.d/mirror-bullseye.list

Again, replace the above example URL with your own mirror’s URL.

Apt update and upgrade:

Once the sources have been updated, then an apt update will be required to refresh the package information using the new mirror:

sudo apt update

Followed by an upgrade:

sudo apt upgrade

Socket redirection with GPG

Recently, I had a scenario where my .gnupg directory was being hosted in a Docker volume instead of the standard home directory on Linux. For those that may not be aware, the default GPG directory can be changed by defining the environment variable GNUPGHOME with a different directory. However, because the sockets that GPG was using were now being persisted across containers, I was getting errors from the gpg-agent.

After some research, I discovered that GPG supports changing where it stores its socket files, by providing a redirection in place of the socket files themselves.

There are several of these files that need to be updated for redirection:

  • S.gpg-agent
  • S.gpg-agent.browser
  • S.gpg-agent.extra
  • S.gpg-agent.ssh

These are described as follows in the GnuPG ArchWiki:

  • The main gpg-agent.socket is used by gpg to connect to the gpg-agent daemon.
  • The intended use for the gpg-agent-extra.socket on a local system is to set up a Unix domain socket forwarding from a remote system. This enables to use gpg on the remote system without exposing the private keys to the remote system. See gpg-agent(1) for details.
  • The gpg-agent-browser.socket allows web browsers to access the gpg-agent daemon.
  • The gpg-agent-ssh.socket can be used by SSH to cache SSH keys added by the ssh-add program. See #SSH agent for the necessary configuration.
  • The dirmngr.socket starts a GnuPG daemon handling connections to keyservers.
Configuration

To add support for socket redirection, we need to both update the GPG configuration and create three other files…

For S.gpg-agent.extra and S.gpg-agent.browser, add the following to the .gnupg/gpg-agent.conf file (create the file if it doesn’t already exist):

extra-socket /var/run/S.gpg-agent.extra
browser-socket /var/run/S.gpg-agent.browser

For S.gpg-agent, S.gpg-agent.ssh and S.dirmngr, create three separate files:

$ printf '%%Assuan%%\nsocket=/var/run/S.gpg-agent\n' > ${GNUPGHOME}/S.gpg-agent

$ printf '%%Assuan%%\nsocket=/var/run/S.gpg-agent.ssh\n' > ${GNUPGHOME}/S.gpg-agent.ssh   

$ printf '%%Assuan%%\nsocket=/var/run/S.dirmngr\n' > ${GNUPGHOME}/S.dirmngr 

In the above, you can see we are now using /var/run as the new socket location. I’m also assuming that you’ve previously set the GNUPGHOME environment variable. If not, then substitute your .gnupg directory instead.

Once complete you will want to restart the gpg-agent:

gpg-connect-agent reloadagent /bye  
Helpful References: