Topics

Games & Puzzles
Sound & Music
Watches & Clocks
Wireless
GPS
Power Supplies
Computers
Graphics
Lighting
Thermometers
Educational
Wearables
Test Equipment
Tutorials
Libraries
PCB-Based Projects
For Children

By processor

AVR ATtiny

ATtiny10
ATtiny2313
ATtiny84
ATtiny841
ATtiny85
ATtiny861
ATtiny88

AVR ATmega

ATmega328
ATmega1284

AVR 0, 1, and 2-series

ATmega1608
ATmega4808
ATmega4809
ATtiny1604
ATtiny1614
ATtiny202
ATtiny3216
ATtiny3224
ATtiny3227
ATtiny402
ATtiny404
ATtiny414
ATtiny814

AVR DA/DB/DD/EB-series

AVR128DA28
AVR128DA32
AVR128DA48
AVR128DB28
AVR128DB48
AVR64DD14
AVR16DD20
AVR32DD28
AVR16EB28

ARM

ATSAMD21
RP2040
RA4M1

RISC-V

ESP32-P4

About

  • About me
  • X (Twitter)
  • Bluesky
  • Mastodon

Feeds

RSS feed

Digital Signal Generator PCB

6th September 2026

This is a PCB version of my earlier digital signal generator that generates a crystal accurate square-wave signal from 2Hz to approximately 33.5MHz in precise steps of 2Hz. The frequency is continuously adjustable over this range using a rotary encoder, or you can enter an exact frequency using a numeric keypad, with the frequency displayed on an OLED display:

DigitalSignalGeneratorAngled.jpg

The Digital Signal Generator, based on an AVR16EB28, generates a square wave of from 2Hz
to approximately 33.5MHz in precise steps of 2Hz.

The earlier version was built on a breadboard and based on an SPDIP version of the AVR32EB28 microcontroller. This version uses essentially the same circuit but using surface-mount components, including an SSOP version of the microcontroller. I've also added an on/off switch, a 3.3V regulator, and space for a LiPo battery to make the project completely self-contained.

For a description of the principles of operation see the previous article Digital Signal Generator.

Operation

The Digital Signal Generator works as follows: you enter the frequency you want, in Hz, on the numeric keypad as a sequence of up to eight digits, and press *. The display then shows the actual frequency that will be generated, and generates the square waves on the outputs. You can then adjust the frequency up or down in steps using the rotary encoder. Initially the step size is 2Hz, but you can toggle the step size between 2Hz and 1000Hz by pressing the rotary encoder knob. Pressing # clears the current input and stops the output.

The signal generator has a range of 2Hz to 33554430Hz. The outputs are provided between WO0 and GND, and WO1 and GND. Because these are out of phase you can get a waveform of the same frequency but twice the amplitude between WO0 and WO1.

The circuit

Here's the circuit of the PCB version of the Digital Signal Generator:

DigitalSignalGeneratorPCB.gif

The circuit of the Digital Signal Generator, based on an AVR16EB28.

Power supply

The circuit runs from a supply of 3.3V from a regulator. I suggest powering it from a 3.7V LiPo battery, and there's space on the PCB for a 150mAh battery and a 2-pin JST connector it can connect to. You can charge it using a Lipo charger such as Adafruit's Micro Lipo [1].

Rotary encoder

A variety of different rotary encoders will fit the PCB; the one I've specified in the parts list is available from Adafruit or its distributors, and includes a suitable knob.

Crystal oscillator

The crystal I used is a 4.194304MHz SMD type with an accuracy of 20ppm, and a load capacitance of 18pF [2].

Unlike the earlier ATmega processors the new AVR series don't support an external high-frequency crystal, so it's necessary to provide a crystal oscillator with its output connected to the EXTCLK input.

A novel feature of this circuit is that it uses the Event System to construct a crystal oscillator from two spare I/O pins. It defines PC3 as an inverted input, PC2 as an event output EVOUTC, and then links them internally using an event channel. The crystal is connected between PC3 and PC2, and the output PC2 is connected to the EXTCLK input on PA0.

Recent AVR processors allow you to configure digital inputs either in Schmitt Trigger mode (the default) or in TTL input mode. I tested the stability of this crystal oscillator in both modes, and with a range of different component values. With PC3 in Schmitt Trigger mode the oscillator only operated with a 1MΩ feedback resistor and if the load capacitors were omitted. In TTL mode the oscillator operated correctly with a range of capacitor values, from none to 30pF, with or without the feedback resistor. I've therefore recommended TTL input mode, a 1MΩ feedback resistor, and 18pF load capacitors.

Here's the parts list (click to expand):

Parts list
Qty Item Value Size Typical parts
1 SMD resistor 470Ω 0805 Yageo RC0805JR-07470RL
1 SMD resistor 1kΩ 0805 Yageo RC0805JR-071KL
1 SMD resistor 3.3kΩ 0805 Yageo RC0805JR-073K3L
1 SMD resistor 4.7kΩ 0805 Yageo RC0805JR-074K7L
2 SMD resistor 6.8kΩ 0805 Yageo RC0805JR-076K8L
2 SMD resistor 22kΩ 0805 Yageo RC0805JR-0722KL
2 SMD resistor 1MΩ 0805 Yageo RC0805JR-071ML
2 Ceramic capacitor 18pF 0805 Yageo CC0805JRNPO9BN180
1 Ceramic capacitor 1µF 0805 Murata GCM21BR71E105KA56K
2 Ceramic capacitor 10µF 0805 Murata GRM21BR61E106KA73L
1 Crystal 4.194304MHz 12.5 x 4.6mm QCS4.194304F18B23M
1 Microcontroller AVR16EB28 SSOP-28 AVR16EB28-I/SS
1 Voltage regulator AP2112-3.3 SOT-23-5 AP2112K-3.3TRG1
12 Push buttons Tactile 6 x 6mm FSM4JH
1 On/off switch SPDT 0.1" pitch SPDT Slide Switch
1 Rotary Encoder PEC11-4215F-S24 12mm Rotary Encoder + Extras
1 I2C OLED Display 128x32 1.5 x 0.45" 0.91" 128x32 OLED Display Module White
1 LiPo Battery 150mAh LP402025 150mAh 3.7V LiPo Battery
1 JST PH Connector 2-pin 2.0mm pitch 2.0mm Pitch Connector Kit - JST PH Compatible
2 PCB Double-sided 81.3 x 40.6mm See below

Construction

I designed a PCB in Eagle and sent it to JLCPCB for production.

DigitalSignalGeneratorFront.jpg

The front panel of the Digital Signal Generator, showing the OLED display, rotary encoder,
and push button keypad
.

I soldered the surface-mount components using a Miniware MHP50-B5 50x50mm hotplate [3] [4] at 235°C with Chip Quik SMD291AX10T3 solder paste. It's probably a good idea to test the board before adding the through-hole components because it will be easier to rework the board.

I then soldered the through-hole components, including the push buttons, rotary encoder, pin header, and display. I attached the display in position with a double-sided foam pad. Finally I secured the LiPo battery in position with double-sided sticky tape:

DigitalSignalGeneratorBack.jpg

The back of the completed Digital Signal Generator, showing the LiPo battery.

Back panel

I've also given details of a plain PCB the same size for use as a back panel; you can attach the boards together using 12mm M2.5 threaded pillars and M2.5 screws [5].

I checked the output of the Digital Signal Generator over its range using my 100MHz Frequency Meter.

The program

For an explanation of the program see the original article, Digital Signal Generator.

The only addition to the PCB version is the interrupt-service routine to handle the rotary encoder switch, which is used to toggle between a step size of 2Hz or 1000Hz. I used a pin on a separate port for the switch, PF1, so it could use a separate interrupt service routine:

ISR (PORTF_PORT_vect) {
  Stepsize = 1002 - Stepsize;                             // Toggle between 2 & 1000
  // Wait 255 cycles once button released for debounce
  uint8_t count = 0;
  while (count < 255) {
    count++;
    if ((PORTF.IN & PIN1_bm) == 0) count = 0;             // Still pressed
  }
  PORTF.INTFLAGS = PIN1_bm;                               // Clear interrupt flag
}

Installing the program

First install Spence Konde's DxCore from GitHub: see DxCore - Installation. I used version 1.6.2.

Then, in the Arduino IDE:

  • Choose the AVR EB-series (no bootloader) option under the DxCore heading on the Board menu.
  • Check that the subsequent options are set as follows (ignore any other options):

Board: "AVR EB-series (no bootloader)"
Chip: "AVR16EB28"
Clock Speed: "20 MHz internal"

You can leave the other options at their defaults, the first option on each submenu.

  • Connect a UPDI programmer to the UPDI, GND, and VDD pins.

The recommended way to upload the program is to use a 3.3V Serial board, such as the SparkFun FTDI Basic board [6] connected with a Schottky diode as follows. You can substitute a 4.7kΩ resistor for the Schottky diode:

SerialUPDIProgSchottky3V.gif

  • Set Programmer to the "SerialUPDI - Normal: 230400 baud (recommended)" option.
  • Select the USB port corresponding to the USB to Serial board in the Port menu.
  • Select Burn Bootloader to reset the fuses (in case they were changed for an earlier project).
  • Click Upload to upload the program to the AVR16EB28.

Resources

Here's the program for the Digital Signal Generator PCB: Digital Signal Generator PCB Program.

Get the Eagle or Gerber files for the PCBs here: https://github.com/technoblogy/digital-signal-generator.


  1. ^ Micro Lipo - USB LiIon/LiPoly charger on Adafruit.
  2. ^ QCL4.194304F18B23B on Farnell.
  3. ^ MHP50-B5 on Adafruit.
  4. ^ MHP50-B5 on AliExpress.
  5. ^ Black Nylon Screw and Stand-off Set – M2.5 Thread on The Pi-Hut.
  6. ^ SparkFun FTDI Basic Breakout - 3.3V on Sparkfun.

blog comments powered by Disqus