A compact Arduino, si5351 VFO with Keyer and OLED display

The remarkable compact transceivers of Peter DK7IH inspired me to dream up a compact transceiver of my own. This project would be an experiment on a shirt-pocket scale — not as dense as some of Peter’s rigs, but small on my scale. Starting with the PLL VFO/controller along the familiar lines of Raduino (Arduino Nano and si5351), I sketched out a physical design, and it became clear that the display choice would dictate the size of this module. Where small displays are concerned, there’s only one option … OLED.

I bought my first OLED over a year ago, but a dodgy 5v regulator forced out my tiny Adafruit display’s internal magic smoke. I cursed them and swore never to let them into my shack again. Being an unapologetic aesthete, I had other issues with OLEDs. I didn’t like the look of them on some homebrew rigs, where they sit on the panels of big boxes looking like a postage stamp. They work, but look all wrong, like a family room with a bathroom-sized window. Another problem was the large amount of memory required by the display buffer.

Despite these issues, I decided to make up with these tiny panels, buying a 128×64 OLED with SSD1306 driver. I bread-boarded it with a Nano, ran I2C_scanner to find its address (0x3C) and downloaded an Adafruit driver script. Voila! Worked first time.

Size matters

But the memory problem reappeared. The Adafruit SSD1306 library does graphics which filled my Nano’s memory all the way to the ‘Low memory’ warning. No room for anything else. My ‘SummitProwler’ VFO/Controller/Keyer script already takes up 84% of program storage space and 66% of dynamic memory. So these two were never going to work together.

The Adafruit library alone fills up the Nano’s dynamic memory.

A quick search found a discussion thread in the Arduino forum on the prohibitive size of the Adafruit OLED library. The wisdom of the crowd came through again, and a few clicks later, I’d installed the smallest ASCII-only SSD1306 library known to mankind, SSD1306Ascii, by Bill Greiman. Look at the difference… program space reduced by a third, and global variable space reduced from 80% to 4%!

To make the frequency digits as large as possible on the minuscule panel, I selected a large font and used the library’s x2 function. The result looked to be usable on a compact rig.


The only drawback of this library is that it includes only printable ASCII characters, so drawing the S-meter necessitated a bit of font hacking. There are GLCD font editors that generate code from a drawing of your custom character in an X by Y grid. I grabbed one and designed a font of six 10×15 pixel characters — S1, S3, S5, S7, S9, +x dB. The resultant code didn’t render properly, so I got into a hacking mindset, cycling through a tight trial-and-error loop, adjusting various hex digits in the font character array, and observing the result. After about an hour of fairly mindless trial-and-error, I’d sussed out a set of usable characters. The font is available here.

Adding OLED to SummitProwler VFO/Controller script

All the VFO/Controllers in my homebrew radios use the same script, available here. Each time I use it in a new receiver or transceiver project, I isolate the project-specific code with a #define‘d project label and #ifdef #endif pairs. This ensures only the code required for that project is included in the compiler scope. This is mostly around the UpdateDisplay() method, BFO initialisation, encoder and push-buttons. Most of the VFO, T/R, rig control, metering and keyer code is common. Some code (e.g. PCF8574 drivers for band switching) is small and is left in, even if not used.

After pasting in the SSD1306 code, and wrapping with pre-processor directives, the script settled at 93% program space and 73% global variable space. Code space on the edge of the warning, so there might be some refactoring to be done soon, as I seem to keep adding features!

Physical build

The rest of the build followed my well-trodden path, reproducing the circuit of VU2ESE’s Raduino with an Arduino Nano, Adafruit si5351 breakout, and a 5v 7805 regulator, with the mechanical rotary encoder and push-buttons for VFO selection on flying leads. The two push-buttons on the left allow selection up and down from the 10 VFOs. The frequency step is changed by pushing in the main tuning knob. The other front panel controls are analogue transceiver controls. The two sockets are for an external speaker and PTT microphone. Other essential controls and sockets including DC power, antenna, paddle and 3 keyer memory push-buttons will be relegated to a rear panel.

The only departure from the standard Raduino pattern was to add a 100uH inductor in series with the 5V line to the OLED module with bypass capacitors to keep OLED digital noise off the 5V line, from where Peter DK7IH reports it getting into the receiver.

The module is worked out in a custom hand made PCB, mounted behind a front panel cut from aluminum angle.

The si5351’s middle clock (CLK#1) is set to the signal frequency (with a 700Hz offset applied) and keyed in software for sending CW. The 2MA square wave clock is buffered with a discrete MMBT2222 buffer/gain stage, to condition it for injection into a transmitter’s driver stage.

Both si5351 clocks run at the 2MA setting, delivering around 5dBm as measured. In the scope screen below (for the 7MHz band) the si5351 CLK#0 (VFO) is the yellow trace, CLK#2 (BFO) is purple. The VFO is about 1Vpp which is 4dBm. The VFO amplitude drops to 700mVpp on 14MHz, 500mVpp on 28MHz and 300mV on 50MHz. Remember that the actual VFO is running 12MHz above these bands. The BFO runs at about 5dBm.

The CW carrier oscillator buffer (CLK#1) was measured at 12dB gain, delivering 25mW, more than enough carrier to drive a future transceiver’s driver/PA board. On a 12v supply the entire VFO/Controller module draws 80mA, a bit less than one with an LCD would draw.


The VFO/Controller module is now complete, tested, and ready to drop into a compact case as the heart of a compact SSB/CW transceiver. Write-up of that project to follow as it progresses. If you like this kind of thing, I urge you to check out Peter DK7IH’s blog for an eyeful of amazing compact homebrew achievements.

Tagged , , , , , , , ,

11 thoughts on “A compact Arduino, si5351 VFO with Keyer and OLED display

  1. scharkalvin says:

    I’m also trying to build a compact 20 meter SSB transceiver (14.5 CM x 15 CM x 6 CM) based on Peter’s ideas. I’m using the Si5351, but instead of going with Adafruit’s module, I purchased ten of the Si5351 chips from Mouser at less than $1 each, and soldered one onto a little SMT breakout board I got from ebay. Likewise instead of using an Arduino, I got a 32 pin SMT breakbout board and soldered an ATmega328P onto it. The breakout boards were mounted onto a pad per hole perfboard. I’m using the Si5351mcu arduino library which borrows from Peter’s code and the Raduino. The display I’m using is a 32×128 OLED, and I’m using the Adafruit library. So far I’m using about 55% of the flash space. As per Peter’s idea the VFO and BFO outputs are swapped in software going from RX to TX, the product detector becomes the TX mixer. Separate parts are used for the RX mixer and Bal modulator, also separate outputs from the Si5351. I used separate 3.3 v regulators for the CPU-OLED, and Si5351, and feed the OLED via a 100uh choke. I’m running the CPU on 3.3 volts so I don’t need level converters on the I2C.


  2. Paul Taylor says:

    Thanks for your comment, your project sounds great, using ‘nude’ si5351s and ATMega MCU. DK7IH has inspired a number of projects lately, yours, mine, Glenn VK3PE has also built a Micro 40 style rig in recent days. It could almost be called a trend!

    My front panel Nano/si5351 module, the subject of this post, will be used in a bidirectional SA612 transceiver, hopefully more than one band, to be built and tested out this VK summer. I hope to achieve it in a case 95mm wide, 32mm high, about 160mm deep.

    Choosing to make a rig ‘compact’ adds an interesting constraint. I’m getting better at cramming it all in, while managing to maintain earthing, screening and getting the layout right.


  3. DK7IH says:

    Hi Paul, looks really great. A nice start for a tiny transceiver! 73 de Peter

    Liked by 1 person

  4. Paul Taylor says:

    Thanks Peter for the inspiration, and your detailed and easily reproduced circuits. Your blog posts are a pleasure to read. Keep melting solder. Old school is cool!


  5. […] 2018: And another Arduino/si5351 compact VFO/BFO/Controller and CW Keyer, first stage of a compact multiband SSB/CW transceiver.  […]


  6. Glenn says:

    Looking good, Paul. I haven’t had much luck in a brief look at why the Tx side of mine is low level. Been hit with a nasty bug and playing radio is last on the list for now.

    Liked by 1 person

  7. Robert Seiler says:

    Hi Paul – first, I’d like to congratulate you for your projects, which like the ones of Peter DK7IH are a real inspiration for many QRP-loving Hams like me! For one of my next projects I’m trying to upload your VFO sketch on an Arduino Nano, but I get a strange error message: ” no matching function for call to ‘Si5351::set_correction(int)’ “. I think I am using the correct library (the one you have suggested). Any idea what the problem can be? Thank you.
    Best 73s de Robert HB9TSE


    • Paul Taylor says:

      Hi Robert, thankyou for your very nice comments, my projects are nowhere near as perfectly executed as those of DK7IH so it is flattering to be compared with Peter. Our interests and choice of rigs are obviously very similar.

      A quick response, Jason’s library changed, use thus line and it will compile:

      si5351.set_correction(cal_factor, SI5351_PLL_INPUT_XO);

      Let me know if you have other compile or runtime issues. The wiki pages on the Github repository are written to help people try the script.


      Are you thinking of using an OLED or LCD? And what are the origins of that fine looking 80m SSB rig of yours on QRZ.com?

      73 72 from Melbourne Paul VK3HN.


  8. Robert says:

    Hi Paul and thanks for your super fast response! For my last project (80m SSB RTX) I’ve used the CDV VFO made by your friend Leon VK2DOB – fantastic little thing! The SSB board is my own design, as is the 8-Watt PA. I’ve developed the SMD boards on the (chinese) Easy-EDA website: easy, cheap and fast. If you send me your email address at my callsign@bluewin.ch I will send you some pictures so you can see what’s inside. Now for the first time I’m starting to try to program my own Si-5351 based-VFO and I’m struggling a bit, as you can see… Now I get the following error: ” ‘cal_factor’ was not declared in this scope” which I suppose makes sense as it was not declared in the first place… Maybe I’m not using the latest version of your sketch?…
    73s from the French-speaking part of Switzerland
    Robert HB9TSE


  9. Paul Taylor says:


    For now replace cal_factor with 1000. Email me using my email on qrz.com for easier collaboration.

    — PT.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Amateur radio with VK1DA

Amateur Radio, Computing and other activities of Andrew VK1DA/VK2UH

G4YDM Ham-Radio and SWL news

Radio craft, homebrew, QRP/SOTA, AM


Radio craft, homebrew, QRP/SOTA, AM


Amateur Radio Homebrew HF Station

The Daily Squalor

The Church of The Athletes Foot

VK1DA on the net

Amateur radio experiences with VK1DA

Tj Lab



Amateur Radio and unrelated technologies

Paul Gacek


Radio Engineering Projects powered by DK7IH (Peter)

Projects for the radio draftsman. Hardware, software, electronics and test equipment for the radio designer

VK3KR Workshop

Homebrew electronics and a bit about a Tandoor oven

%d bloggers like this: