Embedded systems and hardware engineer building the tools that sit between the shack and the sky.
| DAY | NIGHT | |
|---|---|---|
| 80m-40m | -- | -- |
| 30m-20m | -- | -- |
| 17m-15m | -- | -- |
| 12m-10m | -- | -- |
| 14.100 | -- | -- |
| 18.110 | -- | -- |
| 21.150 | -- | -- |
| 24.930 | -- | -- |
| 28.200 | -- | -- |
The beacon panel is a browser-only addition, computed straight from the public NCDXF schedule (18 beacons × 5 bands) — not yet ported to the physical clock's display.
Builds that connect firmware, RF, and the operating desk.
Restoration of a 1969–74 Tektronix 564B split-screen storage oscilloscope, with a 3A6 dual-trace amplifier and a 3B3 delayed-sweep time base. The first power-up showed a working CRT, sweep and triggering, but a dead calibrator, low vertical gain on both channels and a broken CAL OUT connector. With no calibrator to trust, the time base was calibrated against 50 Hz mains hum. The 50-year-old electrolytics are next: a full mainframe recap, with the old caps left in place but disconnected.
Restoration and modernisation of an Atlas 210X HF SSB transceiver from the 1970s: the original VFO and carrier oscillator are replaced by an Si5351 driven by an Arduino Nano, with a digital S-meter read off the radio's own meter bridge, a second Nano controlling a SOTABEAMS VariBeam audio DSP filter, and a new front plate. The receiver got a proper service too: a dirty DC switching relay cleaned, old tantalum capacitors replaced, and the AGC and S-meter trimmers swapped for multi-turn pots.
A day/night world clock for a 1024×600 RGB panel (Waveshare ESP32-S3-Touch-LCD-7B), built for ham radio operators: a live terminator over a real map, an NCDXF/IARU beacon panel with live map markers, an HF band-conditions panel from hamqsl.com, and a five-city clock bar with sunrise/sunset. Runs natively on ESP-IDF — Arduino's scheduling overhead was eating into the RGB panel's scan-out timing margin badly enough to cause visible display jitter that no pixel-clock tuning could fully resolve; removing that overhead fixed it outright.
A remote operating console for a FlexRadio FLEX-3000 alongside PowerSDR. The FLEX-3000 needs a real, physically-attached FireWire bus, so PowerSDR itself can't run remotely — but the operating position can: instead of streaming PowerSDR's window as video (laggy, breaks audio drivers), this streams the underlying FFT bins, meter readings, CAT state, and audio, then renders a native UI on a lightweight client anywhere on the network. The client now has a full operating screen: VFO A/B, S, AVG, PWR and TEMP meters, panadapter and waterfall, band, mode, filter and DSP controls, RX processing, an EQ and a contact log.
A closed-loop antenna rotator controller built from several ESP32 boards. Two ESP32-C5 sensor nodes (one compass-only, one compass + tilt for azimuth/elevation) report orientation over ESP-NOW to an ESP32-S3 touchscreen hub, which drives the rotor relays over RS485/Modbus and runs the on-screen control UI with presets, a compass dial, an Emergency Stop and PSU status. Since the first hardware bring-up it has gained magnetometer calibration, over-the-air updates, and a small ESP32-C3 bridge that reads the G-450C rotor's own position pot, so the hub shows a true rotor angle with the compass as a watchdog.
An interactive HF propagation visualizer: rays leave the antenna, hit a virtual-height ionosphere layer, and bend back to Earth only if the operating frequency is below that layer's MUF at the ray's takeoff angle (secant law). Models D/E/F1/F2 plus patchy, time-flickering Sporadic-E openings, night-mode layer behavior, multi-hop chains, and a curved-Earth globe view alongside a to-scale flat view.
More builds and activity logged on qrz.com/db/YT3CT.
A day/night world clock for the Waveshare ESP32-S3-Touch-LCD-7B (1024×600 RGB panel), built for ham radio operators — the whole thing started with thinking about what to build as a gift for a good friend. Runs natively on ESP-IDF rather than Arduino — the framework's scheduling overhead was eating into the RGB panel's scan-out timing margin badly enough to cause visible display jitter that no pixel-clock tuning could fully resolve. Removing that overhead fixed it outright.
A full-screen day/night terminator over a real map, redrawn once a minute using the NOAA solar-position algorithm (declination plus the equation of time, no ephemeris data needed) — the same math driving every city's sunrise/sunset in the five-city clock bar below it. Local and UTC time sit in the top bar, synced via NTP, alongside a WiFi status indicator.
Shows which beacon is transmitting on each of the 5 HF beacon frequencies right now, computed purely from the clock's own accurate time — no network needed, since the schedule itself is fixed and public. Map markers highlight each of the 18 beacon locations, brightening whichever ones are currently active. Timing was verified against an existing open-source ham radio clock project's own implementation of the same schedule, not trusted from memory alone.
An HF band-conditions panel — solar flux index, sunspot number, A/K index, and day/night propagation quality per band — fetched hourly from hamqsl.com.
Temperature/humidity comes from a DHT11, read via the RMT peripheral rather than CPU bit-banging: RMT timestamps the sensor's edge transitions in hardware, independent of CPU scheduling, so nothing needs interrupts disabled and WiFi traffic can't corrupt the read. A CPU-polling implementation was tried first and proved unreliable under real WiFi load.
Ported from Waveshare's own ESP-IDF LVGL demo for this board — hardware bring-up (I2C bus, IO-expander, RGB panel init, SD card) is their example code, reused as-is. Beacon schedule timing verified against SmittyHalibut/HamClock's own implementation of the same NCDXF schedule.
This project is not affiliated with, endorsed by, or associated with Geochron, Geochronmap, or HamClock — it's an independent build inspired by the general concept those projects/products popularized (a world map with a live day/night terminator for ham radio use). Any resemblance in naming has been intentionally avoided; Geochron and Geochronmap in particular are trademarks of their respective owners.
View on GitHub
The 564B is a split-screen bistable storage oscilloscope mainframe, solid-state apart from the CRT, made between 1969 and 1974. It has two independently controlled 4 × 10 cm storage screens, and stored traces last up to an hour, so it can capture one-off events without a digital scope. This one carries a Type 3A6 dual-trace vertical amplifier (10 MHz, 1 MΩ ‖ 47 pF, 10 mV to 10 V/div, Nuvistor input stages) and a Type 3B3 delayed-sweep time base.
With no working calibrator, all testing used mains-hum pickup and a 1.576 V AA cell measured with a multimeter. The CRT lights, and intensity, focus and position all respond; sweep and triggering work (LINE source), and the vertical amplifier passes signal on both channels. The sweep was 5–7 % slow on every range, so the front-panel SWEEP CAL was adjusted against 50 Hz hum: 5 cycles across 10 divisions at 10 ms/div. Afterwards it was exact at 10 ms/div and within 1–3 % at 2 and 5 ms/div, which is inside the original spec.
The repair, step by step
The CAL OUT connector was broken internally. The old centre pin, with its broken contact points, was removed and replaced with a pin taken from a donor connector, and the connector is no longer broken. The calibrator output itself is also dead, even measured on the wire behind the BNC, so it needs tracing separately: the +125 V rail first, then the Q151/Q159 multivibrator, Q162 and the output divider.
Both channels of the 3A6 read several times too low. The input connectors, R101 (11.7 Ω against a 10 Ω spec), the AC/DC/GND slide switch (0.1–0.3 Ω) and the input path to the Nuvistor grid (about 1 MΩ, as expected) were all ruled out. Swapping the Nuvistors between channels didn't move the fault, so the tubes are good. Because both channels are affected, the suspects are the shared output stage or the mainframe supply rails.
The electrolytics are over 50 years old and the symptoms point to the supply rails, so the mainframe gets a full recap. Replacement values come from the 564B Electrical Parts List, and the old caps are left in place for looks but disconnected. That is 12 capacitors on the power supply board (the −100 V, −12.2 V, +125 V and +300 V rails) and 8 on the storage board (erase timing and sawtooth, target amplifier and bootstrap). There are no electrolytics in the calibrator or the CRT/HV circuit, and the 3B3's precision film timing caps are left alone. The 3A6 and 3B3 plug-in electrolytics are a later job. Also ordered: an insulated panel BNC for CAL OUT, contact cleaner and degreaser for switches and pots, vaseline oil for shafts and detents, and heatshrink.
More photos
First measure and record all four rails before touching anything (specs: −100 V ±0.5 %, −12.2 V ±1.2 %, +125 V ±1.5 %, +300 V ±1.5 %). Photograph and label every pin connector before lifting the power supply board, since the wires are colour-coded by voltage. Clean the sticky dust with a dry brush and air, then IPA or contact degreaser, using damp soapy swabs only away from trimmers, switches and sockets. Then check R33, R75, R94 and Q30/Q38/Q70/Q91, fit the new caps, and power up slowly, setting −100 V first (R23) before checking the other rails. Switch and pot cleaning, the knobs and plug-in recalibration come after that.
564B manual 070-0804-00
3A6 manual 070-419
TekWiki: 564B
Next update: rail voltages before and after the recap.
A restoration and modernisation of an Atlas 210X, a 1970s HF SSB transceiver. The original VFO and carrier oscillator are replaced by an Si5351 controlled by an Arduino Nano, with a 16×2 LCD, encoder tuning, band switch reading and a calibrated digital S-meter. A second Nano controls a SOTABEAMS VariBeam audio DSP filter with its own OLED, and a new 3D-printed front plate is designed to hold both displays, a CNC-style tuning knob and extra buttons.
Si5351 CLK0 is the local oscillator (RF ± IF) and CLK1 the BFO / carrier oscillator, around the radio's 5.520 MHz crystal filter. The Si5351's crystal runs about 101 ppm high, so a +101000 ppb correction is stored, and the result was checked against an FTdx10 and a tinySA to within ±10 Hz with the opposite sideband suppressed. An I²C timeout means an RF glitch on SDA/SCL can no longer freeze the VFO — the chip is simply reprogrammed and a ! shows on the LCD. The last frequency is kept per band and saved to EEPROM, RIT is removed on TX, and holding the encoder button at power-on opens a setup menu for BFO and correction.
The S-meter is read differentially from the Atlas S-meter bridge (PC-100 pins 15/16 into A1/A0 through 10 k and 100 nF, with 1 k across the bridge in place of the removed meter) and calibrated against a tinySA from S6 to S9+40. The LCD shows nine fields, S1 to S9, two lines per field (3 dB each), then +10 to +40 as text.
A second Nano drives a SOTABEAMS VariBeam audio DSP filter, based on KG4RUL's VariBeam local display sketch (MIT licence). Fixes include holding each emulated encoder state for 2 ms because the VariBeam missed steps, counting detents properly, and removing an OLED reset pin that clashed with the encoder switch. It resyncs at power-on, saves settings in EEPROM, draws the passband edges as a trapezoid graph, and a single button cycles CF/BW, presets (SSB, SSB NARROW, CW, DIGI) and the screen mode — the OLED makes RF hash even when idle, so it can be dimmed or switched off.
The dirty DC switching relay in PC-100 was cleaned, which gave a big gain improvement. Old dipped tantalums on PC-200 and PC-300 were replaced, the AGC threshold pot (R309, PC-300D) became a 5 k multi-turn and the S-meter zero (R222, PC-200) a 1 k multi-turn. AGC now idles at 4.53 V and reaches 5.25 V at −73 dBm on PC-200 pin 19 (factory: 4.53 → 5.16 V), and the receiver hears down to −115 dBm. A loose 20 m image filter coil form was also found turning with its slug.
The 3D-printed plate measures 239 × 88 × 9 mm and was corrected from the original design: a recess and through hole for the 60 mm MBL600 encoder with three mounting holes on a 50.8 mm circle, pockets and windows for two 0.96" SSD1306 OLEDs, and a 65 × 15 mm window for the 16×2 LCD.
The VariBeam control sketch builds on KG4RUL's local display sketch (MIT licence, header kept). The Atlas 210X/215X manual, schematics and Engineering Supplement (ZL1UJG / W7KEC) were used heavily; they are copyrighted and not reproduced here.
View on GitHub
A remote operating console for a FlexRadio FLEX-3000, built as a companion to PowerSDR. FireWire and PowerSDR stay on the radio PC; a lightweight client anywhere on the network gets a live waterfall/spectrum, VFO/mode/filter controls, audio, and PTT — without full screen/remote-desktop sharing.
The FLEX-3000 requires a real, physically-attached IEEE-1394 FireWire bus, so PowerSDR itself can never run "remotely." What can be remote is the operating position: instead of streaming PowerSDR's whole window as video (RDP/VNC — laggy, breaks audio drivers), this project streams the underlying data — FFT bins, meter readings, CAT state, audio — and renders a native UI on the client. Data frames are kilobytes; video frames are megabytes.
A server on the radio PC taps the FFT/meter data, captures RX/TX audio, and relays CAT commands and PTT. A client on the operator PC renders the waterfall from that FFT stream, exposes VFO/mode/filter controls, and handles audio in/out and PTT. Two links, split by need: TCP carries control/CAT (needs to be reliable), UDP carries the FFT stream and audio (needs to be low-latency).
The client is no longer a skeleton: it has a full operating screen with a link-status panel, meters, a panadapter and waterfall, tuning, RIT/XIT, levels, DSP, RX processing, an EQ, VOX and PTT, RX audio controls, and a contact log with F1–F4 buttons. The top row also carries buttons for host and board setup, PC and radio power, starting PowerSDR, a keyboard PTT, a frequency overlay, CW and messages. The newest design adds a MAIN/SUB focus switch and a Sub RX panel (enable, track, RF and AF gain, volume, pan). On the PowerSDR side, the repository is a source fork of PowerSDR with a minimal TCP CAT bridge: stock PowerSDR 2.7.2 only has serial CAT, so the bridge listens on TCP and implements the commands the FlexRemote server sends, and known-working release binaries are backed up in the repository.
The protocol comes first (everything else depends on it being stable), then the server's FFT source — the one piece that needs real PowerSDR source to finish, though it can be built and tested against an included simulated FFT source until then. The client can be built and tested entirely against that same simulated server, no radio required.
The PowerSDR side builds on the FlexRadio PowerSDR source code, which is GPL-licensed; the fork stays under the same licence.
A closed-loop antenna rotator controller across several ESP32 boards, built with ESP-IDF. Two ESP32-C5 sensor nodes read orientation and report it over ESP-NOW to an ESP32-S3 touchscreen hub: one node reports azimuth only (GY-271 compass), the other azimuth and elevation (GY-271 plus an MPU6050 for a tilt-compensated heading). The hub drives the rotor through a Modbus relay board, reads front-panel buttons and encoders, and runs the LVGL control UI.
August 2026. The first hardware bring-up verified encoders, the Emergency Stop, the Rotor 2 azimuth/elevation workflow, stop-aware azimuth control, a tap-to-set-target keypad, preset positions with a mechanical stop, PSU status chips backed by an ADS1115, and the network menu.
Calibration and updates. The hub now drives a magnetometer calibration sweep and stores hard/soft-iron offsets and scale on each node, with the measured magnetic declination (+5.72°) built in. Firmware can be updated over WiFi (dual OTA partitions with rollback), so the hub doesn't need its enclosure reopened.
October 2026: a feedback bridge. A small ESP32-C3 with an ADS1115 reads the G-450C's own position pot across its 0–450° travel and reports it over ESP-NOW. The hub shows that pot angle as the primary reading and keeps the compass as a watchdog and fallback, with MAG ONLY and SENSORS DISAGREE warnings. It starts from a built-in 30-degree table and switches to points recorded from the hub's POT CAL screen (up to 64).
Power-on interlock. A separate Arduino sketch controls power to the hub: holding button 1 for 1–3 s switches the master relay on, holding it past 3 s switches it off, and the other relays only respond while the master relay is on.
More photos
Same approach as AmateurRadioClock: the hub's display bring-up (RGB LCD timing, the CH422G IO-expander, GT911 touch, backlight) is fiddly board-specific init code that's easy to get subtly wrong from a written description, so it starts from Waveshare's own ESP-IDF demo for this exact panel, confirmed working unmodified, before this project's files are merged into it.
The hub flashes first and prints its MAC address over serial; that address gets copied into both sensor nodes so they know where to send ESP-NOW telemetry. All three devices share one hardcoded WiFi channel for ESP-NOW, which has to match across all of them if it's ever changed.
Activity logged over 30+ years on QRZ.com — pulled straight from the public profile.
Under Construction — this section is being reworked.
Notes on how signals actually get from this station to the next continent — the working knowledge behind the projects above.
Upcoming HF contests worth planning the operating schedule around.
| DATE | CONTEST | MODE | BANDS |
|---|---|---|---|
| 24–25 Oct 2026 | CQ WW DX Contest (SSB) | SSB | 160–10m |
| 7–9 Nov 2026 | ARRL Sweepstakes (CW) | CW | 160–10m |
| 21–23 Nov 2026 | ARRL Sweepstakes (SSB) | SSB | 160–10m |
| 28–29 Nov 2026 | CQ WW DX Contest (CW) | CW | 160–10m |
| 12–13 Dec 2026 | ARRL 10 Meter Contest | CW/SSB | 10m |
| 31 Jan–1 Feb 2027 | CQ WW 160m Contest (CW) | CW | 160m |
| 27–28 Mar 2027 | CQ WPX Contest (SSB) | SSB | 160–10m |
Sample layout for now — dates and entries above are illustrative, not live. If this looks right, the plan is to pull the real schedule from the public WA7BNM contest calendar once a year (contest dates rarely change), rather than building a whole live-fetching pipeline for something that barely moves.