WSPRing on higher bands

Our WSPR beacon design works fine even on the 4m band (~70 MHz) . The key is to use a 25 MHz high-quality TCXO, like the 25 MHz HCI 0.5ppm TCXO! Results Challenges 2m WSPR is still out of reach for now - see the following sporadic decodes. Of course, the next challenge is to get 2m WSPR beacons working 100% reliably at a low cost. ...

August 30, 2025 · 1 min · 88 words · Dhiru Kholia

Notes on coupled inductors

The usage of ready-made coupled inductors in RF designs was pioneered by Jim Veatch in his award-winning RF amplifier designs. Applications For Baby-QRO applications, we can use Wurth 744851330 coupled inductor. For 5W / 10W RF amplifier applications, we can use Bourns SRF1260A-4R7Y coupled inductor. Recently we were able to utilize very cost-effective YJYCOIN YPRH1207C-4R7M Chinese coupled inductor with excellent results. With our current Digital Amplifier designs, this Chinese coupled inductor works even at ~75 MHz. ...

August 17, 2025 · 1 min · 86 words · Dhiru Kholia

Initial success with cost-effective 6m WSPR + 2m FT8 beacons

Our 6m WSPR beacon design works fine now. The key is to use a 25 MHz high-quality TCXO, like the 25 MHz HCI 0.5ppm TCXO! 2m WSPR is still out of reach for this VFO design - see the following drifty screenshots: While WSPR is no good, 2m FT8 works pretty fine! ...

August 16, 2025 · 1 min · 72 words · Dhiru Kholia

Checking Zoom latency externally

Here is a handy script that I often use to check the quality of the Zoom connection. It measures TCP latency instead of the usual ICMP stuff (which is often blocked). #!/usr/bin/env python3 """ TCP Ping Test (defaults to port 80, 10000 packets) Usage: ./tcpping.py host [port] [maxCount] - Ctrl-C Exits with Results """ """ pip3 install matplotlib numpy python3 ./tcp_ping_grapher.py 115.114.56.202 443 100 python3 ./tcp_ping_grapher.py teams.microsoft.com 443 100 """ import sys import socket import time import signal from timeit import default_timer as timer # https://matplotlib.org/examples/animation/animate_decay.html import numpy as np import matplotlib.pyplot as plt import matplotlib.animation as animation host = None port = 80 # Default to 10000 connections max maxCount = 10000 ## Inputs # Required Host try: host = sys.argv[1] # host = "115.114.56.202" except IndexError: print("Usage: tcpping.py host [port] [maxCount]") sys.exit(1) # Optional Port try: port = int(sys.argv[2]) # port = 443 except ValueError: print("Error: Port Must be Integer:", sys.argv[2]) sys.exit(1) except IndexError: pass # Optional maxCount try: maxCount = int(sys.argv[3]) except ValueError: print("Error: Max Count Value Must be Integer", sys.argv[3]) sys.exit(1) except IndexError: pass # Pass/Fail counters passed = 0 failed = 0 def getResults(): """ Summarize Results """ lRate = 0 if failed != 0: lRate = failed / (count) * 100 lRate = "%.2f" % lRate print("\nTCP Ping Results: Connections (Total/Pass/Fail): [{:}/{:}/{:}] (Failed: {:}%)".format((count), passed, failed, str(lRate))) def signal_handler(signal, frame): """ Catch Ctrl-C and Exit """ getResults() sys.exit(0) # Register SIGINT Handler signal.signal(signal.SIGINT, signal_handler) def work(t=0): passed = 0 failed = 0 count = 0 maxCount = 3200 # Loop while less than max count or until Ctrl-C caught while count < maxCount: # Increment Counter count += 1 success = False # New Socket s = socket.socket( socket.AF_INET, socket.SOCK_STREAM) # 1sec Timeout s.settimeout(1) # Start a timer s_start = timer() # Try to Connect try: s.connect((host, int(port))) s.shutdown(socket.SHUT_RD) success = True # Connection Timed Out except socket.timeout: print("Connection timed out!") failed += 1 except OSError as e: print("OS Error:", e) failed += 1 # Stop Timer s_stop = timer() s_runtime = "%.2f" % (1000 * (s_stop - s_start)) if success: print("Connected to %s[%s]: tcp_seq=%s time=%s ms" % (host, port, (count-1), s_runtime)) passed += 1 # Sleep for 1sec if count < maxCount: # time.sleep(0.5) # time.sleep(1) time.sleep(2) t += 2 yield t, float(s_runtime) # Output Results if maxCount reached # getResults() def data_gen(t=0): cnt = 0 while cnt < 1000: cnt += 1 t += 0.1 yield t, np.sin(2*np.pi*t) * np.exp(-t/10.) def init(): ax.set_ylim(0, 128 * 3) ax.set_xlim(0, 300) del xdata[:] del ydata[:] line.set_data(xdata, ydata) return line, fig, ax = plt.subplots() line, = ax.plot([], [], lw=2) ax.grid() xdata, ydata = [], [] def run(data): # update the data t, y = data xdata.append(t) ydata.append(y) xmin, xmax = ax.get_xlim() if t >= xmax: ax.set_xlim(xmin, 2*xmax) ax.figure.canvas.draw() line.set_data(xdata, ydata) return line, ani = animation.FuncAnimation(fig, run, work, blit=False, interval=10, repeat=False, init_func=init) plt.show() Usage: ...

August 8, 2025 · 3 min · 516 words · Dhiru Kholia

WiFi VFO, beacon and signal generator

We make heavy use of Easy-Digital-Beacons-v1 for testing RF amplifiers. This single board is a versatile WiFi VFO and FT8 / FT4 / WSPR beacon. You can also use our CW-SigGen project to generate a suitable test signal.

July 5, 2025 · 1 min · 38 words · Dhiru Kholia

New RF parts and new promises - part 2

Tokmas CID9N65E3 rocks! Performance It is CRAZY how efficient this GaN FET is in TO-252 (DPAK) package. It generates 5W @ 28 MHz with 13.8V at drain without even warming up! Close to 4W @ 50 MHz with 12.0V at drain. 5W+ @ 50 MHz with 13.8V at drain. 11W+ @ 50 MHz with 20V at drain. It even produces ~3W at 70 MHz with 13V at drain - w00t! ...

June 15, 2025 · 1 min · 208 words · Dhiru Kholia

The poor quality, reliability and longevity of MOONDROP products

I had bought two pairs of MOONDROP Aria 2 IEMs after auditioning them at a Headphone Connect event. After a few months of usage, one of the Aria 2 earphones lost audio in the left earpiece. We got it 'serviced' under warranty from Headphone Zone. After a year of almost no usage, the other pair of Aria 2 IEMs lost audio in one of the earpieces too! I have never seen this poor quality, reliability and longevity before! ...

June 15, 2025 · 1 min · 127 words · Dhiru Kholia

Fast(est) gate drivers in the West

I recently found some FET gate drivers which are quite fast! The Drivers Wuxi Maxinmicro MX1025D - Favorite! BD2311NVX-LBE2 from ROHM Semiconductor TI LMG1020 Tokmas LMG1020YFFR Usage They are perfect for driving the fast Tokmas GaN FETs that we recently discussed on this site. Our 'workhorse' gate driver for the recent experiments has been the Onsemi's NCP81074ADR2G in a friendly SOIC-8 package. And we have shifted to MX1025D gate driver in our latest amplifier designs. ...

June 3, 2025 · 1 min · 77 words · Dhiru Kholia

Debugging / reversing Firebase gRPC traffic with mitmproxy

Recently, I was stuck in figuring out how the Firebase gRPC calls worked and how I could generate, modify, and replay them. Trapping and modifying the existing gRPC traffic was not working too well. Finally, I took a step back and spent some time on learning how to build and debug simple Firebase applications. This approach helped me tremendously and I was able to make further progress with my original task in almost no time. ...

April 16, 2025 · 3 min · 435 words · Dhiru Kholia

Ideas for a 2m (144 MHz) WSPR / FT8 beacon

I am posting an early design sketch of a 2m WSPR beacon. Key Points 25 MHz HCI 0.5ppm TCXO powering the Si5351 module instead of the 26 MHz TCXO. If this fails, we can use a 10 MHz OCXO instead (a bit out of spec but works fine). Tokmas CID10N65F GaN FET might work @ 144 MHz as the 'final'. If not, use Mitsubishi RD15HVF1-501 MOSFET as backup. 2SK3475 as the driver with variable DC bias at the gate The whole VCC to this amplifier will be PTT switched Ideally, we would want to keep the driver stage linear but the final stage as switched (Class C/D) Alternate: Perhaps by DC coupling the Si5351 input to 2SK3475, we can avoid the need for DC gate bias The "RFC" (bifilar coil still needed?) part will need to be figured out for VHF! Status Results: To be built and tested soon! ...

April 15, 2025 · 1 min · 173 words · Dhiru Kholia