New antennas at the lab
I have recently installed new HF antennas at my lab.
The antenna(s) I have installed is a W-8010 and are designed for use in the 80, 40, 20, 15 and 10m radio amateur bands.
I will be using these for other bands too and since no antennas are prefect for all frequencies they need to be tuned depending on the use case.
Remote tuning
I wanted to be able to tune the antennas remotely (up on the roof before the cable to my lab) so I bought a cheap ATU-100 clone:

This device will automatically attempt to tune the antenna based on readings from a built in SWR meter.
Tuning require transmitting through the device at a couple of watts while activating an input.
An onboard microcontroller switches capacitors and inductors via. relays until the antenna is (hopefully) matched to the transmitter.
The tuning process can be followed on a small attached OLED display.
Tuning with VNA rather then SWR
For several reasons I like to tune my antennas using a Vector Network Analyzer rather than with a transmitter and SVR measurements.
The ATU-100 is not built for this so if I wanted to use the tuner part I needed to change its firmware.
Lot of people has contributed firmware to this device but all that I could find were all basically adding to the existing functionality and none really fit my case.
So I set out to write my own firmware
The schematic or the original and clones are basically identical:
A PIC16F1938 microcontroller drives a bunch of relays and receives two analog signals from the SWR detector. It has a couple of I/O pins for buttons and a I2C OLED display.
I have not touched a PIC16 for several decades and I did not have any programmer or development tools.
Physically programming the ATU-100
After looking at the board pinout and reading up on PIC16 programming I could basically tell that the developer had used High Voltage Programming (HVP) where you raise the MCLR (reset) pin to a relatively high voltage (9V) to enter programming mode:
The original designer (N7DDC) had cleverly broken out all required programming pins needed to flash the firmware.
Building a quick and dirty PIC programmer
Being (sometime) cheap and lazy I found that a reasonable PIC16 programmer could be hacked together using a Arduino UNO.
I used this schematic for the programmer: 
High voltage is generated by abusing a NMA-1212D DC-DC converter. It basically takes 5V and creates a +-5V output used as 10V.
A PNP transistor Q1 (BC557) switches the high voltage to the MCLR pin when needed. R1, D1 and R3 level shift the 5V signals from the Arduino to the 10V transistor.
Resistor R2 operates normal MCLR when Q1 is off.
Arduino pin 11 and 12 handles data to/from the PIC16
Firmware development (take a deep breath)
I found the original firmware for the project and used it as the basis for all the connection and measurement methods.
I then set up a VScode project with the the XC8 compiler.
Microchip’s XC8 compiler is free to download, which is good. The installer is roughly the size of a small operating system, which is less good. You grab it from the MPLAB X tools page, run the installer, go make coffee, and come back to find it has deposited itself into C:/Program Files/Microchip/xc8/v3.10/ along with a folder structure that suggests someone once had strong opinions about organization and then gave up.
The other thing you need is a device family pack — a separate download that gives the compiler the register definitions and memory maps for specific PICs. Microchip calls these DFPs. I put mine in xc8 and pointed the compiler at it with -mdfp. Without that flag you get a wall of “device not found” errors that are not especially informative.
I skipped MPLAB X entirely and drove the compiler directly from the command line. The VS Code build task does it in one shot:
xc8-cc.exe -mcpu=16F1938 -mdfp=[WHERE I KEEP MY STUFF]/xc8 -O2 -o build/ATU100-SerialCtrl.hex main.c relays.c uart.c cmd.c adc.c
…Easy right 😉
Luckily I have pre-compiled everything in case you want to try it (at the bottom of the post)
Rule number one: Check the hardware first
One thing that tripped me up was that nothing worked to begin with. Not even the smallest “Hello world” program. It took a while before I noticed that all pins on the PIC were used for I/O EVEN THE FREAKI’n OSCILLATOR PINS!!
The PIC runs off the internal oscillator and NOTHING works if you do not enable this in your project…. remember that one kids 😉
So what can you do then
The firmware speaks a simple ASCII protocol over serial — 9600 baud, 8N1, newline terminated. Commands are case-insensitive.
| Command | Response | Description |
|---|---|---|
C<0–127> |
C=<val> |
Sets the capacitor relay bank. The number is a 7-bit value — each bit switches one capacitor in or out. C0 = all off, C127 = all on. |
L<0–127> |
L=<val> |
Same idea for the inductor bank. |
S0 / S1 |
S=<val> |
Moves the capacitor bank: S0 = antenna side, S1 = transmitter side. This changes the L-network topology. |
R |
R=OK |
Resets everything — all relays off, state back to zero. |
? |
C=<v> L=<v> S=<v> |
Queries the current relay state without changing anything. |
V |
F=<mV> R=<mV> |
Returns raw forward and reflected power readings in millivolts, straight off the ADC. |
W |
W=<val> |
Returns SWR multiplied by 100 — e.g., W=150 means SWR 1.50. Returns W=999 when power is too low. |
But since we are not in the stone age I made a pretty UI for the project:
Try the UI
If you want to ruin your own ATU-100
I have provided all files needed including the stuff for turning an Arduino UNO into a pic programmer.
As usual: Just for fun NO SUPPORT!!



