Sunday, November 20, 2016

eBay J-Link OB clone SWO hacking

Some time ago I bought a standalone J-Link OB clone off eBay. The J-Link OB (On Board) is a small footprint debugger, which Segger licenses to manufacturers to put on their boards, so that no external debugger needs to be used. Despite of this, standalone clones of this debugger have been available on eBay for some time very cheaply. I couldn't resist the price, although looking back, I probably should have just bought the J-Link EDU for 60e.
The J-Link OB standalone clone, which I purchased. Picture taken from eBay listing.
To the point. The debugger works well and all, but lacks SWO capability - in fact there are no J-Link OB clones on the market, which would support it. SWO is a fast serial line for transferring debugging data from the microcontroller to the host computer. The microcontroller has dedicated hardware for this, and the transmission of data is managed without breaking the execution on the microcontroller. Lack of this capability limits the tracing to either UART based transmission or semihosting, which requires setting special break points in the code and thus causes a considerable delay in execution. The material from Segger however indicates that the J-Link OB should support SWO. This got me thinking if the debugger could be modified to support SWO.

Looking around the internet I managed to find the schematic of a J-Link OB debugger using the same microcontroller as the one in my debugger (this is the STM32F103C8 in a QFP48). I won't link it or replicate it here as it is something that should be licensed from Segger. The schematic wasn't an exact representation of the circuit in my debugger, but it was close enough.

The schematic showed that all JTAG pins were in fact connected to some pins of the microcontroller. Most of the them in fact had two pins on the microcontroller - a drive pin and a sense pin - and had 100 ohm resistors connected between the drive and sense pins. The SWO is transmitted through the JTAG pin TDO. This pin is an exception to the drive and sense arrangement, as it only had the sense pin. Luckily it was still connected to an external pull-up resistor, which allowed for easy modification.

The SWO input is directly tied to microcontroller pins PA6 (pin 16), PA10 (pin 31) and PB15 (pin 28). For a first test, I just soldered a wire to the low side of the pull-up resistor and attached that to the SWO output of my target.

Quick bodge to see if SWO works on the debugger.
The initial test produced output on the SWO terminal, which was synchronized with the output from the target, but complete garbage. This turned out to be only a problem of configuration. Once that was taken care of, the messages were coming through loud and clear :-)

Satisfied by the way everything was working, I then built a more permanent solution by removing the old 4 pin connector and replacing it with a 5 pin header. There is no hole for the fifth pin, so I cut the pin short (making sure it couldn't touch the ground pad under it) and soldered the 4 other pins. The fifth pin was then connected with a bodge wire over the to resistor. To support the unsoldered fifth pin mechanically, cyanoacrylate glue was added to attach it more securely to the pin header frame as well as the neighboring pins.

A more permanent solution.

The speedup of using SWO instead of semihosting is considerable. In the plots below there is an example of quasicontinuous I2C communication, where some tracing messages are periodically sent to the debug host. The channels 0 and 1 are the I2C lines, while channel 2 is connected to a "data ready" IRQ pin of the I2C device. Channel 3, which is only shown in the latter figure, is the actual SWO data.

It is clear from the figure below that when the semihosting mechanism is used for message transmission there is a period of more than 30 ms where the microcontroller is not capable of responding to the IRQ. When the execution continues, the first few I2C transfers are considerably longer than typical, as unread data is read out from the FIFO of the device.

Logic analyzer view of I2C communication with semihosting tracing messages.
When tracing is sent through SWO, on the other hand, there is no noticable change in the I2C communication in this example. In fact, the time required to respond to the interrupt doesn't change by a measurable amount, nor can I see any other change in the timing.

Logic analyzer view of I2C communication with SWO tracing messages.

Sunday, June 5, 2016

Making a case for an eBay transistor tester

Quite some time ago I purchased a transistor tester from eBay. The device is based on the AVR transistor tester project originally by Markus Frejek, and further developed by Karl-Heinz Kübbeler. There are several varieties of these devices for purchase on eBay, and I went with basically the cheapest version available. Despite of this, it seems to work very well.

Figure 1: The transistor tester.
As seen in Figure 1, it is just the bare PCB with no case, and even the display is almost hanging loose. I originally bought the item basically as a curiosity, but I find myself using it quite often. For this reason I think it deserves a case.

Recently I took some time to make my CNC router operational again (perhaps I'll post about this in the future), and what better way to make the case than mill it out of wood :-). I had some black alder stock left over from our sauna renovation, which was of suitable thickness and width. So I fired up the CAD and started drawing.
Figure 2: The case design.
There is nothing special with the design. It has a lot of the material cut out to fit the board and the 9V battery used to power it, and has a lip around the cut out to rise the board at a suitable height for a possible cover plate, which I haven't done yet. I exported the projected geometry to the CAM and produced tool paths.

Figure 3: Projected geometry imported.
Figure 4: Tool paths for a 6mm straight cutter.

I then cut the piece out on the CNC router, where everything went smoothly. The tooling left a 3mm round over in the inside corners, which - in order to fit the PCB - I had to remove manually with a chisel.

Figure 5: Good enough.
Figure 6: PCB and battery fitted in the case.
I still need to cut a cover plate over the case from aluminum, but even before that this case makes using and storing the tester much easier.

Friday, March 18, 2016

Listening to satellites

I have had an RTL-SDR (these are cheap software defined radios using ICs originally meant for DVB-T reception) for some time already. I've previously been listening to airplanes, local radio amateurs and all sorts of telemetry data whizzing in the air. Recently I got interested of listening to amateur radio satellites, or to put more accurately, recently I learned that it is possible to do that with basically the gear I already had.

Mostly the satellites transmit at one of two bands, at 144 MHz or at 433 MHz. I had dipole antennas built for the bands already, but I didn't have a balanced feed to them as I had been using them inside very close to the receiver. To have the best chance of receiving anything from the satellites, I had to place them outside. The best solution of course would be to have the receiver reside outside close to the antenna and to just pull the data through a cable, but high speed USB doesn't really work over very long cables. The other solution would then be to have a computer (like a raspberry pi or something) close by to the receiver, perhaps even outside, and then pull the data in over Ethernet. The distance would have been too long for USB and I don't currently have a suitable small computer to use near the receiver I couldn't do with either of those options. Thus I had to add some balancing to the antenna feed and to pull the signal in with a coaxial cable.

The simplest way to build a balanced antenna, I found, was to build a folded dipole with a loop of coaxial cable acting as the balun. The folded dipole has an impedance of about 300 ohms, with the coaxial cable doing a 1:2 voltage division, thus acting as a 1:4 balun. The feed signal is then a 75 ohm signal, which is suitable for the RTL-SDR. A folded dipole is also basically as easy to build as a regular dipole.

With this new setup I was able to hear the local transmission at much increased power and signal-to-noise ratios. However, I didn't hear any satellites. After several nights of trying to hear something, I realized that the amateur radio satellites were in fact solar powered, and not transmitting when not illuminated by the sun. Unfortunately, I don't get much chance listening to satellites at day time due to my day job, and even during weekends it is only possible when the kids are napping.

One evening, just a short while before sunset, I plugged in the receiver to notice a strong transmission I hadn't seen before. Looking at it more closely, I realized it was drifting in frequency! This had to be a satellite. Unless someone was deliberately generating a signal that looked like it had such a strong Doppler shift. I started recording the IQ samples to store it for demodulating later. After two minutes of recording, the signal had vanished.

Screenshot from GQRX showing the satellite signal. The blue area is a spectral histogram of the signal, with frequency in the horizontal axis, time in the vertical axis and signal magnitude indicated with color. The Doppler effect is clearly visible, so the signal must have come from a satellite.
After I was confident the signal was not coming back, I started playing back the IQ data to demodulate the signal. It seems to be some type of audio modem signal, which itself is modulated using narrow FM. The signal is quite noisy, but it clearly has a ~2.4 kHz carrier frequency, which is present intermittently. Whether there is other data than just the intermittent carrier, is lost to noise. A sample of the signal can be obtained here.

As the signal didn't want to be demodulated, and as I couldn't even figure out what modulation it uses, I started to investigate which satellite was responsible for the transmission. The original transmission frequency is difficult to estimate due to the Doppler shift, but my guess is that it was somewhere in the band between 435.56 MHz and 435.57 MHz. I first looked at the amateur radio satellites in GPredict, as it has a very nice time control feature, which easily allows me to check what satellites were in the sky at the time of the transmission. Turns out that GPredict doesn't know this satellite, as none of the satellites it showed transmit at this frequency.

Turning to Google and looking through lists of satellites and their transmit frequencies gives a short list of possible candidates. Finally I find a match with a Russian military satellite Kosmos-2499! It carries a radio amateur payload called RS-47, which transmits on 435.565 MHz, and which was on the sky at the time of recording. There is also this YouTube video with the demodulated signal from the satellite. It sounds exactly like the signal I got. That's pretty cool.

The international space station transmits constantly, even when it is in the Earth's shadow. So in the evening I tuned the receiver to the ISS's frequency range and started to record a spectral histogram. In the morning I could clearly see signals corresponding with ISS passes, as well as several other transmission which also were clearly from satellites.

ISS data signals visible at 145.825 MHz. The annotations I've added are in local time (UTC+2). These times match with the passes of the ISS. The other signals have yet to be identified. There is some local interference, which produces the constant vertical lines. These are probably ghosts from the radio receiver, and not real signals.
I'll need to write some software for recording these signals in an efficient way. My idea is that the software would monitor certain bands and trigger the recording of those bands only in case there is something interesting. Currently I can only record the full IQ sample data from GQRX, which produces around 1 gigabyte per minute.

Wednesday, March 9, 2016

Modifications to a kids' electric scooter

Last summer my mother-in-law found an kids' electric scooter in the free section of a local thrift store. It was lacking a seat and a battery. Back then I quickly made a new seat by laminating sheets of polyethylene plastic together, and also hacked up a battery from my airplane lithium batteries and a DC-DC buck regulator. It was driven almost daily throughout the summer, until it had to be taken inside in the fall.

It was obviously not really designed to be an outside toy, as was evident from the decay of all the decal stickers from just one summer outside. We don't have the space play with it inside though, so it shall remain an outside toy. However, while I had it in for the winter I decided to clean the whole thing. It was already dirty from the thrift shop in addition to a summers worth of daily play. I took the whole thing to pieces and washed everything carefully. This made it look almost band new, but I also wanted to update some functionality.

The scooter originally just ran current through a foot pedal switch directly from the battery to the motor. This is quite hard for the transmission as there is a huge torque spike when the pedal is pressed. It also requires connecting and disconnecting quite large DC currents through an inductive load. This has left quite clear marks on the contact surfaces inside the pedal. Without any speed regulation, the scooter runs slow uphill and fast downhill. Finally, there is no reverse implemented, which together with the rather large turning radius causes problems in tight corners.

I wanted to address all of the problems through an electric speed controller. The speed controller can either limit the current through the motor to an acceptable level, or it can start the motor up more slowly. In both cases limiting the amount of torque through the transmission. Also proper driving of the motor ensures that current is continuous and hence no arcing will occur. Finally, implementing velocity feedback control allows the scooter to run at constant velocity.

I didn't want to add any sensors to read the motor velocity, so I had to do some reading on sensorless motor velocity feedback control. The main idea is that when the motor is turning without current flowing, the motor acts as a generator producing a voltage proportional to the velocity. The only downside is that in order to measure the velocity, we have to cut power to the motor and wait some time for the magnetic energy in the motor to dissipate. The time it takes for the energy to dissipate is also strongly dependent upon the velocity of the motor (which could be used as a secondary velocity measurement as well).

After some bread boarding of the technique I designed and etched a PCB to put everything on. To keep things simple I implemented the drive using a single N-channel MOSFET, while the reverse function is achieved through a DPDT relay. I went with a silicon diode for the freewheel diode instead of a Schottky one. This is a trade-off between efficiency and the time the motor takes to demagnetize. A Schottky diode would be more efficient, but it would take some time longer for the magnetic energy in the motor to dissipate than with a silicon diode. Also, I had silicon diodes capable of handling the current already lying around. The layout of the motor controller is shown in the figure below, while the schematic is available here.

Layout of the motor controller, view from the top side. Nothing special. Mixed through-hole and surface mount components. Footprint of the relay coil drive transistor is inverted... So don't use this layout directly. I had to bodge the part upside down, as I was too lazy to re-do the board.
These new features also needed new interfaces. As the electronics will be running even if the pedal is not pressed, a power switch needed to be installed. Although the electronics could be designed to be very very low power, just the concept of an ignition key is cool which my oldest son found very exciting.

My oldest son showing the position where he wants the ignition lock to be mounted.

The ignition lock in position.
As the scooter will have a new reverse feature, a switch is needed to choose the direction. The switch also includes an indicator light to show when the ignition is turned on.

Direction switch mounted. My son in the background supervising my work.
What was also lacking previously was any kind of fuse. This would not really be a problem if the only components in the system are a lead-acid battery and a motor, but with the buck converter and a lithium-ion battery there was a non-zero probability of an electrical fire. In fact, the lithium battery was never really meant to be anything else than a quick hack to get it going, but I never got into replacing it with something better suited. For this upgrade, however, I got a sealed lead-acid battery and added a 5A circuit breaker. 5A should be enough for normal operation, but also low enough to protect the battery and the wiring.

Connecting power wires. The black block at the back is the 5A circuit breaker. The reset button of the circuit breaker is accessible through the underside of the scooter.

A better view of the inside compartment, showing the speed controller board. The motor is just dangling from the wires for testing. The off-white part in the compartment is the gearbox to which the motor connects.

Flashing the software. The speed controller is seen dangling from the wires. The scooter is too large to comfortably fit in my hobby room, so all of this was done in the living room and on the dinner table.
Taking it for a test spin. Works great!
The biggest requests by my son still has are to get flashing lights and a police siren. So those will be up next. He also wants a speedometer, which I think I'll do some time later using a 128x64 graphics LCD module I've had waiting to be purposed for something.

Tuesday, March 8, 2016

Changing the color wheel on my DLP projector

One evening, just as we were about to turn off the projector, it made a horrible glass breaking sound and the picture went black and white. My first reaction was, that the lamp exploded, but realized a second later that the picture was still there. Only the colors were gone. Obviously it was the color wheel that had disintegrated. The reason for it failing is unclear, as the projector is mounted on a solid concrete wall isolating it from most vibrations.

I contacted the manufacturer to obtain a replacement part, as it is not sold as a standard replacement part. Their Finnish representative replied that they only sold the part together with servicing. They also said that it would cost 60e to do an estimate of the cost of repair. Ugh. I didn't want a service, I wanted the part. I would have happily paid 100 euros or more for the part. No wonder the Finnish economy is in crisis. I would have wanted to buy, but no-one wanted to sell.

So, since the official source didn't want to sell the part to me, I had to look at alternatives. Turns out there are very helpful eBay stores, which sell all sorts of parts for projectors. I found the correct part for about 30 euros and decided to pay some more for expedited shipping through DHL. So for about 70e all together, I got the part shipped to me.

I had checked online how the repair was done before ordering the part. The whole process is very trivial. The whole assembly is removed and the motor removed from the assembly. The new motor with the new color wheel is then put in and the assembly reattached.

The color wheel assembly. I had already removed the old motor and the glass shards from the old color wheel when I took this photo.

Second view of the color wheel assembly. I had already removed the old motor and the glass shards from the old color wheel when I took this photo.

The old motor. No pieces of the color wheel are left. It got completely destroyed.

New motor with the new color wheel attached.

New color wheel fitted in the color wheel assembly.

Sunday, February 21, 2016

Bluetooth adapter for UNI-T UT61E multimeter

This is a useful little project I did already quite some time ago. Since it may be of interest to some people I want to write something about it.

My UNI-T UT61E multimeter has a data out port, which can be used for data logging on a PC. The meter comes with a data cable to connect it to a RS232 port. This has two problems. RS232 ports on computers are quite difficult to come by these days, and even if you have an RS232 port, you have to have a cable connecting the meter to the PC. UNI-T sells a USB cable to get around the first problem, but you still are limited by the cable length.

For my own solution I wanted to go wireless using Bluetooth. I had a spare Bluetooth serial port module laying around, which was suitable for the job. First thing to do was to check how to interface the UT61E. I found the schematic of the RS232 cable at http://blog.avrnoob.com/2014/03/uni-t-ut61e-rs232-serial-interface.html. I've recreated the schematic here. The author of that other blog modified the RS232 cable to interface it with a USB low level serial adapter. I however wanted to use the cable unmodified.

Schematic of the UT61E RS232 adapter.
The data transfer from the UT61E is optoisolated using an IR led in the UT61E and a phototransistor in the adapter. The circuit in the adapter works as follows. If there is no light transmitted from the multimeter, D1 will not sink current. Q2 will thus be in cut-off and its collector will be pulled to -12V. No current thus flows on the base of Q1 and hence R3 pulls RxD to -12V. However, if light lands on D1, it will sink current through the base of Q2. Thus Q2 turns on and the voltage on its collector rises to near +12V. Q1 then acts as an emitter follower pulling RxD near +12V. On RS232 the logic levels are such that negative voltage is a 1 and positive voltage is a 0. Thus, when the UT61E wants to transmit a 1 it turns the IR off and when it wants to transmit a 0 it turns the IR on.

The bitrate at which the multimeter operates is rather slow at 19200 bps (actually 19230 bps to be exact). This allows a lower voltage than 12V to be used and still have the RxD swing quickly enough. In fact, connecting the -12V line (RTS) to GND and the +12V line (DTR) to 5V still produces good output.

Even if running at 5V, as described above, the RxD line still can't be directly fed into the Bluetooth module. Firstly, the module uses 3.3V logic and is not 5V tolerant. Secondly, the polarity is inverted to what the module is expecting. However, both of these problems can be solved using a simple level shifting inverter as shown in the schematic below.

Simple adapter to connect the UT61E serial cable to a Bluetooth module.




I had already made a carrier board for the Bluetooth module I used. These can now be bought online for cheap, and I wouldn't bother to roll my own anymore. I've omitted any details related to that carrier board. The main point is that the Bluetooth module is still removable so that it can be configured using a USB low level serial adapter.


Bluetooth UT61E interface. Top side.
Bluetooth UT61E interface. Bottom side.
The UT61E RS232 cable connects to the DE9 connector and power can be applied for instance from a 9V battery. I've used this about 10 meters away from the computer and have still read measurements without problems.

As a final note, the Bluetooth module I used didn't support the 7-O-1 framing that the UT61E uses. Luckily this frame is compatible with the more conventional 8-N-1 framing with the parity bit getting decoded as the last data bit. This extra bit can then be handled in software. The software I'm using to record data is a modified version of Steffen Vogel's dmmut61e. You can download my modified version here.

Saturday, February 13, 2016

Sous-vide cooking controller

I've been experimenting with sous-vide cooking recently. The main appeal for me is to be able to buy meats when they are on sale and put them in the freezer. Then later thaw and cook them in the sous-vide machine with very little effort. To keep things simple, I wanted to use a rice cooker as the heater and water container. With this setup I only needed to build a simple temperature controlling device to get started.


The board, which I repurposed as the temperature controller. It was originally built for driving an electrodynamic shaker.

Bottom side of the controller board.

For the temperature controller, I happened to have an old board laying around, which I originally built to drive an electrodynamic shaker. The board has an ATmega48 microcontroller, with a number of GPIO pins brought out to headers as well as an open drain output capable of driving inductive loads, such as a relay coil, so it was well suited for the task.


Relay box for controlling the rice cooker.

The relay box with its cover removed. Everything is submerged in hot glue. The relay disconnects both terminals. The clearance between the low-voltage and high voltage is about an inch. I'm very confident that this is completely safe.
The temperature sensor I chose to use was a waterproofed DS18B20 sensor from eBay, which I also had laying around. While for the power switching I built a relay box out of an old in-socket power switch. The relay coil connections are brought out to the controller board, while all the mains voltage connections are contained within the relay box case.

I implemented a simple bang-bang temperature controller which turned the heating on whenever the temperature was below 60 Celsius and turned off the heating whenever the temperature was above 60.5 Celsius. In the first test I had a small computer fan submerged to act as a circulation pump. I was expecting it to work underwater for a long time, but it turns out that 5V is still high enough to cause the wires to corrode and break in a matter of hours through an electrochemical reaction. However, I noticed that there was no real need for water circulation, as in the end the surface water temperature matched the bottom temperature within 1 Celsius. Circulation might speed up the cooking time a bit, but I'll investigate that at some later point in time.

The first roast beef I made with this setup turned out very good. I used the original vacuum plastic bag which the meat came in and this worked well. Setting everything up, however, was a convoluted operation. Changing the cooking temperature for instance required reprogramming the microcontroller.

Wiring in the connections for the LCD and encoder. More wiring is on the other side of the protoboard.

Controller board in place. Showing also the back side piece of the case.

Testing the LCD interface. The display shows 1 temperature sensor found on the 1-wire bus, which is reading 492 counts = 30.75 Celsius.
To make the device useful, I added an HD44780 LCD, for which there was just barely enough GPIO. I had to move the temperature sensor to share a pin with the ISP interface to make room for the LCD. For the user input I had planned on using an encoder with an integrated push button. This would however require 3 additional GPIO lines, which I did not have available. As a compromise, I had to share GPIO between the LCD and encoder. The sharing is done simply by having the switches in the encoder pull down the LCD data lines through 1k resistors. These resistors are small enough to pull low against the internal pull-up resistors on the GPIO when the port acts as an input, but large enough to not interfere with port operations when the port is acting as an output. As writing to the LCD only takes a very short time, this port sharing doesn't cause any real concurrency issues (that is, just an occasional encoder pulse goes undetected every now and then).

The controller keeping water in the rice cooker at 60 Celsius. "T:60.0" indicates the set temperature. "=60.3" indicates the measured temperature. "o" indicates that the relay is off (it shows "i" when relay is on). Manual override is not enabled, as there is no "m" next to the "o". "85%" indicates the currently observed duty cycle. The 8 last characters form a graph of the duty cycle over the last 8 hours.

The user interface I came up with is very simple. The display shows the set temperature, the current temperature (or a possible error condition), duty cycle of the control as well as the relay state. The observed duty cycle is also displayed on an ~8 hour graph. Turning the encoder changes the set temperature in an intuitive way. Pushing the encoder button for the first time activates manual override mode with relay set to off. Pushing it a second time continues in manual override mode with the relay set to on. A third push exits manual override mode and the relay is again under temperature control. There is also an indication on the LCD when manual override mode is chosen.

Now I'll just have to wait for bargains on meats to fill the freezer. Yum.

One last picture.

Tuesday, February 2, 2016

Checking the calibration of a frequency counter

In the previous post I went through how I repaired a Racal-Dana 1992 frequency counter I had obtained from the dumpster. After the repair the instrument seemed to function correctly, but I wasn't sure if it still were anywhere close to calibrated. Given that I don't have an atomic frequency standard, and I'm not planning on buying one, the options I was left with were to either borrow an atomic standard or to use some other frequency source to check the calibration on the 1992.

I've been interested about synchronizing clocks using GPS signals and have been wondering if the cheap GPS receivers (Fastrax uPatch100) I have are any good in this respect. Their data sheet lists their PPS (1 pulse per second) output accuracy as 50 ns RMS, which is 50 ppb (that is 50*10^-9 relative error). The aging rate of the oscillator in the 1992 is specified at 3 ppb/day. The accuracy of the PPS output would thus seem to be adequate for determining whether calibration is required.

Fastrax uPatch100 GPS receiver with a DC/DC converter to power it from a lithium battery. The coax carries the PPS signal.
The GPS receiver had to be placed outside to get a signal. The coax goes back inside and connects to the frequency counter.
An interesting feature of the 1992 is what is called (R-X)/Z mode. In this mode the unit subtracts some programmable constant X from the measurement and divides the result by Z. Programming X=1 and Z=1 allows to easily check the deviation from 1 PPS. At first this deviation was reading around 3 microseconds, which was due to the lowish accuracy of operating only from the crystal oscillator in the GPS receiver. Once the receiver got a position fix, the deviation dropped down to between 10 and 100 nanoseconds, which is about what could be expected with the 50 ns error specification of the GPS receiver. However, I'm somewhat confident that the error in the PPS output of the GPS receiver should have zero mean value. As I'm almost exclusively reading positive values, it suggests the 1992 is running a tiny bit too fast.
Racal-Dana 1992 showing the period error. Here the PPS output is measured as being 23 nanoseconds longer than a second (or what the 1992 considers to be a second).
In conclusion, the unit seems to have an accuracy of around 100 ppb. That is very good considering the aging specification of the oscillator as it would still be within spec even if it were calibrated just a couple of months ago. Though this in fact hints that the oscillator may be much more stable than what is specified. I might investigate this more later.

Thursday, January 28, 2016

Racal-Dana 1992 repair

Racal-Dana 1992 in my lab on top of an old signal generator.

I recently got an old Racal-Dana 1992 frequency counter from the dumpster. The unit looked very good and did power up and in fact did measure frequencies. However, the user interface was completely non-responsive. It was stuck in Freq A mode. After googling around, I found out that a typical failure mode of these instruments is that the push buttons themselves die. The rubber springs have hardened and deformed after all these years (the quality control stickers and IC date codes seem to indicate early 1989). I looked through Mouser, but these switches or anything that would directly accept the switch hat are no longer made.

Front panel removed.
Front panel PCB with the broken switches. The hats are held on the switches just by friction.

Inspired by a post in the EEVblog forums about replacing the buttons, I ordered a bunch of 6x6 mm tact switches to mount diagonally with two of the legs cut off. The original poster used tact switches with a long shaft, which were then shaped to accept the hat. I wanted to go a different route, as I considered shaping the shafts too tedious. I decided to have the hats mounted on the original plastic pieces of the old switches and then have these pieces attached to the tact switches. For this I needed to drill a 3.5mm hole in the bottom of each hat holder piece, to fit the shaft of the tact switch, and then fix the piece to the tact switch shaft with a drop of super glue.

6x6 mm tact switch with two of the legs cut off. This fits perfectly in place of the original switches.
Halfway there. I forgot to take pictures of the desoldering process.

There are 33 switches, so the process of desoldering the old ones and replacing them with the new ones took one whole evening. After this I could finally test the instrument, and find that this repair had indeed fixed the problem. A quick look into the operation of the instrument shows that repairing this unit seems to be well worth the time and effort I've put into it. The drilling of the hat holders and gluing them on the tact switches then took one more evening.

All switches replaced and board cleaned from flux residue.
Testing the instrument with the newly replaced switches. Everything's good!
Front panel PCB back in the front panel casing. Switches seem to line up. Next up is gluing the hat holders on the tact switches.
Hats in place and glue curing.
Front panel in place and everything working correctly. Win.

Overall, I'm very happy with how everything worked out. It is a beautiful instrument with very interesting features. Next up is to check the calibration somehow. Then perhaps I can finally think of getting rid of my old oscilloscope, as I wouldn't need it even for its frequency counter any longer.